Page 1 of 1

genWave Demo-Tutorials

PostPosted: Sun Jan 06, 2013 1:37 am
by GEuser
I'll be archiving a list of demo-tutorials on using the genWave function here

[UNDER CONSTRUCTION]

Demo-Tutorials

1. Gradients: viewtopic.php?f=27&t=12524#p89138
2. Simple Procedural Landscaper / Scroller: (comming soon)
3. Orbiting Actors: viewtopic.php?f=27&t=12524#p89262
4. Simple lighting effects: (comming soon
5. Simple animated effects: (comming soon)

Re: genWave Demo-Tutorials

PostPosted: Sun Jan 06, 2013 1:42 am
by GEuser
genWave Gradient Demo-Tutorial

STRONGLY RECOMMEND you read up on the genWave ( viewtopic.php?f=8&t=12523 ) and genWaveViewer (viewtopic.php?f=8&t=12522 ) threads before you attempt this demo-tutorial

Image

Here's a method for creating a procedural gradient effect using the genWave function.

Rather than diving straight into creating an algorithm for gradients, first, let's consider what were trying to do in general terms to keep explanations simple.

Firstly, need to take into account each of the RGB colour components to make the gradient. We don't always want to start from a value of 0 for the RGB settings because this will always produce the darkest hue. A way is needed to pick any start value (within limits). Lets refer to any start value for these RGB's as colorStart. We also need to consider what the limits are for these settings (to prevent coding errors). Each RGB component is always between 0 and 255 for gE colors, these than are our minimum(0) and maximum (255) limits. This also indicates that we should avoid negative values (they fall outside of minimum 0). Let's refer to 255 as colorMax (colorMax always = 255, its a constant thing).

Still keeping things general, let's consider a color with a start value of 63. See diagram A below:-

Image

We've used 63 of the 255 max available. Theres some FREE color space for us to play with. How do we quantify this FREE stuff? Just do some simple maths:-

FREE = colorMax - colorStart = 255 - 63 = 192. FREE stuff now has a usable value but what does it represent? Since we're creating a gradients I'd say this represents the maximum playing area for our gradient. The bit that varies in color. Let's call it colorGradMax (for color gradient Maximum). Diagram B summaries things up to now:-

Image

Now we've got enough information to start thinking about a possible color gradient algorithm.

Lets recap. We've got our helper formula but it is not quite right yet. An actual color gradient (call it: colorGrad) would comprise a colorStart with this color gradient limit (colorGradMax) added on. So, the revised formula would look like:-

remember that: colorGradMax = colorMax - colorStart

so...

colorGrad = colorStart + colorGradMax

Another thing, way not just do away with the colorGradMax and substitue the calculation for it instead (it will be one less thing to do). 2nd revision:-

colorGrad = colorStart + (colorMax - colorStart) // colorGradMax replaced with (colorMax - colorStart)

Lets substite the 'color' text of each part with red, green and blue (except for colorMax because its a constant):-

redGrad = redStart + (colorMax - redStart)
greenGrad = greenStart + (colorMax - greenStart)
blueGrad = blueStart + (colorMax - blueStart)

we've got the maximum limit for the amount a gradient can vary for each of the red, green and blue components.

All we need now is a mechanism to vary this amount. We have it. The genWave function produces waves which are things that vary in value. The red part of the gradient would then vary by (colorMax - redStart)*genWave(...) and likewise for the other two: (colorMax - greenStart)*genWave(...), (colorMax - blueStart)*genWave(...). This does not mean you would necessarily want to apply a gradient for each of the RGB components, you might just want a gradient for the red part. For this reason we cannot hardwire the gradient formula into the color only keep it as a separate option that can be incorporated into the color definition if user wants it. Another issue is the colorMax. What if I want to create an artificial color limit so that the gradient can end prematurely before the 255 maximum limit is reached? You might not always want to end up with a bright red finish for the end of your gradient. In this case you would have to make available an adjustable maximum limit for each of the 3 RGB components (for more flexible gradient designs). Something like diagram c:-

Image

The code might look somnething like this:-
Code: Select all
int redMax=250;
int redStart=63;
int redGrad=redStart+(redMax-redStart)*genWave(12,...);

int greenMax=225;
int greenStart=120;
int greenGrad=greenStart+(greenMax-greenStart)*genWave(7,...);

int blueMax=147;
int blueStart=97;
int blueGrad=blueStart+(blueMax-blueStart)*genWave(24,...);

setpen(redStart, greenGrad, blueStart, 0, 1); // gradient applied to green component only

=== drawing code here =====



Note that in the code above you can apply a different genWave settings for each of the 3 RGB components for more varied gradients (as long as the genWave output selection reamins the same). You can also do stuff like 255-redGrad to reverse the red gradient component (likewise for the other 2). The same for the start colors (255-redStart).

so for each of these * below you can incorporate either, redStart, 255-redStart, redGrad, 255-redGrad (substitue Green/Blue for the other positions *2, *3).

setpen(*, *2, *3, 0, 1);

For the following stages you need to understand a bit about the genWave function, best to read up genWave Viewer Manual (thread link provided at top).

Drawing a horizontal gradient in a canvass actor.

I need to know what the gradient width and the drawing step size are so that I can use a for loop to do the job. The gradient width has to be synched up with the genWave selection range so that the two can work togather to produce a coherent result (wStep parameter of genWave syncs up with drawStep of for loop). Let's say we want a gradient that is 320px wide. If our genWave selection range parameters are wStart=0 and wEnd=320 then the gW selection range is:-

gW_Selection_range = wEnd - wStart = 320 - 0 = 320 (if wStart was 20 this would have been 300)
Our drawing step size (call it drawStep) would be:-

drawStep = gw_Selection_Range / Gradient width = 320 / 320 = 1.0

Now the 'for loop' code would look something like this:-

Code: Select all
for(i=0; i<gradWidth; i++)
{
    // gradients calculated for loop
     redGrad = ..... * genWave(....,i*drawStep,....); // wStep parameter tied up with for loop's i count
     greenGrad = ..... * genWave(....,i*drawStep,....);
     blueGrad = ..... * genWave(....,i*drawStep,....);

    // rest of draw code
}


You can play around with code for the horizontal gradients at the end of this demo-tutorial

Drawing a horizontal gradient in a canvass actor.

Here you would just transpose the gradient height for the calculations
e.g. drawStep = gw_Selection_Range / Gradient height
e.g. for loop would look something like:

Code: Select all
for(i=0; i<gradHeight; i++)
{
    // gradients calculated for loop
     redGrad = ..... * genWave(....,i*drawStep,....); // wStep parameter tied up with for loop's i count
     greenGrad = ..... * genWave(....,i*drawStep,....);
     blueGrad = ..... * genWave(....,i*drawStep,....);

    // rest of draw code
}


You can explore how the vertical gradient is drawn in the code listing for it at the bottom.


CREATE THE DEMO

1. Create a canvass actor named: gradient

2. Make a Create_Actor (Script) Event for the above canvass actor.

3. Copy/Paste the code below into the new Create_Actor Event (either the horizontal or the vertical gradient code).
(Import by saving code as a .txt file and load in gE via Script Editors File/Load option)

4. Your good to go!


Code for horizontal Gradient

Code: Select all
// Color & gradient parameters
int redMax=255;
int redStart=63;
int redGrad=0; // leave as 0

int blueMax=255;
int blueStart=63;
int blueGrad=0; // leave as 0

int greenMax=255;
int greenStart=128;
int greenGrad=0; // leave as 0

// gradient height & width
int gradWidth=320;
int gradHeight=100;

// These are the gradient positioning x, y coords relative to canvass actors top-left corner
int gradX=10;
int gradY=10;

//These two are genWave parameters  these should be the same as the genWave WAVE you've created.
double wStart=0;
double wEnd=320;

double drawStep=(wEnd-wStart)/gradWidth;

// for loop variables
double dStep=0.0;
int i=0;

//gradient draw loop
for(i=0; i<gradWidth; i++)
{
    dStep=i*drawStep; // this set's up the drawing steps (synched up with genWave)

    redGrad=abs(redStart+(redMax-redStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
    greenGrad=abs(greenStart+(greenMax-greenStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
    blueGrad=abs(blueStart+(blueMax-blueStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
 
    // setup Gradient
    setpen(255-redGrad, greenGrad, blueStart, 0, 1);
 
    // draw gradient
    moveto(i+gradX, gradY+gradHeight);
    lineto(i+gradX, gradY);
}



Code for vertical gradient

Code: Select all

// Color & gradient parameters
int redMax=255;
int redStart=63;
int redGrad=0; // leave as 0

int blueMax=255;
int blueStart=63;
int blueGrad=0; // leave as 0

int greenMax=255;
int greenStart=128;
int greenGrad=0; // leave as 0

// gradient height & width
int gradWidth=320;
int gradHeight=100;

// These are the gradient positioning x, y coords relative to canvass actors top-left corner
int gradX=10;
int gradY=10;

//These two are genWave parameters  these should be the same as the genWave WAVE you've created.
double wStart=0;
double wEnd=320;

double drawStep=(wEnd-wStart)/gradHeight;

// for loop variables
double dStep=0.0;
int i=0;

//gradient draw loop
for(i=0; i<gradHeight; i++)
{
    dStep=i*drawStep; // this set's up the drawing steps (synched up with genWave)

    redGrad=abs(redStart+(redMax-redStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
    greenGrad=abs(greenStart+(greenMax-greenStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
    blueGrad=abs(blueStart+(blueMax-blueStart)*genWave(10, 1, 0, dStep, 0, 320, 0, 2, 0.5, 0, 3, 0.333, 0, 5, 0.2, 0));
 
    // setup Gradient
    setpen(255-redGrad, greenGrad, blueStart, 0, 1);
 
    // draw gradient
    moveto(gradX, gradY+gradHeight-i);
    lineto(gradX+gradWidth,gradY+gradHeight-i);
}



[EDIT] Oops! Cleared up the Code tag typo was making some normal text code, sorry :lol:

Re: genWave Demo-Tutorials

PostPosted: Thu Jan 10, 2013 4:32 am
by GEuser
ORBITAL ACTORS (using genWave)

INTRODUCTION


This demo-tutorial shows how to use genWave function to make one actor orbit another one or create nested orbits. Explanations are given first and demo creation instructions are given at end of post.

SCREENSHOT

Image

DEMO DOWNLOADS

Linux:
lin_orb.zip
(1.8 MiB) Downloaded 189 times

Mac:
mac_orb.zip
(2.1 MiB) Downloaded 194 times

Windows:
WIN_orb.zip
(1.84 MiB) Downloaded 187 times

Images for demo creation:
OrbitPics.zip
(946.83 KiB) Downloaded 185 times


METHOD USED

Skip this if you want (you can always come back to it if your curious about the technique i've used).

This is my (unofficial) way of explaining the trigonometry method I've used to do the orbits (I know there are other more formal ways that mathematicians prefer but hey, it was easier for me this way). Here's the general forumla to make a circular motion (or to draw a circle).

x = r * sin(theta)
y = r * cos(theta)

Look at the image below (1) and you'll see a green ball moving along a circle. Image(2) shows that r (black arrowed line) is the distance from the centre of the circle to the centre of the green ball (r is also the circles radius). The red arrow line is the vertical distance from the centre of the circle to the centre of the green circle and likewise the blue arrowed line is the horizonal distance. The purple bit shows the angle travelled by the ball (angle Theta). Image (3) shows how these vertical (red) and horizontal(blue) distances of the ball relative to the circles centre change as the green ball moves around it.

Image

if I was to cut the circle at 0 degrees, unfurl it and stretch it out in a straight line whilst the green ball was still moving along it like as if it's still on a circle, then it's vertical and horizontal distances would trace out the red and blue paths as shown in animations below.

Image

Image

These paths form the sinewave (blue) and cosine wave (red). If you could combine these, to form the x and y coordinates of a gE actors position it would orbit about a centre by a specified distance. You can see that the red path forming is always 90 degrees ahead of the blue one (this is what the cosine wave is, always leading the sinewave by 90 degrees, or phase shifted by +90). In the genWave function, wave1 set at wAmp1=1, wFreq1=1, wPhase1=0 would be like the sinewave but Wave2 would be set to wAmp2=1, wFreq2=1, wPhase2=90 to make a cosine wave (notice wPhase2 at 90). Now I can replace the sin(theta) and cos(theta) bits in the formulas above with my genWave(...) versions (wave1 for sin and wave2 for cos). The r bit I can replace with distToCentral (to indicate it's the distance from the actor to the orbits centre (or central actor being orbitted). For the angle theta bit I can use orbitStep. An actor variable that can be customised to control the speed rate at which an actor moves along an orbit (ties to the wStep parameter of genWave). Formulas revised:-

x = distToCentral * genWave(1,...,orbitStep,...); //using wave1 (i.e. genWave mode=1)
y = distToCentral * genWave(2,...,orbitStep,...); //using wave2 (i.e. genWave mode=2) phase shifted by +90 degrees

I'm gonna leave the explanations at this (sorry for the rushed response, out of time, getting late).

CODE DESCRIPTION

Typically you would create a normal actor and use draw_from function to copy it's animation image into a canvass actor. This will allow you to scale the image (example: in a solar system sim, the moon is smaller then the planet which is smaller than the sun and their orbits are nested). You call the genWave function from the canvass actor's (orbitting actor) draw event. You would try various genWave parameter combos to get different types of orbital efects.

Your orbitting actors(canvass) Create Actor code would contain all the initial settings for the orbit

Code: Select all
distToCentral=100; // (actor variable) Orbitting actors distance to the central actor / location
x=CentralActor.x+distToCentral; // orbital x positional settings
y=CentralActor.y+distToCentral; // orbital y positional settings
draw_from("NormalActorForAnimations", width/2, height/2, 0.5); // get animation image from Normal Actor


Your orbitting actors Draw Actor code could look like this:

Code: Select all
orbitStep+=1; // Actor variable, try fractional steps for more smoother, slower orbits or integer multiples for faster ones
animpos+=1;
if (animpos>36) // Whatever the number of animation frames (copied into canvass from normal actor)
{
   animpos=0; // reset frame position to keep looping animation in canvass
}

if(orbitStep>=360) // if orbit revolution complete re-start from 0
{
    orbitStep=0;
}


x=CentralActor.x+distToCentral*genWave(1, 1, 1, orbitStep, 0, 360, 0, 1, 1, 0, 1, 1, 90, 1, 1, 0); // genWave mode 1 used =sin()
y=CentralActor.y+distToCentral*genWave(2, 1, 1, orbitStep, 0, 360, 0, 1, 1, 0, 1, 1, 90, 1, 1, 0); // genWave mode 2 used =cos()
draw_from("NormalActorForAnimations", width/2, height/2, 0.5); // copy current normal actor frame into canvass


Of course, your central actor could be replaced with a spawn location or any arbituary location. The central actor could be a mothership or regular ship with orbitting drones that protect it or an enemy base patrolled by orbitting robo-guards, etc...


THINGS TO DO
Generally just play around (but keep the selection range 0 to 360 unless you know what your doing).

1. Reverse the orbitting direction by changing this bit: genWave(... orbitStep ...); to: genWave(... 360-orbitStep ...);
2. Try different genWave modes (first parameter in genWave [1 to 24] )
3. You could adjust the parameter ratios of wave1 and wave2 to create Lissajous curves (http://en.wikipedia.org/wiki/Lissajous_curves ).
4. There's nothing stopping you from adding more genWaves to the x and y parts (multiplier needed otherwise it will be just between -1 and 1).
5. Try different phase angle and frequency combos.
6. Replace draw actor event with a timer (canvass actor). Try using a timer for the orbitStep adjustments (warning: you MUST know what your doing). You could just try using various timers for the phase angles and amplitudes too, etc...


DEMO CREATION INSTRUCTIONS


1. Add 2 Actor Variables (Script=> Global code => Global Code Editor <Variables> <ADD>

INTEGER
distToCentral
REAL orbitStep

2. ADD genWave Global code to Global Code Editor (add it as: genWave)

Get Code from here (it's at end of post)
viewtopic.php?f=8&t=12523

ACTORS TO CREATE
Image

3. Create 3 NORMAL ACTORS

SunMaster (use animation images: Sun0001.png...Sun0036.png)
PlanetMaster (use animation images: Planet0001.png...Planet0036.png)
MoonMaster (use animation images: Moon0001.png...moon0036.png)

Animation Images: Are located in .zip file download (SEE DOWNLOADS: OrbitPics.zip)

4. Create 3 CANVASS ACTORS and insert code in script event indicated

CANVASS ACTOR: Sun1
SCRIPT: CreatActor Event
Code: Select all
x=-1*width/2;
y=-1*height/2;
draw_from("SunMaster", width/2, height/2, 1);


SCRIPT: DrawActor Event
Code: Select all
animpos+=1;
if (animpos>36)
{
   animpos=0;
}

draw_from("SunMaster", width/2, height/2, 1);


SCRIPT: MouseButtonDown Event (Right key, enable Drag)
Code: Select all
// right mouse drag enabled


CANVASS ACTOR: Planet1

SCRIPT: CreatActor Event
Code: Select all
distToCentral=100;
x=Sun1.x+distToCentral;
y=Sun1.y+distToCentral;
 draw_from("PlanetMaster", width/2, height/2, 0.5);


SCRIPT: DrawActor Event
Code: Select all
orbitStep+=1;
animpos+=1;
if (animpos>36)
{
   animpos=0;
}

if(orbitStep>=360)
{
    orbitStep=0;
}


x=Sun1.x+distToCentral*genWave(1, 1, 1, orbitStep, 0, 360, 0, 1, 1, 0, 1, 1, 90, 1, 1, 0);
y=Sun1.y+distToCentral*genWave(2, 1, 1, orbitStep, 0, 360, 0, 1, 1, 0, 1, 1, 90, 1, 1, 0);
draw_from("PlanetMaster", width/2, height/2, 0.5);


CANVASS ACTOR: Moon1

SCRIPT: CreatActor Event
Code: Select all
distToCentral=30;
x=Planet1.x+distToCentral;
y=Planet1.y+distToCentral;
draw_from("MoonMaster", width/2, height/2, 0.25);


SCRIPT: DrawActor Event
Code: Select all
orbitStep+=5;
animpos+=1;
if (animpos>36)
{
   animpos=0;
}

if(orbitStep>=360)
{
    orbitStep=0;
}

x=Planet1.x+distToCentral*genWave(1, 1, 1, orbitStep, 0, 360, 0, 1, 1, 0, 1, 1, 90, 1, 1, 0);
y=Planet1.y+distToCentral*genWave(2, 1, 1, orbitStep, 0, 360, 0, 1, 1, 0, 1, 1, 90, 1, 1, 0);
draw_from("MoonMaster", width/2, height/2, 0.25);


When you run it you should see a planet orbitting its sun and a moon orbitting the planet. If you hold down the right mouse key over the sun, you can drag it around the screen abd the orbits adjust accordingly with interruption. Play around with the distToCentral and orbitStep sizes to create different orbiting characterists for the planet and moon.

I'd be grateful if someone could make Sprite strips for those animated images I've uploaded (no big deal if can't). Hope you find it useful. I know you can just use the in built gE's sin() and cos() functions to do the same stuff but this would save all the coding you have to do and with genWave you can make a lot more adjustments with single tweaks here and there and even create some chaotic looking movements (by adding genWaves to genWaves or nesting genWaves within genWave calls themselves e.g. genWaves substituted within wAmp1, wFreq1, wPhase1, etc... parameters, endless possibilities).

Re: genWave Demo-Tutorials

PostPosted: Thu Jan 10, 2013 4:23 pm
by Hblade
Are you from nasa? O-o

Re: genWave Demo-Tutorials

PostPosted: Thu Jan 10, 2013 4:45 pm
by MrJolteon
Hblade wrote:Are you from nasa? O-o

I think he's from another planet. o_O

Re: genWave Demo-Tutorials

PostPosted: Thu Jan 10, 2013 5:06 pm
by Hblade
Lol he's smart thats for sure

Re: genWave Demo-Tutorials

PostPosted: Fri Jan 11, 2013 7:33 pm
by GEuser
:lol: Niether an E.T. or smart. I can't even remember my own name most days...hehe... As for NASA wow, wouldn't that be great. To work for NASA, way overboard for me.

Re: genWave Demo-Tutorials

PostPosted: Fri Jan 11, 2013 7:39 pm
by MrJolteon
GEuser wrote::lol: Niether an E.T. or smart. I can't even remember my own name most days...hehe... As for NASA wow, wouldn't that be great. To work for NASA, way overboard for me.

I never said you're E.T.
You might be a Dalek for all I know.

Re: genWave Demo-Tutorials

PostPosted: Fri Jan 11, 2013 8:52 pm
by Hblade
Good old dr who reference