So far there has been very little risk or reward in the game at all. We have added a Shop to the game where we can purchase items, but we are not yet able to earn any cash. We can use as much equipment as we want, as long as it is in our inventory, which means that there is no need for strategy. We need to add a Game Over Screen, if the player ever runs out of money or completes all the levels. We also need a Score Screen as currently the player has no idea how well they did so we will want to show that as well. It's time to add these features starting with rewarding the player points:
GameOver
and apply bg_MainMenu
as its background.obj_GameOver
, with no Sprite attached.scr_GameOver_Create
, with the following code and attach it to a Create event:gameOverText = "You ran out of money, better luck next time!"; alarm[0] = 5 * room_speed;
scr_GameOver_Alarm0
, and restart the game:game_restart();
scr_GameOver_Draw
, and attach it to a Draw | Draw event:draw_set_color(c_black); draw_set_halign(fa_center); draw_set_font(fnt_Large); draw_text(320, 280, "Game Over"); draw_set_font(fnt_Small); draw_text(320, 320, gameOverText); draw_set_font(-1);
GameOver
and place a single instance of obj_GameOver
somewhere in the room. We are now done with this and can close the room.obj_ScoreFloat
, to display the points rewarded as each Pillar or Debris is destroyed.scr_ScoreFloat_Create
, and initialize two variables:fadeOut = 0; alpha = 1;
We will have the score fade out over time, so we have a variable for triggering the fade out and one for the value of transparency which is currently set to full opacity.
scr_ScoreFloat_Draw
, to show the value on screen:y -= 1; fadeOut++; if (fadeOut > 60) { alpha -= 0.05;} if (alpha <= 0) { instance_destroy(); } draw_set_color(c_black); draw_set_font(fnt_Small); draw_set_alpha(alpha); draw_text(x, y, myValue); draw_set_alpha(1);
This object is not a part of the physics world, so we can manually move it vertically every frame. We increase the fadeOut
variable and once it hits 60, we start to decrease the alpha
variable by a small amount. Once alpha
has hit zero, we destroy the instance so that it doesn't take up any memory. After that we set the color, font, and transparency values and draw the text. The myValue
variable will be passed upon creation from the object that spawns it. Finally, we set the transparency back to full opacity; otherwise everything else in the entire room will fade out as well.
scr_Pillar_BreakApart
and insert the following code after the shatter sound is played but before the instance is destroyed:scoreFloat = instance_create(x, y, obj_ScoreFloat); scoreFloat.myValue = floor(phy_mass); obj_Menu.tempScore += scoreFloat.myValue;
When the Pillar breaks apart it will spawn an instance of obj_ScoreFloat
. We then set the displayed value to the rounded down amount of the object's total mass. Finally, we increase the Menu's tempScore
by the same amount.
scr_Pillar_Destroy
and insert the same code in the same place.spr_Screen_BG
and spr_Button_NextLevel
, both supplied in Chapter 7/Sprites/
. Make sure not to Remove Background and to Center the Origin for both.scr_Menu_Button_NextLevel
, with the functionality of this button:if (isVictory) { draw_sprite(spr_Button_NextLevel, 0, nextLevelX, menuItems_Y); if (win_Y > menuItems_Y - menuItem_Zone && win_Y < menuItems_Y + menuItem_Zone) { if (win_X > nextLevelX - menuItem_Zone && win_X < nextLevelX + menuItem_Zone) { draw_sprite(spr_Button_NextLevel, 1, nextLevelX, menuItems_Y); if (mouse_check_button_pressed(mb_left)) { for(i = 0; i < totalLevels; i++) { if (level[i, 0] == room) { level[i+1, 1] = false; room_goto( level[i+1, 0] ); } } } } } }
We only want the Next Level button to appear if the player successfully clears the Zones, so we check for that first. If the player has won the level, we draw the sprite and then check to see if the mouse is hovering over it. If the mouse is over the button and it is pressed, we run a quick loop through the level array to see what room we are currently in and unlock the next level. Finally we go to the room we just unlocked.
obj_ScoreScreen
, to display the Score Screen. Set the Depth to -100
so that it always draws on top of all other GUI elements.scr_ScoreScreen_Create
attached and initialize the following variables:isGameActive = false; obj_Menu.isActive = true; isVictory = scr_WinCondition(); screenX = 320; screenY = 200; menuItem_Zone = 32; menuItems_Y = 440; restartX = 200; shopX = 320; nextLevelX = 440;
We don't want the player to play during this time, so we turn off the isGameActive
variable and make the Menu active so that the Equipment buttons no longer function. Next we need to check if the player has been successful in order to know what to draw. The final seven variables are all for the placement of the various text and buttons we will be displaying.
scr_ScoreScreen_DrawGUI
and we will start by drawing all the text we need:draw_sprite(spr_Screen_BG, 0, screenX, screenY); draw_set_color(c_black); draw_set_halign(fa_center); draw_set_font(fnt_Large); draw_text(screenX, 60, room_get_name(room)); draw_text(screenX, 144, obj_Menu.tempScore); draw_text(screenX, 204, obj_Menu.tempCost); draw_text(screenX, 284, obj_Menu.tempScore - obj_Menu.tempCost); draw_set_font(fnt_Medium); draw_text(screenX, 120, "Damage Estimate"); draw_text(screenX, 180, "Equipment Cost"); draw_text(screenX, 260, "Total Profit"); draw_set_font(-1);
First we draw the background sprite. We then set the color, alignment, and font. We are using the largest font to draw the name of the room and the values for the amount of damage, the amount of equipment used, and the total profit. We then switch to the medium font to write the description of each value, placed above the number it corresponds to. We are done drawing text, so we set the font back to its default value.
Win_X = window_mouse_get_x(); Win_Y = window_mouse_get_y(); scr_Menu_Button_Restart(); scr_Menu_Button_Shop(); scr_Menu_Button_NextLevel();
Just as we did with the Menu, we get the coordinates of the mouse on screen and then execute the scripts for the three buttons.
scr_Overlord_Alarm0
and have it spawn an instance of obj_ScoreScreen
instead of the code it currently runs. Remove all the code and replace it with the following code:instance_create(0, 0, obj_ScoreScreen);
scr_ScoreCleanUp
:with (obj_Menu) { ds_grid_copy(equip, startEquip); ds_grid_destroy(startEquip); score += tempScore - tempCost; for ( i = 0; i < ds_grid_width(equip); i++) { e = ds_grid_get(equip, i, AMOUNT); if (e == 0) { inv = ds_list_find_index(inventory, i); ds_list_delete(inventory, inv); } } }
When this script is executed, it will go into the Menu and copy the remaining equipment over to the global equipment values and then delete the temporary grid from memory. Next we increase the global score based on what occurred during gameplay. We then run a loop through the inventory looking for whether the player has run out of any items. If they have, we remove it from the inventory altogether.
scr_Menu_Button_NextLevel
and replace the line of code where we switch rooms with the following:scr_ScoreCleanUp(); if (score < 0) { room_goto(GameOver); } else { room_goto( level[i+1, 0] ); }
scr_Menu_Button_Shop
and replace the line of code where we switch rooms with the following code:if (!isGameActive) { scr_ScoreCleanUp();} if (score < 0) { room_goto(GameOver); } else { room_goto(Shop); }
Now the score will be transferred only if gameplay has stopped. We also check the score here for the game over state to decide what room to go to when clicked.
18.117.138.178