- Title: Overlooked features of GM
- Description: Arrays, global variables, and scripts/functions are some of the most underused features of Game Maker.
- GM Version: Game Maker 7
- Registered: No
- File Type: .gmk
- File Size: Various
- File Link: Links to examples can be found throughout the tutorial.
Tutorial
Now, even though this is easy for the beginning programmer, it does require some knowledge about how GML works. Sorry, no DnD. Also, make sure your Game Maker settings are for "Advanced" and not "Simple".
Arrays
Arrays are little things that group multiple pieces of info into a set of columns and rows. I could go into technical terms, but for the new programmer, I'm going to keep this as simple as I can.
Now there are 3 types of arrays: 1D, 2D, and 3D arrays. I will only be going into 1D and 2D because 3D arrays are just a mix of the two.
Arrays are usually portrayed as: variable[0] for 1D, and variable[0,0] for 2D.
1D ARRAYS
1D arrays keep track of lists, like a list of items. For example, say you wanted to show an inventory of a list of about 50 items. Now, it's about 2 hours worth of work to list these individually, so we'll list them using a for loop.
So, let's make a 1D array for a list of 5 items:
Start by making a new game. Create a room, an object, and 2 scripts. Name the room "rm_start", the object "obj_gamestart", and the scripts "scp_gs_create" and "scp_gs_draw".
Place the object somewhere in the room, doesn't matter where. In the object, start a "Create Event" and a "Draw Event". Going into the DnD control tab, drag the
icon into the action window of both. Select the "scp_gs_create" script for the Create Event, and the "scr_gs_draw" script for the Draw Event.Now open the script for "scp_gs_create" and type/copy&paste the following code:
// This should go into the create event of the Game Start Object. // Ok, so now we're going to make a list of the items. item[0] = "Sword" // Item 1 is a Sword item[1] = "Shield" // Item 2 is a shield item[2] = "Helmet" // Item 3 is a helmet item[3] = "Glove" // Item 4 is a Glove item[4] = "Accessory" // Item 5 is an accessory.
Cliche, I know, but good generic example.
So now we want these to show up on the screen.
Open the "scp_gs_draw" script. Now, we could do this one of two ways. Here is the long way:
// This should go into the Draw Event of the Game Start Object. // This is a generic code that will do what we need, but uses a lot of code. draw_text(5,5,item[0]); // Draws the text "Sword" at 5 pixels across, 5 pixels down from the top-left corner of the screen. draw_text(5,25,item[1]); // Draws the text "Shield" at 5 pixels across, 15 pixels down from the top-left corner of the screen. draw_text(5,45,item[2]); // Draws the text "Helmet" at 5 pixels across, 25 pixels down from the top-left corner of the screen. draw_text(5,65,item[3]); // Draws the text "Glove" at 5 pixels across, 35 pixels down from the top-left corner of the screen. draw_text(5,85,item[4]); // Draws the text "Accessory" at 5 pixels across, 45 pixels down from the top-left corner of the screen.
Now imagine doing that to 50 items. Might take a while, not to mention a lot of calculations. So we'll use a "for loop".
A "for loop" is a set of conditions that are looped until the problem is solved.The format of a for loop looks something like this:
for ([starting the problem] ; [the solution if false] ; [what to do to the problem] ;)
{
do this while the loop is looping
}
so an example is:
for (i = 0; i < 15; i += 1)
I'll transform this into a simple if/else statement. Keep in mind that the only difference between this and a for loop is that a for loop does this all in one step, not several:
// Create event
i = 0; // This is the "starting problem".
// Step Event
if i < 15
{
i += 1
do this
}So now that you have a grasp of how a for loop works, here is the economic way to use 1D arrays.
// This should go into the Draw Event of the Game Start Object.
// This code uses the same amount of time to make, whether you have 5 or 50 items in your array.
for (i = 0; i < 5; i += 1;) // We want the loop to see if "i" is less than or equal to 5, and add 1 to "i" if it is.
{
draw_text(5, 5 + (i * 20), item[i])
/* Ok, allow me to explain this in sections.
draw_text(x,y,string) - Only once.
So for x, we want 5 pixels across. It puts the results in a nice even line.
For y, we want 5 [5 pixels from the top] + (i [increases per loop] * 20 [pixel difference per text line])
And for the string, we want item[i(which increases per loop)]
*/
}So this code will work for 5 or 500 items. You might have to add additional code if you have too many or it'll eventually disappear off the bottom of the screen.
EXAMPLE LINK: http://games.kiraoft...er/1darrays.gmk
2D ARRAYS
2D Arrays are lists with features. Take the previous list, for example. Let's use the previous Game Maker setup as a template. We can now take those items and give them attributes:
// This should go into the create event of the Game Start Object. // Ok, so now we're going to make a 2d array list of the items. // Array for Sword. item[0,0] = "Sword" // This is the name of the item. item[0,1] = 10 // This is the strength of the sword. item[0,2] = "A sharp sword for killing enemies." // This is the description of the item. // Array for Sheild. item[1,0] = "Shield" // This is the name of the item. item[1,1] = 10 // This is the defence of the shield. item[1,2] = "A defensive shield for protection." // This is the description of the item. // Array for Helmet. item[2,0] = "Helmet" // This is the name of the item. item[2,1] = 10 // This is the defence of the helmet. item[2,2] = "A defensive helmet for protection." // This is the description of the item. // Array for Glove. item[3,0] = "Glove" // This is the name of the item. item[3,1] = 10 // This is the strength of the glove. item[3,2] = "A strong glove for stronger grip." // This is the description of the item. // Array for Accessory. item[4,0] = "Accessory" // This is the name of the item. item[4,1] = 10 // This is the defence of the accessory. item[4,2] = "An accessory that defends against elements." // This is the description of the item.
So for each array in this case, we have this format:
variable[list item, attribute]
So what can we do with this?
Well, we can do an expantion of what we did earlier. I'm going to make a table in the Draw Event.
// This should go into the Draw Event of the Game Start Object.
// This code uses the same amount of time to make, whether you have 5 or 50 items in your array.
// First, we're going to make a table with a header and separators.
// HEADER
draw_text(5,5,"ITEM")
draw_text(105,5,"ATTRIBUTE")
draw_text(255,5,"DISCRIPTION")
// SEPARATORS
draw_line(0,25,640,25) // Draws a line under the header
draw_line(100,25,100,180) // Draws a line that splits "ITEM" and "ATTRIBUTE".
draw_line(250,25,250,180) // Draws a line that splits "ATTRIBUTE" and "DISCRIPTION".
// ITEM list
for (i = 0; i < 5; i += 1;) // We want the loop to see if "i" is less than 6, and add 1 to "i" if it is.
{
draw_text(5, 30 + (i * 25), item[i,0])
/*
Ok, allow me to explain this in sections.
draw_text(x,y,string) - Only once.
So for x, we want 5 pixels across. It puts the results in a nice even line.
For y, we want 30 [30 pixels from the top] + (i [increases per loop] * 25 [pixel difference per text line])
And for the string, we want item[i(which increases per loop),0(item name)]
*/
}
// ATTRIBUTE list
for (i = 0; i < 5; i += 1;) // We want the loop to see if "i" is less than 6, and add 1 to "i" if it is.
{
draw_text(105, 30 + (i * 25), item[i,1])
/*
draw_text(x,y,string) - Only once.
So for x, we want 105 pixels across. It puts the results in a nice even line.
For y, we want 30 [30 pixels from the top] + (i [increases per loop] * 25 [pixel difference per text line])
And for the string, we want item[i(which increases per loop),1(item attribute)]
*/
}
// DISCRIPTION list
for (i = 0; i < 5; i += 1;) // We want the loop to see if "i" is less than 6, and add 1 to "i" if it is.
{
draw_text(255, 30 + (i * 25), item[i,2])
/*
draw_text(x,y,string) - Only once.
So for x, we want 255 pixels across. It puts the results in a nice even line.
For y, we want 30 [30 pixels from the top] + (i [increases per loop] * 25 [pixel difference per text line])
And for the string, we want item[i(which increases per loop),2(item description )]
*/
}Looks like a bunch of code, but it's pretty much the same thing over and over with slight alterations.
EXAMPLE LINK: http://games.kiraoft...rrays_part1.gmk
There is also another use for 2D Arrays. Mainly for character select or somthing like that.
So say you're making a fighter game or an arcade game in which you select a character.
Let's use the previous example as a template. Just add a couple more things, a Step Event to the obj_gamestart object, a new script called "scp_gs_step", and 3 sprites. Just make the sprites the standard size boxes and colors of your choice (different colors for each sprite) and name them "spr_ron", "spr_jill", and "spr_frank".
So put this in "scp_gs_create":
// This should go into the create event of the Game Start Object. // Ok, so now we're going to make a 2d array list of the characters. // Array for character "Ron". character[0,0] = "Ron" // This is the name of the character. character[0,1] = 15 // This is the strength of the character. character[0,2] = 5 // This is the defence of the character. character[0,3] = spr_ron // This is the sprite of the character. // Array for character "Jill". character[1,0] = "Jill" // This is the name of the character. character[1,1] = 5 // This is the strength of the character. character[1,2] = 15 // This is the defence of the character. character[1,3] = spr_jill // This is the sprite of the character. // Array for character "Frank". character[2,0] = "Frank" // This is the name of the character. character[2,1] = 10 // This is the strength of the character. character[2,2] = 10 // This is the defence of the character. character[2,3] = spr_frank // This is the sprite of the character. // Now we set some standard creation variables. message = "Select a character!" // Default message select = 3 // An odd number for a creation variable, but 0 is taken...
And put this in "scp_gs_draw":
// This should go into the Draw Event of the Game Start Object. // This is going to draw everything on the screen. draw_text(5,5,message) // This draws whatever "message" is at the time. draw_sprite(spr_ron,0,96,368) // This draws sprite "spr_ron". draw_sprite(spr_jill,0,304,368) // This draws sprite "spr_jill". draw_sprite(spr_frank,0,528,368) // This draws sprite "spr_frank". draw_text(96,400,"Ron") // This draws the text "Ron" under their sprite. draw_text(304,400,"Jill") // This draws the text "Jill" under their sprite. draw_text(528,400,"Frank") // This draws the text "Frank" under their sprite.
And finally, put this in the new "scp_gs_step":
// This should go into the Step Event of the Game Start Object.
// So we're going to make it so you can select a character and their attributes are selected.
// First we're going to give the mouse something to do.
if (mouse_x >= 96) and (mouse_x <= 128) and (mouse_y >= 368) and (mouse_y <= 400) and (mouse_check_button(mb_left))
// This long bit of code checks to see if the mouse is over the sprite.
{
select = 0 // Making up variables here. This one controls the character array. "Ron" selected.
}
else if (mouse_x >= 304) and (mouse_x <= 336) and (mouse_y >= 368) and (mouse_y <= 400) and (mouse_check_button(mb_left))
{
select = 1 // Jill selected.
}
else if (mouse_x >= 528) and (mouse_x <= 560) and (mouse_y >= 368) and (mouse_y <= 400) and (mouse_check_button(mb_left))
{
select = 2 // Frank selected.
}
// This next part is just a message to display your selection, but really you can do a lot more.
/*
Bear with me, character[select(whatever character is choosen),0].
Remember that Ron is 0, Jill is 1, and Frank is 2.
So if Frank is the selected character, "select" becomes 2 and
the arrays suddenly say character[2,0], which is Frank's name.
*/
if (select = 3) // The unused select and the default
{
message = "Select a character!"
}
else // If a character is selected
{
// So this message uses variables in it. To do that, separate the strings from the variables with a [+string()]
message = "You have choosen " + string(character[select,0]) + string(".##Strength: ") + string(character[select,1]) + string("##Defence: ") + string(character[select,2])
}I know this is extensive and that normally you want to put a lot of this in other events and objects, but for simplicity's sake I limited the objects and scripts.
So basically what this set of scripts do is give you the option to select a character and then is displays that character's attributes based on their 2D array. You can go on further to create one generic script that controls the character's actions and the specifics are controlled by 2D arrays.
EXAMPLE LINK: http://games.kiraoft...rrays_part1.gmk
And that concludes the Array tutorial.
Global Variables
So this is a short bit on setting up global variables. Now the most common way of doing this is putting global. before the variable, but this puts a bunch of global.s all over your script and it can be a bit distracting. So this is what I do.
I create a script called "scp_globalvars". I put this in the Create Event of a game start object. The script will look something like this:
// This goes in the Create Event of the Game Start Object. // I'm going to set up my personal global variables here. globalvar item, // This controls the global item array character, // This controls the global character array other; // This controls the any other variable that needs to be made global.
Remember that global variables should only be used for variables used in multiple objects. Also remember that the format for globalvar is:
globalvar variable1, variable2, variable3;
Please note the commas and the semi-colon. Unlike a lot of things in GML, these are required.
Scripts/Functions
Now you may have noticed that I keep having you build scripts
instead of using the Execute Code Action
. This is because I find that using scripts allows you to edit code without having to open the object as well as editing multiple scripts at the same time instead of one at a time. The downside of this is that it might take a little longer to load your game. Pro and Cons I guess...Now, scripts are mostly used as functions. A function is basically a chunk of code that can be executed as many times as you need without having to type it out. In these functions you can set arguments, which are variables dependent on the specific situation. For example:
script(argument0, argument1, argument2, etc.)
I'm going to set up a simple script to act as a function with arguments. I'm calling the script "f_playsound". This is what I'm going to put in it:
// This is a function to play sound or loop sound depending on argument1
/*
argument0: sound name
argument1: Will it loop? 0 is no, 1 is yes.
*/
if argument0 = 0
{
sound_play(argument0)
}
else if argument0 = 1
{
sound_loop(srgument0)
}So what we got here is a function that adds an extra argument to sound_play(). Now if you want to use it, just put in the script name and the arguments in paranthesis, like this:
f_playsound(sound0,1)
What this will do is loop sound0 starting in the place that function was written.
-----------------------------------------------------
Well, I hope this helps a lot of you out. I wish I knew this stuff sooner, it would have made for a lot less headache...
UPDATE:
Fixed the "i" in the 1D code block.
Edited by Kira Games, 02 December 2009 - 08:58 PM.











