Adding risk and reward to destruction

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:

  1. We will start with the Game Over screen. Create a new Room called GameOver and apply bg_MainMenu as its background.
  2. Create a new Object, obj_GameOver, with no Sprite attached.
  3. Upon creation we will create a variable that will contain the game over message and we will set an alarm for five seconds, which we will use to restart the game. Create a new Script, 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;
  4. Add an Alarm | Alarm 0 event and then attach a new Script, scr_GameOver_Alarm0, and restart the game:
    game_restart();
  5. All that we have left to do is to draw the win/lose statement. Create a new Script, 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);
  6. If it isn't still open, reopen GameOver and place a single instance of obj_GameOver somewhere in the room. We are now done with this and can close the room.
  7. The next thing we will create is a new Object, obj_ScoreFloat, to display the points rewarded as each Pillar or Debris is destroyed.
  8. Add a Create event with a new Script, 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.

  9. Next we need to add a Draw | Draw event with a new Script, 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.

  10. Now that we can display the score we need to spawn it and pass a value to it. Since we already know that each Pillar and Debris has a different mass, we can use that number to award points upon its destruction. Reopen 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.

  11. We need the Small Pillars and Debris to do the same, so open scr_Pillar_Destroy and insert the same code in the same place.
  12. Run the game and destroy the Pillars in the first level. As each piece breaks, a number will float up signifying the value that it is worth. The floating numbers should fade out after a few seconds and should look something like the following screenshot:
    Adding risk and reward to destruction
  13. All we need to do now is to make a Score Screen that sums up the damage and shows the total profit for the level. We will start by bringing in a few more sprites, 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.
  14. Let's create a new Script, 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.

  15. Now we are ready to create a new Object, obj_ScoreScreen, to display the Score Screen. Set the Depth to -100 so that it always draws on top of all other GUI elements.
  16. Add a Create event with a new Script, 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.

  17. Now to add a Draw | Draw GUI event with a new Script, 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.

  18. Now we just need to add the buttons into the script:
    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.

  19. In order to activate the Score Screen, we need to reopen 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);
  20. Run the game and finish the first level. After the timer has run out, the Score Screen appears displaying the damage, the cost, and the profit. The in-game menu has disappeared and has been replaced by three buttons for replaying the level, going to the Shop, or the next level. It should look like the following screenshot:
    Adding risk and reward to destruction
  21. There is one issue that we need to solve. While the screen says we have earned money, if we go to the Shop, there will be no cash available. This is because we haven't transferred the temporary values to the global values, which we will do in a new Script called 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.

  22. If the player goes to the next level, we should pay them immediately. We should also check the score to make sure that the player has money. If they run out of money, then it is game over, otherwise they can go to the next level. Reopen 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] );
    }
  23. If the player decides to go to the Shop, it becomes a bit trickier. The script we are calling is also used on the Menu, so we don't want it to change the data during gameplay. Reopen 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.

  24. Everything should work properly now, so run the game and check to make sure that the score doesn't change when you go to the shop during gameplay.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.138.178