ebook img

Diving Into GEMscript PDF

32 Pages·2013·0.59 MB·English
by  
Save to my drive
Quick download
Download
Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.

Preview Diving Into GEMscript

User’s Guide Diving Into GEMscript Learn to how to program in GEMscipt by writing the classic “Breakout” game. GEMscript User’s Guide Published: July 2013 Table of Contents Diving Into GEMscript ............................................................................................................................................ 2 Hello World ......................................................................................................................................................... 3 Breakout Game ................................................................................................................................................... 5 Lesson 1: Accessing Objects ............................................................................................................................ 6 Lesson 2: Arithmetic ....................................................................................................................................... 8 Lesson 3: Arrays & constants ........................................................................................................................ 13 Lesson 4: Functions ....................................................................................................................................... 17 Lesson 5: Call-by-Value vs Call-by-Reference .............................................................................................. 21 Lesson 6: Rational Numbers ......................................................................................................................... 26 Lesson 7: Wrap up ......................................................................................................................................... 29 2 GEMscript User’s Guide | Amulet Technologies Hello World A GEMscript script consists of a set of functions and a set of variables encapsulated by an opening <script> and closing </script> tag. You may have multiple matching open and close script tags in the page functions editor. For brevity, after this first example, the opening and closing script tag will be omitted in code examples. The first program in almost any programming language is one that prints a simple string; printing “Hello World” is a classic example. In GEMscript, the simplest “Hello World” program would look like this: <script> @load() InternalRAM.string(0) = "Hello World" </script> A script will automatically start execution upon page load if an entry function is defined using the reserved word “@load” as the function name. The @ sign at the beginning of a function definition tells the compiler that this is a callback for one of the system events, which automatically fire the callback, in this case upon the completion of loading the page. The @ sign also makes the function “public”, meaning accessible outside the GEMscript VM. This means you may call the method again later if you wish, instead of only once upon page load. The function @load contains only a single instruction, which is at the line below the function head itself. Line breaks and indenting are insignificant; the invocation of the InternalRAM function could equally well be on the same line as the head of the function. The definition of a function requires that a pair of parentheses follow the function name. If a function takes parameters, their declarations appear between the parentheses. The function @load does not take any parameters. The rules are different for a function invocation (or a function call); parentheses are optional if the result is not used in an expression. GEMscript is a “case sensitive” language: upper and lower case letters are considered to be different letters. It would be an error to spell the function @load in the above example as “@Load”. Keywords and predefined symbols, like the name of the function “@load”, must be typed in lower case. The one exception is demonstrated in this example. The keyword InternalRAM is typed frequently, and since numerous other examples show it with varied capitalization, GEMscript is NOT case sensitive on the keyword internalram, or any names of its members, accessed with the “dot” syntax. The InternalRAM class is the primary channel in which you can exchange data with the Amulet OS. The members of the InternalRAM class are specified with a dot after the keyword InternalRAM, then a keyword for the type of data: byte, word, color, or string. The index of the InternalRAM variable immediately follows the type, inside a pair of parenthesis. The index has a range of 0-255 and can be a literal number, variable, or expression that returns an integer type. For example: 3 GEMscript User’s Guide | Amulet Technologies InternalRAM.byte(0) InternalRAM.color(Border_Color) InternalRAM.string(i+1) InternalRAM methods can be used just like variables, except they do not need to be declared or initialized by GEMscript (however, you can initialize them in the Amulet OS). If used as an argument in an expression or anywhere on the right side of the equals sign, this will perform a “get”. A “set” will be performed when this is used on the left side of an equals sign. Going back to the example, we can see it is performing a “set” command on an InternalRAM string variable at index 0, with a literal string as the argument. This makes a few assumptions. Simulating this code inside a blank project won’t do anything visible, so you must actually have a widget that is polling that specific InternalRAM variable so see something on the screen. In this case we are using a string, so the widget is a StringField and the code is setting string index 0, so the HREF of the StringField widget must be “Amulet:InternalRAM.string(0).value()”. Finally, we must consider the printing options for the widget and make sure that the string we want to print can fit within its internal buffer. This is defined in the printf parameter of the StringField, and the default lengths are actually long enough to fit the string “Hello World”. If you know the C language, you may feel that this first example does not look much like the equivalent “Hello world” program in C/C++. GEMscript can also look very similar to C, though. The next example program is also valid GEMscript syntax (and it has the same semantics as the earlier example): public main() { print("Hello World"); } print(string source{}) { InternalRAM.string(0) = source } Instead of using the system event @load, this script defines a function called main and declares this as a public function. The keyword public means that objects in the Amulet OS can access this function. At least one public function is necessary if the script is to do anything upon non-system events, like if you want to run some code when the user presses a specific button. In this case, in addition to our StringField to show the string, some mechanism is needed to execute the function “main”. The simplest is just a FunctionButton which calls the GEMscript function directly. This is done with the format: “GEMscript.functionName()”. The keyword “GEMscript” is not case sensitive, but the method name is. Currently, you cannot pass variables to these functions (use InternalRAM for that for now) so the ending pair of parenthesis is optional, but the demos in this tutorial will always use them. Once a FunctionButton widget is constructed with the HREF “GEMscript.main()” then you can compile and run the project. 4 GEMscript User’s Guide | Amulet Technologies These first examples also reveal a few differences between GEMscript and the C language:  there is no need to include any system-defined “header file”;  semicolons are optional (except when writing multiple statements on one line);  when the body of a function is a single instruction, the braces (for a compound instruction) are optional;  when you do not use the result of a function in an expression or assignment, parentheses around the function argument are optional. As an aside, the few preceding points refer to optional syntaxes. It is your choice what syntax you wish to use: neither style is “deprecated” or “considered harmful”. The examples in this manual position the braces and use an indentation that is known as the “Allman style”, but GEMscript is a free format language and other indenting styles are just as good. GEMstudio project files "hello.gemp" and "hello2.gemp" implement the above examples are included with your installation of GEMstudio under the folder: Documents\GEMstudio\GEMscript\ 5 GEMscript User’s Guide | Amulet Technologies Breakout Game In the following examples, you will be walked through the construction of a "breakout" style game. The chapters are broken up to introduce you to just a few new topics at a time, and each one will have a corresponding example (i.e. Lesson1.gemp) in the folder: Documents\GEMstudio\GEMscript 6 GEMscript User’s Guide | Amulet Technologies Lesson 1: Accessing Objects The first example "Hello World" program is overly simple to introduce GEMscript. More powerful scripts take some sort of input and create some kind of output. In GEMscript this input usually comes directly from the user or other Amulet OS event (such as a timer), or from another device (such as a sensor reading or another processor). For a breakout game, there are two inputs during game play. The user controls a "paddle" usually with horizontal movement. Time is the other input. The game "ball" moves throughout the 2D game "world" at a certain number of pixels per second. public moveBall() { //create integer X and set it to the value of MySlider_1 new int X = document.MySlider_1 //create integer Y and set it to the value of MySlider_2 new int Y = document.MySlider_2 //erase the current image of Ball document.Ball.disappear() //move Ball to new X and Y coordinates document.Ball.setx(X) document.Ball.sety(Y) //redraw the image Ball document.Ball.reappear() } Functions and Variables We declare the function moveBall as public so that it is callable from outside of GEMscript. Because there are multiple statements we must be enclose them in braces, { }. Variables must be declared using the keyword new, an error will be generated if new is omitted and the variable does not already exist. If the variable already exists as a global variable, this will create a new variable which overrides the global variable within the scope of this function. Each time the function is called the variables X and Y are recreated so their values are not preserved between function calls. Supported types are int, string, and float; if a type is not specified the variable is created as an int, for clarity all integers are declared explicitly in this manual. Newly declared variables may be initialized through the assignment operator =, but it is not required. An uninitialized variable will be initialized to zero, and strings will have every character initialized to zero. If we are not initializing a string when declaring it we must specify a length in brackets, [ ]. Accessing Objects The document class is the interface to all widgets existing on the page, only widgets which are on the 7 GEMscript User’s Guide | Amulet Technologies current page may be accessed. The document class is referenced in "dot" syntax, where each further level into the hierarchy is separated with a dot. These commands are case insensitive. Like the internalRAM class, accessible widget parameters can be read and assigned depending on which side of the assignment operator they appear. We initialize X and Y with the intrinsic value of MySlider_1 and MySlider_2. The intrinsic value of a Slider widget is the current value of the slider as set by the user. In addition to being able to get and set various parameters of widgets, each widget has a set of methods that perform various actions on the widget. These methods are called Inter-Widget Communications (IWC) and the comprehensive list of IWCs are presented in Appendix C of the GEMstudio Help. In moveBall the IWC methods disappear, setx, sety and reappear are used to erase, move and redraw the Ball widget which is an image of the ball in the breakout game. Considerations and Conclusion An important issue to consider is GEMscript functions are blocking, this means while moveBall() or any other function is running, the operating system is unable to perform other functions such as updating the contents of the display. So the IWC functions called during the execution of the GEMscript function, such as disappear, setX, setY and reappear will not be performed until after the function returns. If we put a forever loop at the end of moveBall() the ball's image will never move because the OS isn't provided the time to execute the scheduled functions. The code presented in this lesson is available in the GEMstudio project named "Lesson2.gemp". Feel free to modify the code to gain a better understanding of its functionality. 8 GEMscript User’s Guide | Amulet Technologies Lesson 2: Arithmetic The next step is to animate the ball traversing across the game screen and bouncing off the walls. To do this, we need to add two things to the project: (1) a free running interval timer that generates a timer event at the period of the animation frame rate, and (2) a timer event handler to service the timer events. At each timer event, the event handler needs to move the ball one step along its trajectory and change the trajectory vector if the ball collides with any of the walls. Creating The Interval Timer: The following Meta Refresh tag is used to create a 50mS interval timer with a GEMscript callback function named ball(): <META HTTP-EQUIV="REFRESH" CONTENT="0.05;URL=GEMscript.ball();Name=move_ball"> As with all <META> tags, the tag needs to be placed outside of the <SCRIPT>...</SCRIPT> tags. In the example project, the META tag is place below the </SCRIPT> tag, but it could be also placed above the <SCRIPT> tag. Like widgets, the timer function also has IWC methods. If we wish to use any of them, such as starting and stopping the timer, we need to give the timer object a name using the "Name" attribute. The example timer object above is named move_ball. The Timer Event Handler: The Interval timer, created above, has a callback function named ball() which serves as the timer's event handler. We will use GEMscript to write this event handler. But, to write the event handler we need to introduce 3 new GEMscript language concepts:  static local variables  conditional if statement with comparison operators  math operators static local variables We need 4 variables local to the ball() event handler to hold the Y and X coordinates of the ball and the X and Y portions of the slope of the ball's trajectory. Normally, variables that are local to a function only exist during the run time of that function because each new run of the function creates and initializes new local variables. But, since we need the value of our four variables to be preserved between each timer event, we need to declare the variables with the keyword static rather than new. Static local variables remain in existence after the end of a function, so the values will be preserved for the next time the function is called. Here is a sample of the GEMscript source code for our ball() event handler with all four static variables declared. Note that the data type is "int" which means that it is a 32-bit integer. Also since ball() is being called from the META object which is declared outside of the 9 GEMscript User’s Guide | Amulet Technologies <SCRIPT>...</SCRIPT> block, we must declare the function as public. public ball() { static int currenty = 0//X coordinate of ball. static int currentx = 0//Y coordinate of ball. static int yslope = 7 //DeltaX portion of slope. static int xslope = 4 //DeltaY portion of slope. } the conditional if statement and Comparison Operators Next, we need to handle the collisions between the ball and the walls so that we can make the ball bounce off each wall. To do this, we need to check the position of the ball to see if it is beyond the wall's boundaries. This is done with the conditional if statement and the comparison operators for greater than and less than. The following line of GEMscript code checks if the currentx position of the ball is greater than 200, which is the X coordinate of the right wall. if(currentx > 200)//Check for collision with vertical wall on right. We also need to check if the ball is to the left of the leftmost wall which is located at the X coordinate of 0. We could use another if statement, but the code to "bounce" the ball along the x-axis is exactly the same regardless if the ball bounces on the left wall or the right wall. So, it makes more sense to combine both conditional tests in the same if statement using the || operator for logical OR, as shown in the following line of code: //Check for collision with vertical walls on the left and right if(currentx > 200 || currentx < 0) To bounce the ball, all we need to do is reverse the direction along the axis of the bounce. This is can be done with one line of code nested under the if conditional, so that it executes only if the condition is satisfied: //Check for collision with vertical walls on the left and right if(currentx > 200 || currentx < 0) { xslope = -xslope //bounce by reversing X direction. } To handle bouncing off the top and bottom walls, we apply the same logic with another conditional block to complete the bouncing operation as follows: //Check for collision with vertical walls on the left and right 10 GEMscript User’s Guide | Amulet Technologies

Description:
GEMscript User's Guide | Amulet Technologies. Table of . The keyword InternalRAM is typed frequently, and since numerous other examples show it
See more

The list of books you might like

Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.