Chapter 9. GML Scripting—Part 1

At this point you should have a solid understanding of how to apply programming logic using Game Maker’s actionicons. Now, it is time to learn how to work with Game Maker’s GML scripting language. GML provides greater control over program execution, allowing you to exercise detailed control over the interaction of object instances and the environment in which these objects exist. In this chapter, you will learn how to collect, process, modify, and store data within your games and to apply conditional programming logic when analyzing and processing that data. You will also learn how to work with different types of operators, allowing you to apply arithmetic and compare data.

An overview of the major topics covered in this chapter includes learning how to:

  • Create and assign data using constants

  • Store, access, and manipulate data stored in variables

  • Store collections of data using arrays

  • Apply conditional programming logic

  • Work with different types of GML operators

Working with Game Data

Like all computer applications, games developed using Game Maker need to collect, manipulate, and store data. For example, the types of data in use include the number of points, scores, number of lives, and player health. Data might also include the player’s name or information about the size, location, direction, and speed of objects as they move about the screen.

Game Maker supports several different types of data, including:

  • Integer. Any whole number, positive or negative, as well as the number 0.

  • Real. Numbers that include decimal points.

  • String. A set of characters embedded within single or double quotation marks.

Data may be embedded or hardcoded within code statements or it can be dynamically collected, manipulated, and stored during game play. For example, in arcade games, data is collected through interaction with the user. Data can be collected from the keyboard and mouse. Game Maker even supports the use of joysticks.

Once collected, data must be stored someplace. Game Maker lets you pro-grammatically store individual pieces of data using variables and constants or collections of data using arrays. This data is stored in computer memory during game execution where it can be accessed and manipulated whenever it is needed.

Embedding Data within Code Statements

All computer games require the manipulation of some type of data. This data may be collected as a result of interaction with the user or it may be stored internally within the game. Game Maker provides a number of different ways of storing data. One of the most basic ways of working with data in your applications is to embed within your code statements, as demonstrated here:

show_message("The value of pi is 3.14.");

Here, the value of the mathematic constant pi (3.14) is embedded within a string passed to a GML function named show_message(). A string is a collection of one or more characters enclosed within single or double quotation marks.

Hint

The show_message() function displays (draws) text passed to it as a string on the screen. To use this function, you must initiate its execution using a Draw event.

Although embedding within code statements provides an effective means of handling small amounts of static information that never changes, this approach is not satisfactory in most games, where data is constantly changing. Game Maker provides you with a number of different ways to store data within your applications, including variables, constants, and arrays.

Working with Numbers and Strings

Game Maker supports three different types of data: integers, real numbers, and strings. Each of these types of data is handled differently. Integers and real numbers can be added, subtracted, multiplied, and divided. Strings can be concatenated together, creating a new, larger string. However, strings cannot be subtracted, multiplied, or divided. An integer is a whole number, whereas a real number has a decimal point. As previously stated, a string is created by enclosing characters within single or double quotation marks.

Storing Data in Variables

As is the case in all programming languages, Game Maker can store and modify data within your games. One way that this is achieved is through the use of variables. A variable is a pointer to a location in memory where data is stored. Variables are used to store individual pieces of data.

Creating Variables

As you define the variables used in your GML scripts, make sure you assign them descriptive names. This helps to make your code statements self-documenting and easier to understand. Game Maker variable names are case-sensitive. From Game Maker’s view, a reference to a variable named player1 is not the same thing as a reference to a variable named Player1. So be careful to use a consistent case when naming your variables. Variables must be uniquely named. When naming variables, you must follow the rules outlined below.

  • Variable names must begin with a letter.

  • Variable names can only contain upper- and lowercase letters, numbers, and underscore characters.

  • Variable names cannot contain blank spaces.

  • Variable names cannot be Game Maker language keywords or the names of other defined game resources.

Game Maker does not require you to explicitly declare variables. Instead, all you have to do to create a new variable is to use it. In order to assign a value to a variable, you use the = operator, as demonstrated below.

name = "Alexander";

