Game development is an iterative process where elements are added in when they are needed and often reworked several times as features are implemented and feedback from users changes the direction of the project. Building a game in this fashion saves time because it allows us to get things done quickly, see the results, and adapt as we go. In the last chapter we were focused on functionality of the basic gameplay. We built a simple HUD that allowed us to spawn each piece of equipment with a click. However, we did not limit what equipment the player had access to, nor did it have the ability to restart the level or show a countdown timer displaying how much time was remaining to clear the Zone. We will need to fix all of this, plus we should allow the player to go to the Shop in case their supplies are running low. All of this can be done as follows:
scr_Global_Gameplay
, and declare the necessary global variables:globalvar isGameActive, isTimerStarted; isGameActive = true; isTimerStarted = false;
Here we initialize two variables that we will need to improve the functionality of the game. The variable isGameActive
will be set to true
at the start of each level to commence gameplay. It will also afford us the ability to display information at the end of the level while preventing the player from using the Menu. The isTimerStarted
variable will be used for the countdown to clear the Zones.
scr_Global_GameStart
and call this the script.scr_Menu_Create
and add the following code:timer = 10; isTimerStarted = false; menuItem_Zone = 32; menuItems_Y = 440; restartX = 468; shopX = 564; tempCost = 0; tempScore = 0; startEquip = ds_grid_create(3, 4); ds_grid_copy(startEquip, equip);
The first variable is the amount of time the player will have for a countdown. Here we are going to give ten seconds for the Zone to be cleared. We then set the vertical location of the menu to be near the bottom of the screen. The next two variables are for the horizontal location of the Restart and Shop buttons. We need some temporary variables for holding the value of the equipment used and how much the player earns in the level as we don't want to change the global score unless the player wins the level. Finally, we create another Grid and copy the data from the equip
Grid so that if the level is restarted we still have the original settings.
if (ds_list_size(inventory) == 0) { room_goto(Shop); }
We check the size of the inventory and if it contains nothing we go to the Shop.
scr_Menu_Equipment
, for which we will need to accept some parameters:slot = argument0; item = argument1; if (slot == 0) { myX = 40; } if (slot == 1) { myX = 104; } if (slot == 2) { myX = 168; }
We start by declaring two variables for the two arguments that must be supplied when calling this script. Arguments are just variables that pass information from a script or function when it is called. Here we will have a slot placement on the Menu and a declaration of what item is to be displayed in the slot. Since we have a predetermined amount of slots on our Menu to be three, we can check which slot is being passed and apply the appropriate horizontal offset.
draw_sprite(ds_grid_get(startEquip, item, SPRITE), 0, myX, menuItems_Y); if (!isActive) { if (win_Y > menuItems_Y - menuItem_Zone && win_Y < menuItems_Y + menuItem_Zone) { if (win_X > myX - menuItem_Zone && win_X < myX + menuItem_Zone) { draw_sprite(ds_grid_get(startEquip, item, SPRITE), 1, myX, menuItems_Y); if (mouse_check_button_pressed(mb_left) && ds_grid_get(startEquip, item, AMOUNT) > 0) { instance_create(myX, menuItems_Y, ds_grid_get(startEquip, item, OBJECT)); ds_grid_add(startEquip, item, AMOUNT, -1); tempCost += ds_grid_get(startEquip, item, COST); isActive = true; } } } }
Previously we had code similar to this for each piece of equipment. Now that we have the data structure, we can use the information to create all of the equipment dynamically. We start by drawing the sprite that is pulled from the local startEquip
Grid. We then check to see if the Menu is active due to the player trying to place an item. We check for the mouse location on screen and see if it is hovering above the button and change to the appropriate frame of animation. If the button is clicked, we create the selected item, subtract one unit of the item from the Grid, add the value of the item to how much the player has spent, and make the Menu active.
draw_set_color(c_black); draw_set_halign(fa_center); draw_set_font(fnt_Small); draw_text(myX + 20, menuY + 14, ds_grid_get(startEquip, item, AMOUNT));
All we are doing here is setting the color, horizontal alignment of the text, and the font. We then draw the amount of units for each item in the lower right-hand corner as we did in the Shop.
scr_Menu_DrawGUI
and remove all the old clunky code. Delete all the code except for the very first line that draws the menu background. Once it has been removed, add the following code to draw the Menu:if (isGameActive) { Win_X = window_mouse_get_x(); Win_Y = window_mouse_get_y(); for (i = 0; i < ds_list_size(inventory); i++) { scr_Menu_Equipment(i, ds_list_find_value(inventory, i)); } } draw_set_font(-1);
We start by checking whether the global variable isGameActive
is true or not. If it is true, we get the screen location of the mouse, so we have the proper information to place the menu correctly. We then run a loop for as many objects as the player has in the inventory, which will then execute the menu equipment script to draw all the buttons. At the very end of the script we once again set the font back to its default.
spr_Button_Restart
, and with Remove Background turned off, load Chapter 7/Sprites/Button_Restart.gif
. Center the Origin and click on OK.scr_Menu_Button_Restart
, and write the following code:draw_sprite(spr_Button_Restart, 0, restartX, menuItems_Y); if (win_Y > menuItems_Y - menuItem_Zone && win_Y < menuItems_Y + menuItem_Zone) { if (win_X > restartX - menuItem_Zone && win_X < restartX + menuItem_Zone) { draw_sprite(spr_Button_Restart, 1, restartX, menuItems_Y); if (mouse_check_button_pressed(mb_left)) { room_restart(); } } }
Just as we did with the Equipment buttons, we start by drawing the button in its non-hovered state. We then check if the mouse is hovering over the button, and if it is, we change the animation to the hover state. If the button is clicked, we restart the room.
scr_Menu_DrawGUI
and call this script after the loop that creates the buttons for the equipment.scr_Menu_Button_Shop
, with code similar to all the other menu buttons:draw_sprite(spr_Button_Shop, 0, shopX, menuItems_Y); if (win_Y > menuItems_Y - menuItem_Zone && win_Y < menuItems_Y + menuItem_Zone) { if (win_X > shopX - menuItem_Zone*2 && win_X < shopX + menuItem_Zone*2) { draw_sprite(spr_Button_Shop, 1, shopX, menuItems_Y); if (mouse_check_button_pressed(mb_left)) { room_goto(Shop); } } }
Same as before, we draw the sprite and then check whether the mouse is hovering or not, making sure that we change the width to the larger size of this sprite. If the button is clicked, we go to the Shop.
scr_Menu_DrawGUI
and call this script immediately after the Restart button.scr_Menu_Clock
:draw_set_color(yellow); if (isTimerStarted) { draw_set_font(fnt_Small); draw_text(320, 416,"COUNTDOWN"); draw_set_font(fnt_Large); draw_text(320, 436, timer); } else { draw_set_font(fnt_Small); draw_text(320,416,"PRESS SPACE TO"); draw_set_font(fnt_Large); draw_text(320,436,"DESTROY") }
The background is black, so we will use the yellow color we created for all the text. If the global variable isTimerStarted
is true, we draw the word "COUNTDOWN"
in small letters and the amount of time remaining in a large font underneath it. If isTimerStarted
is false, we then draw the text in a similar manner to indicate to the player what they are supposed to do.
scr_Menu_DrawGUI
and call this script after the Shop button call. The completed script should look like the following code:draw_sprite(spr_Menu_BG, 0, 0, 400); if (isGameActive) { Win_X = window_mouse_get_x(); Win_Y = window_mouse_get_y(); for (i = 0; i < ds_list_size(inventory); i++) { scr_Menu_Equipment(i, ds_list_find_value(inventory, i)); } scr_Menu_Button_Restart(); scr_Menu_Button_Shop(); scr_Menu_Clock(); } draw_set_font(-1);
scr_Overlord_KeyPress
. Add the following code:if (!isTimerStarted) { obj_Menu.alarm[0] = room_speed; isTimerStarted = true; }
We check the isTimerStarted
variable to see if it has been activated already or not as we only want it to happen once. If the timer has not started, it will turn on an alarm in the Menu in one second.
obj_Menu
and add an Alarm | Alarm 0 event with a new Script, scr_Menu_Alarm0
, attached.if (timer > 0) { timer -= 1; alarm[0] = room_speed; } else { obj_Overlord.alarm[0] = 1; }
The Menu has a timer initialized for ten seconds and in this alarm we check to see if there is still time remaining. If there is, we reduce the time by one and reset the alarm for another second. This will repeat until time expires, in which case we tell the Overlord to run the victory condition alarm immediately.
scr_Overlord_Step
and remove the line of code that sets the alarm.18.224.56.29