SketchyPhysicsWiki
(SLight extension of Variable section. Corrected some typos/spelling errors in Multiple variable section)
No edit summary
Line 96: Line 96:
   
   
Luckily, the simulation has a 'local' variable (It can be used by any script), updated every frame, called ''frame'', that tells us which frame the simulation is currently at.
+
Luckily, the simulation has a 'local' variable (It can be used by any script), updated every frame, called ''frame'', that tells us which frame the simulation is currently at. Frame 0 is the first frame of the simulation, so using this if function, you can create 'default' variables right at the beginning of each simulation. In this case, ''foo'' is set to a random value, but will stay that way for the remainder of the simulation (or at least until ''foo'' is changed). If you have SP3 X (Which is recommended for this tutorial, and above), you can put all your if functions into onTick, on multiple lines:
  +
  +
  +
''if frame==0''
  +
  +
''setVar("foo",rand)''
  +
  +
''setVar("fee",10)''
  +
  +
''setVar("foe",0)''
  +
  +
''end''
  +
  +
  +
Notice that in the example above, I didn't use the ';'. That's because, on a single line, ';' creates a virtual line break, letting you perform a number of functions. With multiple line input opened up, however, they aren't strictly necessary. Also, notice how I didn't include 'then' or 'else'; 'then' is never needed, and basically just makes the script easier on the eye. If you only want the script to do something when the argument is true, don't include 'else'. Since onTick doesn't directly control anything, it wasn't needed in the example. Now for some other useful add-ons:
  +
  +
  +
'''if-and'''
  +
  +
This lets you only do something if two or more arguments are all true at the same time. Say you want to change a variable when two buttons are held down:
  +
  +
  +
''if joybutton("a")==1 and joybutton("x")==1''
  +
  +
''setVar("foo",1)''
  +
  +
''end''
  +
  +
  +
''and'' can also be written ''&&'':
  +
  +
  +
''if joybutton("a")==1 && joybutton("x")==1''
  +
  +
''setVar("foo",1)''
  +
  +
''end''
  +
  +
  +
  +
'''if-elsif'''
  +
  +
This will do something if the argument is true, but will make another argument if the first is false. In this example, if ''foo'' is bigger that 5, it is set back down to 1, but if it's lower than 1, it's set back up to 5:
  +
  +
  +
''if getVar("foo")>5''
  +
  +
''setVar("foo",1)''
  +
  +
''elsif getVar("foo")<1''
  +
  +
''setVar("foo",5)''
  +
  +
''end''
  +
   
 
W.I.P
 
W.I.P

Revision as of 20:51, 18 May 2009

Tutorial

These scripts are used in a similar way to the beginner scripts but there functions are a little more complicated; they are often more useful, however, and after this tutorial you should be able to understand and write scripts that give advanced, dynamic behaviours to your SP models.

Intermediate script

Local and global variables

These are very, very handy. They store information (I.E. numbers) for you, that you can then retrieve later on. I'll start with global variables, as these are the most useful. They're totally specific to SP, and can't be used in any other program. To create one, use:


setVar("var",1)


This creates a global variable, called var, that holds a value of 1. To retrieve this variable (from any object or script field, anywhere in the model), use:


getVar("var")


Having already set var at 1, this would give us a value of 1 (big surprise). To set and retrieve a variable at the same time, use:


getSetVar("var",1)


Which will set var at 1 and give a value of 1.

Now, local variables. These aren't really all that useful, and most users will never use them at all; but it doesn't hurt to know. These are 'normal' ruby variables, but, in SP, won't carry from one frame to the next, and will only work from within the script that created them. They are generally used just to hold numbers, defined at the beginning of the script, as it's easier to change the one variable than go through the script, changing every number. This may also make what you've written easier to understand. These variables are alot more freeform that the global variables. To create one, just use:


var=1


You'll then have a local variable, called var, set at 1. Retrieving local variables is easier than with global ones; they work something like letters in algebra, and can be slotted in almost anywhere:


var