Here, a variable named name is created and assigned a string value of Alexander. If this variable already existed, Game Maker would simply change its value as instructed in the assignment statement.

Hint

When developing programming logic using Game Maker’s action icons, you can also work with variables using the actions shown in Figure 9.1 to create, modify, analyze, and display variable values.

These action icons facilitate the use of variables.

Figure 9.1. These action icons facilitate the use of variables.

Managing Variable Scope

Game Maker supports three types of variables, each of which has a different scope. Scope defines the locations within your application from which variables can be accessed. The three types of variables that Game Maker supports are outlined here:

  • Instance. Variables accessible within the instance in which they are defined in other instances.

  • Global. Variables accessible throughout the game.

  • Local. Variable access is limited to the script in which they are defined.

Defining Instance Variables

By default, the variables you define within your scripts have an instance scope, making them accessible to other like instances. To modify the contents of a variable in the current instance, all you have to do is reference it by name, as demonstrated here:

name = "Alexander";

Game Maker lets you access the contents of other instance variables. To do so, you use dot notation, specifying the name of the other instance, followed by a dot (period character), and then the name of the variable you want to work with, as demonstrated here:

x = playerOne.name;

Here, the value stored in a variable named name belonging to an object named playerOne is assigned to a variable named x.

Defining Global Variables

Game Maker also supports the use of global variables, which can be accessed from any location within an application. There are two ways of working with global variables. First, you can use the global keyword when initially creating them, as demonstrated here:

global.age = 21;

To refer to this global variable from other locations within an application, you must use the global keyword, as demonstrated here:

global.age = 18;

Alternatively, rather than use the global keyword repeatedly throughout your scripts, you can use the globalvar keyword to declare a variable as global, as demonstrated here:

globalvar age;
age = 21;

Here, a global variable named age is defined and then assigned an initial value. If you need to, you can declare multiple variables as local using a single statement, as shown here:

globalvar age, name, address, phone;

Defining Local Variables

In general, it is considered to be good programming practice to restrict variable scope as tightly as possible, as this reduces a program’s memory requirements and reduces the changes of accidently modifying a variable’s value. To restrict variable access to the script in which it is used, you need to declare your variables at the beginning of the script using the var keyword, as demonstrated here:

var age;
age = 21;

Here, a single local variable named age is defined and then assigned a value. If you need to, you can declare multiple variables as local using a single statement, as shown here:

var age, name, address, phone;

Game Maker’s Special Variables

As you have already seen through various action icons, Game Maker provides access to a large number of special variables that it automatically creates and maintains during program execution. These include both global and local variables. Examples of global variables are lives, score, and health. There are also global variables that provide information about the location and the operations of the mouse, including mouse_x, mouse_y, and mouse_button. Examples of Game Maker’s special local variables include:

  • x. The x-coordinate for a given object instance.

  • y. The y-coordinate for a given object instance.

  • direction. The direction (angle) an object instance is moving.

  • speed. The speed (in pixels per step) that an object is moving.

  • hspeed. The speed along the horizontal axis (in pixels per step) that an object is moving.

  • vspeed. The speed along the vertical axis (in pixels per step) that an object is moving.

  • solid. Specifies whether an object instance is solid or not.

  • sprite_height. Contains the height of a sprite (in pixels).

  • sprite_width. Contains the width of a sprite (in pixels).

You can retrieve and analyze the values stored in any of these variables, and in most cases, you can change their values as well, directly impacting the operations of your games as a result.

Trick

To view a listing of all special global and local variables created and maintained by Game Maker, click on Scripts > Show Built-in Variables.

Working with Data That Does Not Change

Though useful, variables are not appropriate for storing data whose value does not change during game execution because variables can accidentally be modified. A better solution for storing this type of data is by using constants. A constant is a value whose value is known at design time and does not change when the game executes.

