Posted by: Raiun | August 14, 2012

Short Game Project – Nibbles Part 1

Recently, I decided to renew my interest in game design and creation. I haven’t worked on a serious programming project outside of school in quite some time, so I wanted to start off with something simple that wouldn’t take me a long time to complete and would help get me back into a programming mindset.

Back in my first year of taking computer science at university, one of the assignments was to build a game called “Nibbles” using a command prompt window and ASCII characters. At the time, my professor gave us students a large portion of the code to use, because the assignment was less about making the game, and more about learning the ability to read and use the code that he gave us.

I decided to re-make Nibbles from scratch, because it was a fairly straightforward game, wouldn’t take me a ton of time, and would give me a complete, working game at the end.

Nibbles

Not my best score

Chances are you have played a game like Nibbles, called Snake. The main difference is that Nibbles has you collect numbers between 1 and 9 instead of apples. Each time the player moves a square, the numbers all decrease by 1, and disappear when they reach zero.

The Nibbles that I made for my class assignment (and re-created recently) is a slight variation on the style. My Nibbles game does not increase the length of the player’s “tail” when you collect tokens. Instead, the player has a limited number of moves and when you collect tokens your number of moves left increases by the number displayed on the token. Your score also increases by that much.

These changes make it into a more strategic style game where the player has to think and react quickly. The board is 10X10, so if a 9 spawns all the way across the board, there is no way to reach it before it disappears. If an 8 appears six squares away, you will get 2 points and 2 extra moves for it, but if a 6 appears three squares away you will get 3 points and 3 extra moves for it. The game doesn’t wait for you to make a decision, so quick thinking is a must.

First Steps

I decided that building the game the exact same way I did it for my class was not going to be very productive. Using a command prompt made sense at the time because we were working in a really low-tech, old style UNIX system that had very little support for GUIs. I decided to modernize this using a more modern graphics setup and windowing system. I wanted to make the project in C++ since that is the language I’m most comfortable with, so I decided to go with SDL. Having settled on a graphics library and coding language, I set about making the game.

The first couple of decisions that I had to make were very basic. How big did I want the game board to be? How big did the window have to be to accommodate that, and still have room for things like a score counter, and the moves left display? How big should each square on the board be, and as a result, how many squares could I fit on the board? I eventually decided to keep it simple. I went with a 640X480 window, with a 10X10 game board of squares that are 40X40. This ends up making it so all of my numbers are nice and clean and consistent.

Nice round numbers

When coming up with the numbers for something like this, it is kind of important to make the numbers work out nicely. Notice how I ended up with a border of 40px on three sides of the game board? That wasn’t by accident. Since I need to check those values when I move the player, it is much easier to calculate where the border is if there are nice, even numbers. It’s kind of like buying furniture. If you measure the space you have properly, you can find a couch that fits, but if you just go buy a couch you will more than likely end up with one that is too small or too big, and it looks ridiculous.

The Player

Now that I have my dimensions set up for the board, the next most logical thing to add to the game is the player. The player in this game is fairly straightforward, it only really needs to know what its X location is, what its Y location is, and what direction it is facing. Oh, and what it looks like, that’s important to. As you might have noticed earlier…

The player looks like this

You can’t tell just by looking at it, but that image is exactly 160px wide, 40px high, and each of the arrows are smack in the center of a 40X40 block. That’s because once that picture is loaded in the game’s code, I can display any piece of it I like, from a single pixel, to a 40X40 block, or the entire thing. By making a simple construct called an enumerated type (programmers should be familiar with this idea, it’s a useful tool from time to time), I can quickly and easily assign each direction to a number.

In this case I would say Up = 0, Right = 1, Down = 2, Left =3. Then when I go to display the player, I simply look up which direction the player is facing, and tell the program to draw the piece of the above image that has X = Direction * 40, Y = 0, and make it 40X40. For those of you who are less mathematically inclined, you can pretend it’s magic, but I promise you it works.

Now that we know which way the player is facing, and how to draw the appropriate piece of the image to reflect that, we need to know exactly WHERE to place the player on the game board. Again, how I’ve laid out the board and window makes this fairly easy. I could store the player’s X and Y locations as absolute values of the window, but that seems like it’s a little unnecessary. I have a 10X10 game board, what I would really like to do is store the player’s X and Y as a number between 1 and 10, to indicate which square the player is in, rather than the pixel coordinates in the window.

As a brief aside, I just want to point out an odd quirk with how computers display graphics. In the most common X,Y coordinate system that everyone learns in high school math class, Y is zero at the bottom, and increases as you move upwards. In computers, Y is zero at the TOP of the screen and increases as you move DOWNWARDS. So when you want to draw an object, you want to know the top left corner’s X,Y coordinates, the object’s width, and it’s height.

Basically what I am trying to do is treat the game board as a grid like so:

X values increase across, Y values increase down.

Now hold on a second. Didn’t I say I wanted to use X and Y values from 1 to 10? Well… I lied. Realistically, almost everything in a programming paradigm starts at 0, not 1. When you want a spread of 10 numbers, you almost always use 0-9, not 1-10, and it works a lot more cleanly. Consider:

Say I store the values of the left and top of the game board as the variables boardLeft (= 200) and boardTop (= 40), and I make a variable that I’m going to call cellOffset (=40, for both the width and height of the cells). Then my formula for finding the left and top of the player’s location using the player’s X and Y is really simple:

playerLeft = boardLeft + playerX * cellOffset, and

playerTop = boardTop + playerY * cellOffset.

The fact is when the player is in the top row of cells, we want playerTop = boardTop. The only way to do that is if playerY = 0 when the player is in the top row of cells. Similarly for the left column, playerLeft must equal boardLeft, so playerX must equal zero.

If I wanted to use values of 1 to 10 instead, I would use something like

playerLeft = boardLeft + (playerX-1) * cellOffset.

This isn’t a huge difference, but it’s easy to overlook and cause errors, and it introduces a weird -1 magic number that is just sort of there. If I look at that code in three years I won’t understand immediately why that -1 needs to be there.

So, at this point we just link some keyboard events (using SDL) to change the player’s direction when the key is pressed, and a timer that updates the player’s X or Y location depending on which direction they are facing at each interval, and suddenly we have a player moving around a board.

We can add a check to make sure the player never moves if moving would make their X or Y values lower than 0 or higher than 9, which will ensure they never travel off the board. We’re basically half done already!

Next time I will write about the tokens you are supposed to collect, how to place them and collect them as the player, and also how we are going to tackle displaying the score and moves left counters.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: