Main

Writing Expressions

Note: Scripting has been significantly enhanced with features not documented below, see these link for what's been added: - http://www.emix8.org/forum/viewtopic.php?t=704 and - http://www.emix8.org/forum/viewtopic.php?t=868.

Scripts and expressions.

ZGameEditor has a simple scripting language. The general syntax is based upon "C"-dialects.

The following syntax is supported.

Comments

// this is a single line comment

/*
   this is a 
   multi line 
   comment
*/

Assignments

[objectname].[propertyname].[propertyindex] = value ;
[localvariable] = value;
[array] = value;

objectname - The name of a component is the value of its "Name"-property and is set in the editor. The special objectname "CurrentModel" can be used if the expression written has a Model-component as a parent.

propertyname - The name of the property to assign.

propertyindex - If the property is an indexed property, then the name of the index must be specified.

For Color-values, this is "R","G","B","A" for the Red/Green/Blue/Alpha components of the color in the range 0 to 1.

For position or vertex-values (such as Model.Position/Rotation/Velocity) the propertyindex is "X","Y","Z" for the value of its corresponding axis.

Example assignments

PlayerModel.Position.X = 42;
PlayerModel.Position.X = PlayerModel.Position.Y / 2;
MyMaterial.Color.R = 0.5;

PlayerScore += 500;

Other C-style assignments are supported also:

  • = - normal assignment
  • += - plus-assign: x+=1 is the same as x=x+1
  • -= - minus-assign: x-=1 is the same as x=x-1
  • *= - multiply-assign: x*=1 is the same as x=x*1
  • /= - divide-assign: x/=1 is the same as x=x/1
  • ++ - pre or post increment of local variables: i++, ++i
  • -- - pre or post decrement of local variables: --i, i--

When assigning a property with several components (such as the x,y and z of Scale or Rotation) to the same value a shorter syntax is allowed.The following assignment:

CurrentModel.Scale=1;

Give the same result as:

CurrentModel.Scale.X=1;
CurrentModel.Scale.Y=1;
CurrentModel.Scale.Z=1;

IF-statements

if( [condition] )

  [one line expression] ;
if( [condition] ) {
  //do something if condition is true
} else {
  //do something else if condition is false
}

condition - An expression which is evaluated to true or false.

Operators that are valid in conditions:

  • == - equal
  • != - not equal
  • > - greater than
  • >= - greater than or equal
  • < - less than
  • <= - less than or equal
  • || - OR, statement is true if any of the conditions are true
  • && - AND, statement is true if both conditions are true
  • ! - NOT, statement is true if condition(s) is/are false

Example IF-statements:

if(PlayerScore>5000)
  PlayerLives += 1;

if( (App.Time>5) && (PlayerLives<2) ) {
  Difficulty *= 1.2;
  Speed *= 1.2;  
}

Loops

For-loops

C-style for-loops can be used:

for ( (defVar optional) <EXPR1> ; <EXPR2> ; <EXPR3> )
{  
  //do something;
}

The expression <EXPR1> is evaluated, then <EXPR2> is checked, if it's true, then the loop body is executed. After the first iteration, the <EXPR3> is evaluated, <EXPR2> is checked again, if it's true, the loop body is executed, etc...

When you want to use a global variable that is already defined by the DefineVariable Component, you can simply write ..

for(i = 0; i<4; ++i){expression;}

In case you want to use a local variable (only exists within the scope that it is defined in), initializing the variable as you need it is more convenient

for(int i = 0; i<4; ++i){expression;}

Change "int" into "float" when you want to use a floating point variables.

While-loops

while(i<42)
{
   //do something;
   i++;    
}

While statements can also be defined using the Repeat component.

Break and continue

Use break to break out of a loop before it has finished execution:

while(i<42)
{
   if(i==10)
     break;  //exit loop
   i++;    
}

Use continue to jump directly to the next loop iteration:

for(int i=0; i<10; i++)
{
   if(i>=5)
     continue;  //keep looping and skip the rest of the loop body
   sum+=i;  //this line only executes when i<5
}

Switch statement

//Switch-statement example
switch(i) {
  case 0 :
  case 1 :
  case 2 :
     //When i is 0, 1 or 2.
     doSomething();
     break;
  case 3 :
     //When i is 3.
     doSomethingElse();
     break;
  default :
    //The default case when i is none of the above
}

Conditional statement

//Conditional statement example
//Give 1000 in bonus when time<100, otherwise bonus will be zero
int bonus= time<100 ? 1000 : 0; 

Bit manipulation operators

  • Hex-values: int x=0x0f; //15
  • Binary AND: int x=0xff & 0x0f; //0xf (15)
  • Binary OR: int x=1 | 2 | 4; //7
  • Binary XOR: int x=1 ^ 2 ^ 4 ^ 4; //3
  • Binary Shift left: int x=1 << 1; //2
  • Binary Shift right: int x=2 >> 1; //1

