Nathan’s Game Dev Blog Part 5 – Crappy Plumber 0.9

Herein lies the chronicle of my attempts to learn how to make a game. My goals: Provide a place to record my experiences making my first “shippable” game, share knowledge, and to provide motivation. Please comment and share if you like what I have written ~Nathan

The Final Push

Let’s take inventory, shall we?

  • DONE – Add a jumping sound
  • DONE – Add a score
  • DONE – Add a High Score
  • DONE – Add a death animation and sound
  • DONE – Add a game over screen
  • DONE – Change the animation speed when the player jump/flaps
  • DONE – Add background music
  • NOT DONE – Add an intro screen

There’s a lot to cover here, but I’ll touch on each one briefly.  Some were more difficult than I expected, but most challenges were due to inexperience, ie not using functions in the correct Event type, or using deprecated functions.  One challenge that I’ll have to overcome will be using case statements.  I didn’t add an intro screen (hence the 0.9 version instead of 1.0) because a lot of what I wanted to learn through the intro screen came when I added the game over screen.  At the end, I’ll cover some of the concepts and processes that were new to me here, and how I met those challenges.

Add A Jumping Sound

if(is_dead !=1)
{
    if(keyJump)
    {
        if(preGame == 1)
        {
            vsp = 0;
        }
        else
        {
            vsp = -7;
            audio_play_sound(snd_jump,1,false);
        }
    }
}

Not much has changed here. Making a sound play in Game Maker is only a matter of adding the sound to the project, then using a function to call that sound.  The documentation is very robust, so using new functions has so far been easy.  You can see from the code that during the obj_player Step Event, I just added a single line of code in the case that the jump action is taken. The most difficult part of this section was that I originally googled and received old information, so I kept trying to use a deprecated function, which did nothing.  Game Maker did not give me any error messages which would have prevented probably 30 minutes of churn, but oh well, lesson learned.  In the future, consult the Help documentation in addition to Googling something.

Add Background Music

audio_play_sound(bgm_swim,0,true);

This was probably the easiest thing to implement. Once I had my issues with legacy functions worked out, I just added this one line of code to the Creation Code of the room rm_main, and the music would begin when the room did. Very straightforward.

Add A Score & High Score

This was the most complicated part of the process. Adding a score was relatively easy; it involved a draw event to add a font and update the score. Adding a High Score was more complex. It involved creating a file, writing to the file, then reading from the file, to keep variable data between game resets. The benefit is that this also maintains the high score even if you close the application entirely. This was the most difficult, and most gratifying update to add.  I started by creating a new object, obj_score.  This object was responsible for holding the scr and hiscr variables, and tracking whether a point was tallied for getting past a pipe.  It also handled creating, saving, reading, and deleting the hiscore.txt file that stores the high score.  There is a lot of code, so I’ll post a picture of all the code for each event.

Click to see all code
Click to see all code
if(scored != 1)
{
    if(x < 120)
      {
         obj_score.scr += 1;
         if(obj_score.scr > obj_score.hiscr)
         {
             obj_score.hiscr += 1;
         }
         scored = 1;
    }
}

In addition, I added some Step Event code to obj_pipe (to the left).  Since Mario never moves horizontally, I can just watch the pipes, and if a pipe reaches a certain X value, then the score is updated.  This code adds the score, and checks to see if the object has already been tallied (since, as a Step Event, this will happen every frame of the game, instead of just once when the pipe is passed.  The code also updates the hiscr variable, which in gameplay will show the High Score updating along with the player’s score, if the player beats the High Score,  this was a small but satisfying reward for the player that I think really added to the desire to beat the High Score.

Add A Death Animation And Sound

if(is_dead == 1)
{
    draw_sprite_ext(spr_die,0,x+16,y+16,1.5,1.5,0,-1,1);
    ...
}

in the obj_player draw event, I added an IF statement checking when Mario was dead. If he was (which was a simple declaration when a collision occurs), then the first thing I did was draw the sprite. I was having trouble figuring out how to get the animation to only be the first 4 sub-images of spr_mario, so I wound up cheating and adding a separate spr_die sprite, which is brought up with this line of code. most of the variables deal with re-sizing the sprite (something I never mentioned I had to do).

Add A Game Over Screen

if(is_dead == 1)
{
    draw_sprite_ext(spr_die,0,x+16,y+16,1.5,1.5,0,-1,1);
    draw_set_font(fnt_normal);
    draw_set_halign(fa_center);
    draw_set_color(c_black);
    draw_text(360+2,room_height/2+2,"PRESS 'r' TO RESTART");
    draw_set_color(c_white);
    draw_text(360,room_height/2,"PRESS 'r' TO RESTART");
}
else
{
draw_self();
draw_set_font(fnt_normal);
}

Here is the rest of the code I referenced in the previous section. I got lazy and put this in the Draw Event for obj_mario, even though it isn’t strictly related to obj_mario.  You can see that this just formats the font to the way I want it, and makes it appear if Mario’s state is “is_dead = 1”. It’s worth noting that in order to set a font, as I did, you need to add the font to the fonts section of the resources in Game Maker.  I had trouble with this text not displaying, which took me a good 30 minutes of experimenting to figure out, but it turned out the font I was using did not have lower case characters, so I just had to type everything in caps.  Another lesson learned.

Change The Animation Speed When The Player Jump/Flaps

I tried to use the case functionality to get this to work, but ultimately fell back onto IF…THEN…ELSE statements. I’m going to leave the code out since it is sloppy, but essentially I tied Mario’s swimming animations speed (image_speed) to his vsp, which at the beginning of a jump is -7, and comes down to 0 before going positive again. The IF…THEN simply checked the VSP, and if it was below a certain value, the image_speed was updated to animate more or less quickly.

Add A Game Start Screen

This would have been key if I planned on releasing this game for play. My plan was to have a title, with Mario flapping at a set height, uncontrollable. The player would hit the spacebar, and receive an image or text saying “press spacebar to swim/jump/flap”, and wait for another spacebar press before releasing control to the player. I skipped this for two reasons.

First, I already completed the “draw something on screen” and “press a key to make a change” portions with the game over text and ability to restart the game (seen above). Second, doing this would mean creating new art or fonts to generate this image, and that was not the goal of this exercise. So I decided this section was unnecessary.

The Final Word… ?

This concludes my work on Crappy Plumber 0.9.  Because I wanted to jump right into the code, it was important for me to let other things fall to the side so I could focus on the code and learning.  This mean swiping existing graphics and sound so I wouldn’t have to think about those things while I was learning.

However, this also meant things like version control, pre-planning, prioritizing, bug tracking, defining features, a road map, release schedule, or a GDD (game design document) also fell to the side.

I’ve already begun thinking about my next game, a much more ambitious effort.  I will write a post-mortem on Crappy Plumber 1.0, in which I will talk about what went right, what went wrong, and what I will take with me into the next game.  I suspect this is the last code you will see in one of these articles for a few weeks, but I will continue to look for and share information that informs and guides me as I plan my next game.

On Thursday I will publish the first of these articles, a brief look at The Binding of Isaac, and its impact on my thought process.

Say Something

This site uses Akismet to reduce spam. Learn how your comment data is processed.