by Ben Tyers
"ham"
4
"tomato"
You can sort the list:
ds_list_sort(example_list, true);
Where true will be ascending or false for descending. Strings are sorted alphabetically, lowest to highest for values.
This would then look like:
Index
value
0
"bacon"
1
"cheese"
2
"ham"
3
"mushroom"
4
"tomato"
You can remove a value:
ds_list_delete(example_list, 2);
Would remove the value at position 3 (index 2). The list will then look like:
Index
value
0
"bacon"
1
"cheese"
2
"mushroom"
3
"tomato"
You can insert a new value:
ds_list_insert(example_list, 1, "egg");
Would insert "egg" at position 2 (index 1). The list will then look like:
Index
value
0
"bacon"
1
"egg"
2
"cheese"
3
"mushroom"
4
"tomato"
After adding an element you may want to sort your list again.
Other things you may want to do, such as finding where in the list something appears:
position = ds_list_find_index(example_list, "cheese");
You can return a value to a variable, for example, the following, which would set word to "mushroom":
word=ds_list_find_value( example_list, 3);
You may need to find the size of a list, for example:
list_size=ds_list_size(example_list);
Which is great to use before you try and find a value at a position. You can shuffle (randomize) the values with:
ds_list_shuffle(example_list);
You can also use the accessor| that will allow you treat the ds_list as an array, for example, the following code would draw the value in index 3 at 100,100 on the screen:
draw_text(100,100,example_list[| 3]);
You can look up how to use the following in the manual:
ds_list_clear()
ds_list_empty()
ds_list_replace()
ds_list_copy()
ds_list_read()
ds_list_write()
When you have finished using a ds_list it's essential to destroy it. This helps prevent memory leaks. For example:
ds_list_destroy(example_list);
Basic Projects
• A) Create an inventory system for five objects. Allow keypress of X for user add an additional item, add it to the end of the list, then remove the top item. Draw this onscreen.
• B) Create a ds_list with five fruits. Player enters a fruit; if it matches a value in the ds_list, remove it, and tell player they made a correct guess. Player wins when all five fruits are guessed.
• C) Create a list with the names of students in the class. Sort them in ascending order and draw on the screen.
Advanced Project
• D) Add the names of all playing cards to a list. Shuffle them. Create four new ds_lists to represent player’s hands. Deal and remove the top card from the main list and deal to each of 4 players until each has five cards. Draw the values of each player's hand on the screen. Represent value and suit like: AS, 9H, 2D etc.
Appendix 23 Paths
Sometimes you want to have repeated object motion similar to how code is repeated with scripts. Paths are a useful way to make objects move in a set predefined motion (they can also be created dynamically through code). You can create paths using the built-in path editor or using GML. This section covers both.
You can create a new path by right clicking where shown in Figure A_23_1:
Figure A_23_1: Creating a new path
You can then create the path, and add points by clicking. Figure A_23_2 shows a path with four points added, with Closed and Smooth curve checked. sp means the speed.
Figure A_23_2: Showing an example path closed and smooth curve
You can edit the location of a path point by right-clicking, for example where shown in the Figure above.
If you were to create the same path using GML, you would use the code below:
path_example=path_add();
path_add_point(path_example,10,10,5);
path_add_point(path_example,100,10,5);
path_add_point(path_example,100,100,5);
path_add_point(path_example,10,100,5);
This creates the path and stores it in instance scope, not global scope as the path editor would have.
This would create a memory leak if the instance is destroyed later without calling path_delete().
The 5 at the end relates to the objects speed, though this is usually superseded when starting the path using code.
The above example could be used to make a sentry move around and protect a building.
You can then set whether the path is straight or curved: use 0 for straight, 1 for curved. So in this example we’ll use:
path_set_kind(path_example, 1);
Then set that the path is closed with:
path_set_closed(path_example, true);
Then start the path with:
path_start(path_example,50, path_action_restart, false);
path_example is the name of the path you created in the editor.
50 relates to the speed. path_action_restart tells what should happen when the last path location (end) is reached. The last part can be true or false. false places the path at the absolute position within the room (i.e., where you defined it in the path editor) and true positions it relative to the instance (i.e., the start position will be at the current instance x/y position).
There are several end path actions. They are:
Action name Path Action Value What It Does
path_action_stop
0
Stops at the end of the path
path_action_restart
1
Restarts path from first position
path_action_continue
2
Continues the current path
path_action_reverse
3
Reverses along current path
A neat feature that should be pointed out is that you can preview and change a path in the room editor, you can To use this feature, click as shown in Figure A_23_3. This would allow you to create a path around any instances that you have placed in the room.
Figure A_23_3: Setting a path layer in the room editor
Some other useful functions for dealing with paths include the following:
Note: These should not be used for paths currently being followed.
You can insert a new point in a path using the following, which would add a new point to the path path_example at position 3 with the X and Y at with a speed of 5:
path_insert_point(path_example,3, 50,50, 5);
You can change a point’s location, or speed using the following, which would change the path’s point at position 4 to an X and Y of 25 with a speed of 5:
path_change_point(path_example, 4, 25, 25, 5);
You can get the X or Y point of a path’s position using, for example, the following, which give the point of X location at position 2:
xpoint=path_get_point_x(path_example, 2);
You can set how precise a curved path is using 1(low) to 8(high):
path_set_precision(path_example, 4);
You can draw the path on screen, using for example (which must be within a draw event) which is very useful for debugging and testing:
draw_path(path_example,x,y,true);
Note: Set the drawing colour before using this code, to make the drawn path stand out.
direction holds the value in degrees of the direction
an instance is moving along a path.
Basic Projects
• A) Create a path for an object, and make it move contunously in a circle. 1 Point
• B) When the player left-clicks the mouse add the location as a new point on the path. Draw rhe path on screen.
Advanced Projects
• C) Make an object point in the direction of movement when following a path. Use project 23 B as a basis.
• D) Create a random path of 10 points, and save the points to an INI file.
Appendix 24 Scripts
Reusable code makes it easy to update program objects at the same time. Additionally, it makes it easier to organize and understand how your code works. GML scripts are useful in processing data, especially if you will be doing the same calculation again and again. This can include sending data to the script and then returning a value if required. If you are using the same code twice or more anywhere in your program, then you should consider using a script. This allows you to make just one change to update your code. Imagine a game that had over 100 enemy monsters with their own code; changing the code for each would take many hours, and be prone to errors. Using a script you could do this in a few minutes. It also allows for nice and tidy code. Scripts also allow you to easily share code between different game projects (which is must if you go on to a career in game making) – saving you potentially a lot of time.
Some examples for scripts:
Doing a math calculation and returning the answer, even if only used once; it means that your code is easier to read through and understand.
Setting a drawing or font type, formatting, and colour – makes code easier to read.
Playing sound effects and voices – you can send through which asset to play.
Sending through an object and returning the closest instance – great for complex weapon systems.
Drawing code that’s used multiple times – allowing you to quickly update it.
Recording bullet hits against multiple different objects.
Adding things to a DS list
Any other GML that’s used more than once.
You can create a new script by right clicking where shown in Figure A_24_1:
Figure A_24_1: Creating a new script
Name the script scr_example. Put in the following code:
/// @function scr_add(value,value,value)
/// @param {real} value
/// @param {real} value
/// @param {real} value
return argument0+argument1+argument2;
The comments in the above script perform an important function, as you type the script name when calling it, it will partially audio complete, reminding your what variables are needed.
Create an object obj_example.
In its Create Event put (so we don't try and draw a nonexistent variable):
answer=scr_example(12,18,7);
show_message(answer);
This will send the values 12, 18, and 7 to the script. The script will perform its GML and then return the value of total.
You can return strings, integers, real numbers, Boolean (true or false) and indexes of sounds, objects, rooms etc.
For example you can send through some objects: Create a script and name it scr_pos:
/// scr_pos(obj1, obj2)
//compares heights on y axis
if (instance_exists(argument0) && instance_exists(argument1))
{
if argument0.y < argument1.y
{
return true;
}
}
return false;
This will return true if obj_1 is higher up the room than obj_2, by checking the Y location of each, or false otherwise.
Note that when you call return you are exiting the script, and no further code will be run from it.
You do not have to return a value, as shown in the following example. Another example, this script will use views to keep two objects in view, and set the border size. It takes the X and Y locations of two objects and adjusts the view so that both can be seen at the same time.
You can send through positions of an instance or of the mouse, for example, without returning. The following would draw a laser between two endpoints.
scr_laser(start_x,start_y,end_x,end_y)
draw_set_color(make_color_rgb(irandom(255),irandom(255),irandom(255)));
draw_line_width(argument0, argument1, argument2, argument3, 5);
draw_set_color(c_lime);
draw_line(argument0+1,argument1+1,argument2,argument3); draw_line(argument0+1,argument1-1,argument2,argument3);
draw_line(argument0-1,argument1+1,argument2,argument3); draw_line(argument0-1,argument1-1,argument2,argument3);
draw_line(argument0,argument1,argument2,argument3); effect_create_above(ef_spark, argument2, argument3, 1, choose(c_red,c_orange));
An example of using this script, which would draw a laser effect from the object to the mouse position:
scr_laser(x, y, mouse_x, mouse_y);
Arguments can be accessed in two ways, for example:
name=argument0;
Or
name=argument[0];
Note: You cannot mix the two argument formats shown above.
Basic Projects
Create a script to do each of following, and display any result onscreen visually, as required, remembering to set up any text drawing.
• A) Find the average of five numerical values and round to the nearest whole number. 1 Point
• B) Work out if the player is within 200 pixels of an enemy object, and return true or false.
1 Point
• C) Draw given text, in white with a red shadow, at given position. 1 Point
• D) Create three different fonts. Create a script that allows you to quickly draw text, using font, alignment, colour, and position.
Advanced Projects
• E) Create a script that finds an average point between two objects, and draws a star effect at that position.
• F) Create a script that takes and calculates an angle between two objects and draws that direction as text as the angle were on a compass needle, that is, North or South West. The direction is that from the first object to the second. North is up.