Jump to content


Photo
- - - - -

Overlooked Features Of Gm


  • Please log in to reply
22 replies to this topic

#1 Kira Games

Kira Games

    GMC Member

  • GMC Member
  • 134 posts

Posted 30 November 2009 - 04:02 AM

  • 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.
Additional Info

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 Posted Image 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 Posted Image instead of using the Execute Code Action Posted Image. 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.

  • 1

#2 EucoDan

EucoDan

    EucoGames Coder

  • New Member
  • 478 posts

Posted 02 December 2009 - 07:55 AM

Clearly you put a lot of effort into this, and I'm grateful.

However, it's just not something that needs a typed tutorial. Arrays and global variables are pretty basic if you use a good metaphor, and well, making functions?

Yeah. Thanks, but try again! :D
  • 0

#3 Robert3DG+

Robert3DG+

    VR Games

  • GMC Member
  • 1823 posts
  • Version:GM:Studio

Posted 02 December 2009 - 10:57 AM

Really good and well written. I'm sure it will help loads of members :D
  • 0

#4 tidus97

tidus97

    GMC Member

  • New Member
  • 580 posts

Posted 02 December 2009 - 11:22 AM

what arcπ said. these are basic stuff; hardly "overlooked". otherwise, good job.
  • 0

#5 Tarik

Tarik

    GMC Member

  • GMC Member
  • 2469 posts
  • Version:GM:Studio

Posted 02 December 2009 - 01:59 PM

Arrays, for loops, scripts and global variables overlooked? Maybe you meant to use the opposite word, they are probably among the most used and often part of the elementary functionality of most GM projects. In addition, much of the concepts you mentioned are universal, not exclusive to GM, and are also universally frequently used.

Overlooked and underused? That's simply false, no discussion required. Nice tutorial either way though, a good introduction to some of the most frequently used features of GM!
  • 0

#6 Lithium

Lithium

    Spitfire Member

  • New Member
  • 1474 posts
  • Version:Unknown

Posted 02 December 2009 - 02:36 PM

You might want to add constants to the list, they're simple to use and make game making a lot easier, especially when using arrays.
  • 0

#7 collipop

collipop

    GMC Member

  • New Member
  • 16 posts

Posted 02 December 2009 - 05:26 PM

Nice job, could come in very usefull.
  • 0

#8 mastersem

mastersem

    GMC Member

  • New Member
  • 236 posts

Posted 02 December 2009 - 05:31 PM

Small mistake here:
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]); // <--- here, you forgot the [i] part :P.
/* 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)]
*/
}
As the // comment said, you forgot [i] after item in the draw_text function :D.

for the rest it's well written, and hope people will use this :D
  • 0

#9 Kira Games

Kira Games

    GMC Member

  • GMC Member
  • 134 posts

Posted 02 December 2009 - 08:56 PM

I guess I meant features that don't have many tutorials. In fact, I had to look through about 10 tutorials to explain what I did for 2D arrays.

I wrote this in hopes to cover holes in other tutorials that touch on these things, but don't really go into them.
  • 0

#10 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 15 December 2009 - 06:47 AM

You know, the manual covers 2D arrays.

two indices with a comma between them for 2-dimensional arrays


  • 0

#11 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 16785 posts
  • Version:GM:Studio

Posted 15 December 2009 - 09:53 AM

3D arrays are just a mix of the two.


This is false... GM does not support 3D arrays, and they are certainly not a mix of 1 and 2D arrays... Apart from that, this is a well written tutorial and explains some of the fundamentals of GM (and programming languages in general) rather well.
  • 0

#12 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 15 December 2009 - 10:23 AM

3D arrays are just a mix of the two.


This is false... GM does not support 3D arrays, and they are certainly not a mix of 1 and 2D arrays... Apart from that, this is a well written tutorial and explains some of the fundamentals of GM (and programming languages in general) rather well.

Not true actually. A 3D array example is:
array1[0, array2[0, 0]]
Clunky but it works. It is rather misleading to talk about 3D arrays in GM though because you have to kludge it. The author should probably take that out.

Edited by PlasticineGuy, 15 December 2009 - 10:25 AM.

  • 0

#13 Petey_Pii

Petey_Pii

    GMC Member

  • New Member
  • 769 posts

Posted 15 December 2009 - 09:47 PM

Not true actually. A 3D array example is:

array1[0, array2[0, 0]]
Clunky but it works. It is rather misleading to talk about 3D arrays in GM though because you have to kludge it. The author should probably take that out.



that doesnt work... it just uses the value in one 2d array as the second indice for another array
  • 0

#14 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 15 December 2009 - 11:49 PM

It does work, it's just not really a smooth example. You will have to preset it of course:
var i, ii;
for(i = 0; i < 32000; i += 1) {
	for(ii = 0; ii < 32000, ii += 1) {
		array2[i, ii] = (i + 1) * ii;
	}
}

  • 0

#15 icicle.flame

icicle.flame

    CyntaxGames

  • New Member
  • 283 posts

Posted 16 December 2009 - 06:10 PM

Nice Tut but a couple of things...
  • The link for the Part2 of the Arrays(the one that selects) is still the first download link
  • You should think about fixing the scp_gs_draw so that it uses the array variables instead of strings
  • It leaves it too open, you say that this is just the beginning of what you can do but you don't explain what you can do if you get good.
  • ( Posted Image żDid that make sense? Posted Image )
Anyway, nice job, there needs to be some good tuts for newB's
  • 0

#16 Ussyless

Ussyless

    Objective

  • GMC Member
  • 957 posts
  • Version:Unknown

Posted 17 December 2009 - 08:27 AM

what makes you think these features are overlooked? i use them all the time

if its explained in the first post, i probably didnt get up to it

Edited by Ussyless, 17 December 2009 - 08:33 AM.

  • 0

#17 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 17 December 2009 - 09:29 AM

I guess I meant features that don't have many tutorials. In fact, I had to look through about 10 tutorials to explain what I did for 2D arrays.

I wrote this in hopes to cover holes in other tutorials that touch on these things, but don't really go into them.


  • 0

#18 Ussyless

Ussyless

    Objective

  • GMC Member
  • 957 posts
  • Version:Unknown

Posted 17 December 2009 - 10:35 AM

these funcions hardly need tutorials, they are easy enough to pick up anyway
perhaps thats just my personal experience though

Edited by Ussyless, 17 December 2009 - 10:36 AM.

  • 0

#19 True Valhalla

True Valhalla

    ಠ_ಠ

  • Retired Staff
  • 4879 posts
  • Version:GM:Studio

Posted 17 December 2009 - 10:50 AM

Wouldn't say overlooked, but definitely a useful tutorial for beginners. It took me a long time to figure out I could use global variables (self taught! No GMC!). Well written, good examples.

Well done.

-Tv
  • 0

#20 Pesmerga

Pesmerga

    GMC Member

  • New Member
  • 152 posts

Posted 05 January 2010 - 04:49 AM

Well I'm also self taught. To me, a beginner is someone who uses drag n drop and doesn't understand GML very well. So I consider myself an intermediate user. In real life, I'm a professional game level designer, but the programming thing is still new to me. And I must say I found this tutorial very helpful in many ways.

I learned how to use loops and arrays with game maker wiki, but the examples were not clear and I wasn't sure how to use them and what for. I heard about 2D arrays also but again I didn't really understand their usefulness. This explains it very well so I'm glad I took the time to read this.

There are a lot of things I already knew, but it certainly helped me understand how things work better. Good job. :whistle:
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users