Game Maker automatically generates and manages a huge collection of predefined constants, whose values you can access from within your GML code in exactly the same manner as you reference variable values. An example of one such constant is pi, which is set to 3.14. Other examples of constants that Game Maker makes readily available to you include a range of the color constants shown below.

  • c_aqua

  • c_black

  • c_blue

  • c_dkgray

  • c_fuchsia

  • c_gray

  • c_green

  • c_lime

  • c_ltgray

  • c_maroon

  • c_navy

  • c_olive

  • c_orange

  • c_purple

  • c_red

  • c_silver

  • c_teal

  • c_white

  • c_yellow

In total, Game Maker provides access to close to 300 predefined constants, offering access to keyboard, mouse, joysticks, and many other types of data.

Trick

To view a listing of all predefined constants created and maintained by Game Maker, click on Scripts > Show Constants.

You can create and add your own constants to your Game Maker games. For example, if you created a game that awarded the player extra lives when certain score levels were achieved, you might want to save this value in a constant. To add a constant to a Game Maker game, click on Resources > Global Game Settings. This opens the Global Game Settings window. Select its Constants tab. This window displays any constants that you choose to add to your game. For example, Figure 9.2 shows an example of three constants that have been added to the game.

You can add any number of constants to your games.

Figure 9.2. You can add any number of constants to your games.

Using the buttons located at the bottom of the window, you can insert, delete, append, and clear constants. You can also change the order in which the constants are defined by selecting individual constants and then clicking on the Up and Down buttons to change its location in the list. Lastly, you can click on the Sort button to sort the window’s contents.

Constants offer a number of advantages. First, their values cannot be accidently changed. Second, when assigned descriptive names, constants can make your code self-documenting. Lastly, constants typically require less memory than variables, making your games more efficient.

Managing Collections of Data

As long as your applications only need to work with and manage a handful of variables at a time, you can use variables to manage the storage of all the data in your games. On the other hand, if your games require that you create and manage hundreds or thousands ofvalues, variables alone won’t get the job done. In these situations you need to use arrays. An array is an indexed list of data that is stored and managed as a collection. The data that you store in an array is accessed using the array’s name and the index position of the data.

Game Maker lets you create one- and two-dimensional arrays. A one-dimensional array is like a list. A two-dimensional array can be thought of as being like a spreadsheet consisting of rows and columns. While Game Maker lets you create two-dimensional arrays, this chapter will focus on teaching you the basics of working with one-dimensional arrays.

Creating Arrays

GML lets you create both one- and two-dimensional arrays. Single-dimensional arrays are created in GML by assigning them a name followed immediately by a [ bracket and a number representing the array’s index followed by a closing ] bracket, as demonstrated below.

Like variables, you do not have to declare arrays prior to using them. The syntax that you must follow when defining an array is outlined here:

arrayname[indices]

arrayname represents the name of the array being created, indices is a comma-separated list of numeric values that specifies whether the array has one or two dimensions. The following example demonstrates how to define an array named animals[] that is capable of storing six elements.

animals[5]

All array indices in GML begin at 0, so as defined above, the animals[] is capable of storing six entries (0 through 5). In GML, two-dimensional arrays are created by assigning them a name followed immediately by a [ bracket and two comma-separated numbers representing both of the array’s indices, followed by a closing ] bracket, as demonstrated here:

animals[4,4]

GML limits array index size to 32,000 and limits an array’s overall storage capability to 1,000,000 entries.

Populating Arrays with Data

Game Maker arrays are zero-based. The first element (value) in the array starts at index location 0, and the second element in the array begins at location 1. The following example demonstrates how to create an array named names and assign it three elements.

{
   names[0] = "Molly";
   names[1] = "William";
   names[2] = "Alexander";
}

Retrieving Data from Arrays

Once created, you can reference any element in an array by specifying its index number, as demonstrated here:

{
   names[0] = "Molly";
   names[1] = "William";
   names[2] = "Alexander";

   show_message("Match!");
}

Here, an array made up of three elements is created, and the second element (William) stored in an array is retrieved and displayed. Be repeating and modifying the last statements shown above, you could modify this example to display all of the array’s contents.