Built in functions

  • sin(i) - returns the sine of the angle x in radians
  • sqrt(i) - square root of x
  • cos(i) - cosine of the angle x in radians.
  • tan(i) - tangent of x
  • abs(i) - absolute (positive) value of x
  • rnd() - returns values in the range: 0 <= Number < 1.0
  • random(base,variance) - random number in the range base-variance to base+variance
  • atan2(y,x) - arctangent angle and quadrant of a given number
  • noise2(x,y)
  • noise3(x,y,z) - 2 and 3 dimensional Perlin Noise. Return values in an approximate range of -0.3 to 0.3 so you need to scale it to get a -1 to 1 range. More info: Hugo Elias article about noise.
  • frac(i) - fractional (decimal) part of i
  • exp(i) - the exponential of i
  • clamp(i,min,max) - clamps the value i to be in the range min to max
  • pow(base,exponent) - raises base to any power
  • centerMouse() - centers the mouse cursor
  • setRandomSeed(i) - set the random seed value to i, returns the old seed.
  • getSystemTime() - returns seconds elapsed since midnight.
  • floor(i) - returns the floor of x (the highest integer less than or equal to i)
  • ceil(i) - returns the ceiling of x (the smallest integer larger than i)
  • Expressions now support integer modulo operator (%) --- @Ville - is it mod(i)?
  • acos(i) - returns the inverse cosine of i
  • asin(i) - returns the inverse sine of i
  • round(i) - rounds a floating point Number to an Integer value.
  • quit() - quit the application
  • joyGetAxis(joyId,axisNr) - return position of joystick axis
  • joyGetButton(joyId,buttonNr) - return state of joystick button
  • joyGetPOV(joyId) - return position of joystick POV-control
  • touchGetCount(i) - Get nr of touches on touchscreen (Android)
  • touchGetX(i) - Get position of touch i
  • touchGetY(i) - Get position of touch i
  • touchGetID(i) - Get ID of touch i
  • log2(i) - returns log base 2 of i
  • getBinaryProp(BitmapFromFile1.BitmapFile,FileBuffer) - get the content of a binary property with the content of a byte array.
  • setBinaryProp(BitmapFromFile1.BitmapFile,FileBuffer) - set the content of a binary property with the content of a byte array.
  • trace(message) - shows a message in the log-window. Useful for debugging.
  • also see string-functions in the string section below

User defined functions

Define functions using the ZLibrary component. Call external modules (dll:s) using the ZExternalLibrary component

Predefined constants

  • PI - Value of PI
  • ANDROID - This is defined (set to 1) when building for Android. "if(ANDROID) ...".

Variables

Global variables can be defined with the DefineVariable component.

Arrays can be defined with the DefineArray component.

Local variables can be defined with the following syntax:

  • float i1,i2,i3; //define three local variables
  • float i=1.5; //define and initialize one local variable
  • int i=1; //define and initialize one local variable of integer type

Note that local variables and arrays are not initialized, you need to assign a value before using them:

//S is uninitialized, this will generate a runtime error
string s;
s=s + "i";

//Ok initialize S before use
string s="";
s=s + "i";

Strings

The scripting language also handles strings.

Example - RenderText component named ScoreJimmy
int Sc=5;
ScoreJimmy.Text = "Score: "+intToStr(1+Sc);//"Score: 6"//Jimmy padded!

There are a number of built-in functions for strings:

  • string s = intToStr(42); //"42" //convert from integer
  • int i = strToInt("42"); //42 //convert to integer
  • string s = chr(65); //"A" //chr(charcode) : return character from ansi-code
  • int i=ord("A"); //65 //ord(string) : return ansi-code from character
  • int i = length("1234"); //4 //returns length of string
  • int i = indexOf("lo","hello",0); //3 //indexOf(substr, str, startpos) : returns position of substring in string from a start position. Startpos must be less than length of string.
  • string s = subStr("hello",0,2); //"he" //subStr(source, startpos, length) : returns substring. Startpos and length must be within source-string bounds.

Special characters in string literals

  • "\"" : double quote character
  • "\n" : newline character
  • "\\" : backslash character

Advanced scripting

  • Script based Component invocation:

Syntax: @ <component> ( [ <property> : <value> ], ... ); This will declare and execute a component with the properties set to the desired values.

Examples:

//A component that does not need any properties

@RemoveModel();

//Component with a single property

@SetAppState(State : AppState_TitleScreen);

//Several properties

@RenderText(Text : "Hello" + intToStr(i), X : -0.5, Y : -1 + (0.1*i));

It makes much more functionality available from scripting so it's up to the user to choose between Component, code-based, or a combination approach, based on personal preference.

  • Cross component referencing:

Previously you could only use expressions such as "[component].[property]". Now you can use more advanced expressions, so for instance this is possible:

(Um1 is a UseMaterial component name)

//Set the red component of the material

Um1.Material.Color.R=1;

Notice that "Material" is a property referring to another component. You can also assign component references to another component:

//Use different materials

if(something) Um1.Material=Material1; else Um1.Material=Material2;

  • Pass reference arguments to functions:

Use the "ref" syntax. "Ref" stands for "reference". This allows you to return more than one value from a function.

Examples:

//notice the "ref" word in front of the arguments that are passed by reference

void splitColor(int color,ref int r, ref int g, ref int b) {

 //..separate r,g,b from color and return back to caller

}

//call this function

int r,g,b; splitColor(0xff8020,r,g,b);

This also allows to call dll-functions that expect a pointer to an integer as an argument.

//OpenGL-function, generate a texture id and return it into the second argument

void glGenTextures(int n, ref int textureid) { }

//Delete a texture, pass the id using a reference

void glDeleteTextures(int n, ref int textureid) { }

  • Datatype called "xptr" (pointer to be passed to external functions):

Example:

//OpenGL external library definitions, notice the last parameter "xptr pixels"

void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int atype, xptr pixels) {}

void glGetTexImage(int target, int level, int format, int atype, xptr pixels) {}

These functions can now be called with a DefineArray (only, so far) component instance as the last parameter.

Green Marinee theme adapted by David Gilbert, powered by PmWiki