That's it. Having been set at 1, var will give a value of 1; so far so difficult. You may never need to use these, but other people do; in more complex scripts, they can be 'built-in', so that changing them changes the behaviour of the script, without going through it and replacing all the relevant values.


Multiple variable script

Instead of using many different boxes for the same job (For example, switching landing gear up and down) it can all be combined into one script.


gear1 add to the servo its connected to: getSetVar('gear1')

gear2 add to the servo its connected to: getSetVar('gear2')

gear3 add to the servo its connected to: getSetVar('gear3')


(This is what each gear is called for simplicity) In the onTouch box add this script to one of the gears:

setVar('gear1',1)

Tthat will then activate the first gear, now combine the second part of the script to add the second gear:

setVar('gear1',1)+setVar('gear2',1)

(This is the script to set off two sets of landing gear)


Now just add the last gear and all 3 gears will come down when the 1 box is touched:

setVar('gear1',1)+setVar('gear2',1)+setVar('gear3',1)


Have a play around with it and try it.

if functions:

Probably the most useful function for SP's purposes. This extremely adaptable script function effectively asks a question, about what's happening with inputs, the frame number, and variables, and returns an 'answer', which can itself be a variable, number, or even a self-contained formula with other inputs. It's written:


if (this is true?) then; (do this); else; (do this); end


Now, scripts aren't intellegent. You can't ask it whether you're fat, or if your house looks nice... no, because it'll give a big ol' syntax error. You have to ask something it will 'understand', with numbers and variables and functions that are written properly. So, let's find out if 5 is bigger than 4:


if 5>4 then; 1; else; 0; end


Obviously (I hope), it is, so this will return a 1. Now, let's do something that could be useful! Say we want to move a joint to a random position... BUT, we want it to stay there. Try just using the rand command by itself. Not pretty, huh? The if function can help! It's important to realise that the physics simulation isn't a continous flow, it runs in frames; each frame is a still image, projected onto your screen. You see movement because the physics engine calculates where each object should be in the next frame, and moves it there. The script isn't exempt from this... to move an object that's connected to a script-controlled joint, the script must be run every frame, to find a single, numeric output which is used as the joint's controller. This means that, by just using the rand command, it is run every frame, resulting in a different value every time, and a wildly vibrating joint. So, let's get on with it:


if frame==0 then; setVar("foo",rand); else; getVar("foo"); end


Luckily, the simulation has a 'local' variable (It can be used by any script), updated every frame, called frame, that tells us which frame the simulation is currently at. Frame 0 is the first frame of the simulation, so using this if function, you can create 'default' variables right at the beginning of each simulation. In this case, foo is set to a random value, but will stay that way for the remainder of the simulation (or at least until foo is changed). If you have SP3 X (Which is recommended for this tutorial, and above), you can put all your if functions into onTick, on multiple lines:


if frame==0

setVar("foo",rand)

setVar("fee",10)

setVar("foe",0)

end


Notice that in the example above, I didn't use the ';'. That's because, on a single line, ';' creates a virtual line break, letting you perform a number of functions. With multiple line input opened up, however, they aren't strictly necessary. Also, notice how I didn't include 'then' or 'else'; 'then' is never needed, and basically just makes the script easier on the eye. If you only want the script to do something when the argument is true, don't include 'else'. Since onTick doesn't directly control anything, it wasn't needed in the example. Now for some other useful add-ons:


if-and

This lets you only do something if two or more arguments are all true at the same time. Say you want to change a variable when two buttons are held down:


if joybutton("a")==1 and joybutton("x")==1

setVar("foo",1)

end


and can also be written &&:


if joybutton("a")==1 && joybutton("x")==1

setVar("foo",1)

end


if-elsif

This will do something if the argument is true, but will make another argument if the first is false. In this example, if foo is bigger that 5, it is set back down to 1, but if it's lower than 1, it's set back up to 5:


if getVar("foo")>5

setVar("foo",1)

elsif getVar("foo")<1

setVar("foo",5)

end


W.I.P