Rather than retrieving data an element at a time, it is usually a better idea to set up a loop to iterate through the array’s contents. For example, the following script creates an array and then loops through it using a for loop to iterate through and display its contents. More information on loops is provided in Chapter 10.

{
   names[0] = "Molly";
   names[1] = "William";
   names[2] = "Alexander";

   x_coord = 50;
   y_coord = 50;

   for (i=0; i<3; i=i+1) {
        draw_text(x_coord, y_coord, names[i]);
        y_coord = y_coord + 20
   }
}

Evaluating Options Using Conditional Logic

In order to create games of any level of complexity, you need the ability to analyze the data collected by your games and to conditionally execute different programming logic based on the results of that analysis. The result of any conditional analysis comes down to a determination as to whether the condition being tested results in a value of true or false. If the result of the analysis is true, one set of actions is taken. If the result is false, a different set of actions may be taken. Game Maker provides two programming statements that facilitate the implementation of conditional logic. The first is the IF statement and the second is the SELECT statement.

Hint

Game Maker provides access to 18 action icons that facilitate various forms of conditional logic, including those shown in Figure 9.3.

These actions facilitate things like analyzing collision detection and testing expressions. Action icons that perform conditional logic are easily identified; they only have eight sides.

Any eight-sided action icon can be used to implement conditional logic.

Figure 9.3. Any eight-sided action icon can be used to implement conditional logic.

Introducing the if Statement

An understanding of how to work with the if statement, along with its corresponding else statement, is required to develop even the most simple scripts. Using the if statement, you can implement any type of conditional test. Using the optional else statement, you can specify what you want to happen in the event the tested conditional evaluates as false.

if Statement Syntax

You use the if statement to evaluate an expression and then initiate an action if that expression evaluates as true. Using the if statement and its corresponding else statement, you can specify an alternate action to be performed in the event the expression evaluates as false. Using the syntax outlined below, you can set up conditional code blocks that can execute any number of code statements based on the results of that analysis.

if (expression){
     statements
}

else {
   statements
}

Here, expression evaluates to a value of true or false. statements represents one or more code statements that will be executed. else is an optional keyword that tells Game Maker what to do in the event the tested condition evaluates as false.

Single Line if Statements

In its simplest form, the if statements can be used to create a single-line statement using the syntax outlined here:

if (expression) statement;

Single-line if statements are well suited to situations where you do not need to perform an alternative action should the tested expression evaluate as false and where you do not have to perform more than a single action when the expression evaluates as true. As a demonstration, the following statements demonstrate the use of this version of the if statement in order to control the conditional display of a text statement.

secretNumber = round(random(2) + 1);
displayMsg = "I am thinking of a number from 1 to 3, try to guess it."

userGuess = get_string(displayMsg, "");

if (secretNumber == real(userGuess)) show_message('You guessed it!");

Here, a real number between 0 and 2 is generated by calling on the random() function and passing it a numeric argument indicating the upper range from which it is to generate its results. Next, the round() function is used to round the value generated by the random() function to the nearest integer value. A value of 1 is added to the result, resulting in a randomly generated number in the range of1 to 3. Next, a variable named displayMsg is created and assigned a string.

Next a variable named userGuess is created and assigned a value returned to it by the get_string() function. The get_string() function displays a popup dialog. It accepts two arguments, The first argument is the message that is displayed. The second argument is the default value displayed in the popup dialog window. Passing an empty string as the second argument means that a default value is not displayed in the popup dialog window. Lastly, an if statement is used to compare the value assigned to secretNumber against a value of userGuess. Since secretNumber is an integer and userGuess is a string, the value assigned to userGuess had to be converted to a numeric value, which was done using the real() function.

if Statement Code Blocks

In the event that you need to execute more than one statement when an if statement’s expression evaluates as true, you need to set up an if statement code block using the syntax outlined below.

if (expression){
   statements
}

Trap

Note that unlike the single line version of the if statement, you must include the opening { and closing } characters when formulating a multi-line code block.

Using the previously outlined syntax, you can group and conditionally execute any number of code statements, as demonstrated here:

secretNumber = round(random(2) + 1);
displayMsg = "I am thinking of a number from 1 to 3, try to guess it."

userGuess = get_string(displayMsg, "");

if (secretNumber == real(userGuess)) {
    show_message("You guessed it!");
    sleep(3000);
    game_end();
}

Here, three code statements are executed in the event the user is able to guess the randomly generated secret number. The first of these three statements displays a congratulatory message. The second statement executes the sleep() function (equivalent to the sleep actions), which is used to pause script execution for three seconds. Lastly, the game_end() function is executed, terminating the execution of the game in which the script executes.

Setting Up Alternative Courses of Actions

Using the optional else statement in conjunction with the if statement, you can specify two different sets of programming statements, one to be executed when the tested expression proves true and another to execute when the expression evaluates as false, as demonstrated here:

secretNumber = round(random(2) + 1);
displayMsg = "I am thinking of a number from 1 to 3, try to guess it."

userGuess = get_string(displayMsg, "");

if (secretNumber == real(userGuess)) {
    show_message("You guessed it!");
} else {
    show_message("Sorry. Your guess was wrong.");
}

Nesting if Statements within One Another

One of the powerful features of using the if statement to develop conditional programming logic is that the if statement allows you to embed or nest it within other if statement code blocks. Nesting conditional code blocks within one another facilitates the development of more complex programming logic, as demonstrated here:

a = 5;
b = 10;
c = 20;

if (a == 5) {
    if (b == 10) {
        if (c == 20) {
            draw_text(200, 200, "Bingo!");
        }
    }
}

By nesting if statement code blocks you can create programming logic that conditionally performs one test based on the result generated by a higher-level code block. In the previous example, three if statement code blocks have been defined, each of which evaluates the value assigned to a different variable. Only if all three code blocks evaluate as true is the draw_text() function executed.

Comparing One Value Against a Series of Matching Values

In addition to various adaptations of the if statement, Game Maker allows you to implement conditional logic using the switch statement. This statement is designed as a substitute for using multiple if statement code blocks. The switch statement is designed for situations where you need to compare one value against a range of different values. The switch statement must be used in conjunction with a number of other statements, including the case, break, and default statements, to create a code block as outlined here:

switch (expression){
    case expression:
         statement;
         .
         .
         .
         break;
    case expression:
         statement;
         .
         .
         .
         break;
   .
   .
   .
    default:
        statement;
        .
        .
        .
}

The switch statement code block begins with the switch statement followed by the expression to be evaluated and then a series of case blocks, each of which is designed to analyze a possible match with the expression. Each case block specifies its own expression that is compared to the switch statement’s expression. The statements embedded within the first case statement that results in a match are executed and the rest of the statements in the switch code block are skipped. In the event that none of the case statements results in a match, the statements embedded within the default code block are executed.

Note that the default statement and its code block are optional. If omitted and none of the expressions belonging to the case statements match the expression belonging to the switch statement, then nothing happens. Inclusion of the break statements is also optional and if omitted, any case statement that evaluates as true will be executed.

As an example of how to set up a switch statement code block, consider the following example.

{
   userGuess = get_string("Okay, what is the game rated?", "");

   switch (userGuess) {
       case "e": draw_text(200, 200, "Yes. Of course you may."); break
       case "t": draw_text(200, 200, "Yes. I suppose you can."); break
       case "m": draw_text(200, 200, "No. Wait until you are older."); break
       case "a": draw_text(200, 200, "No. Not in my house!"); break
       default: draw_text(200, 200, "No. I need to know more about it.");
   }

   sleep(3000)
   game_end()
}

Here, the user is prompted to enter a video game rating (e, t, m, or a). A switch statement code block is then used to analyze the user’s input and to compare it against a series of four case statements. A different text string is displayed based on the user’s input. If the user enters something other than e, t, m, or a, the string belonging to the default statement is displayed.

Comparing Values Using Relational Operators

So far, all of the examples that you have seen in this book have used the equality (==) operator to determine when values were equal. Game Maker supports a number of other relational operators. You can use these operators to perform comparisons based on ranges of values. Game Maker supports all of the relational operators shown in Table 9.1.

Table 9.1. GML’s Relational Operators

Operator

Description

Example

Result

==

Equal to

6 == 5

False

!=

Not equal

6 != 5

True

<

Less than

5 < 6

True

<=

Less than or equal to

7 <= 4

False

>

Greater than

5 > 4

True

>=

Greater than or equal to

5 >= 5

True

Crunching Numbers

Game Maker gives you the ability to perform addition, subtraction, multiplication, and division. The following statements demonstrate how to use the + operators to add two numbers together.

x = 100;
y = 50;
z = x + y;

When executed, z is assigned a value of 150. Table 9.2 outlines the arithmetic operators supported by Game Maker and shows examples of their use.

The last five operators listed in Table 9.2 merit additional explanation. For starters, you can use negative numbers in your expressions. Negative numbers are preceded by a - character, without any intervening space and can be used as demonstrated here:

x = 10
y = -5
z = x + y

When executed, a value of 5 is assigned to z. The remaining four operators listed in Table 9.2 combine arithmetic and assignment functionality into a single operator, providing you with the ability to modify and assign a value in a single step.

One of the best ways to understand how Game Maker performs arithmetic calculations is to work through an example like the one shown below.

x = 8 + 4/2- 2* -7 + 2

Table 9.2. GML’s Arithmetic Operators

Operator

Description

Example

Result

+

Addition

x = 3 + 2

5

Subtraction

x = 5 –– 3

2

*

Multiplication

x = 2 * 4

8

/

Division

x = 10 / 3

3.33

div

Integer Division

x = 10 div 3

3

mod

Modulo (returns remainder)

x = 10 mod 3

1

–x

Reverses a variables sign

x = –x

–1

+=

Shorthand for x = x + y

x += 5

4

–=

Shorthand for x = x – y

x–=5

–1

*=

Shorthand for x = x * y

x *= 5

–5

/=

Shorthand for x = x / y

x /= 5

–2.5

Game Maker processes this statement using the steps outlined here:

  1. Working from left to right, all division and multiplication operations are performed first. Therefore, 4 is divided by 2 yielding a value of 2, and 2 is multiplied by -7 yielding a value of -14. At this point the status of the equation is as shown below.

      x = 8 + 2 - -14 + 2
  2. Addition and subtraction are performed next, on a left to right basis, resulting in a final value of 26 being assigned to x.

Hint

If necessary, you can override Game Maker’s default order of precedence by enclosing different parts of equations inside parentheses. To see how this works, take a look at the following statement.

  x = (8 + 4)/ 2-2* (-7 + 2)

When parentheses are used, their contents are evaluated first, on a left to right basis, and then the result of the expression is processed according to GML’s order of precedence. In the case of the previous statement, this results in a value of 16 instead of a value of 26.

Commenting GML Code

In order to help make your GML code easier to understand, you should get into the habit of embedding comment statements into your scripts. Comments do not affect the performance of your games. GML supports two types of comments.

You can add comments at any location within your scripts by typing // followed by the text of your comment, as demonstrated below:

//Generate a random integer from 1 - 3
secretNumber = round(random(2) + 1);

If you want, you can also append comments to the end of your code statements, as demonstrated here:

secretNumber = round(random(2) + 1); //Generate a random integer from 1 - 3

GML also lets you add multi-line comments to your scripts placing text inside opening /* and closing */ characters, as demonstrated below.

/*
Display a popup dialog window that prompts the player to enter a numeric
Guess in the range of 1 to 3.
*/

Summary

This chapter provided a basic understanding of how to apply programming logic using Game Maker’s GML scripting language. GML allows you to execute stricter control over the execution of your games. This chapter showed you how to collect, process, modify, and store data within your games. You also learned how to apply conditional programming logic when analyzing and processing the data used by your games. You learned how to define constants and variables and to manipulate collections of data using arrays. On top of all this, you learned how to apply conditional programming logic, compare program data, and set up arithmetic operations.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset