CS/ENGR 101: Gameboy Session
Fall 2006 – Snake Game Project (Days 7-9)
Due: Wednesday, November 29


Snake Game

The Snake Game is an old video game which has become a standard cellphone game. In this game, a snake moves around a screen and is controlled by the player using a joystick or arrow keys. The object of the game is to collect points by guiding the snake to eat apples (or other desirable objects) and to avoid running into walls and the snake body, which causes to game to end. In some versions, the snake is of fixed length. In other versions, the snake grows as the game is played. Below is a picture of a version that grows:




Gameboy Snake

For this project, you will write a program that will allow a user to play a simplified Snake Game on the Gameboy. Our version will have the following features:



To make this program easier to understand, we will break it up into several functions. We will use the ClearScreen function from previous exercises. Here are descriptions of the other functions.


PeekPixel

The first new function you will need is one to find out the color of a pixel. This is basically the opposite of ham_PutPixel, but for some reason the GBA library doesn't implement one, so we have to do it ourselves. The code for this function is below. (Don't worry about understanding how it works.)


/* returns the color of the pixel at (x, y)*/
int PeekPixel (int x, int y)
{
   return *(MEM_VRAM_PTR + 240 * y + x);
}


DisplayStartScreen

Another function we need is one to make the text splash screen. It requires that we change to text mode rather than graphics mode. In this mode, the screen is divided into characters rather than pixels. Since each character is 8x8 pixels, the screen has 30x20 characters. In this mode, only letters, digits, and (most of) the English text punctuation marks (e.g., '!', but not "*") will display and the letters are displayed capitalized (even when they are in lowercase in the output string). The code for this function is below.


void DisplayStartScreen ()
{
    ham_SetBgMode (0);  /* 0 is text mode */
    ham_InitText(0);    /* Required initialization */
    /* ham_DrawText arguments are (x,y) of where to 
       place text, and the text */
    ham_DrawText (5, 2, "Welcome to Snake");
    ham_DrawText (5, 4, "Press START to begin");
    while (!F_CTRLINPUT_START_PRESSED);  /* spin until START is pressed */
    ham_DeInitText();   /* Required deinitialization */
}


DisplayFinalScore

You will need to write a similar function DisplayFinalScore that has an argument that is the score to be displayed for the final score reporting text screen. This function also should wait for the player to press the A button to start a new game. Here is a skeleton of its function definition:


void DisplayFinalScore (int score)
{
    /* code for this function goes here
}


PlayGame

The final function we will write is PlayGame, which holds the main game code. We put the game code in a separate function from the main program code to make it easier to change between the text mode of the splash and score screens and the graphics mode of the game screen. This function will return the final score the player earned. Here is a skeleton of its function definition:


int PlayGame ()
{
    /* code for this function goes here */
}


The main idea of this program is that the snake will be growing continuously (whether or not the user presses a button). The arrow buttons will control the direction that the snake is growing. We will do this by encoding the direction as an integer. For example, we can use 0 for left, 1 for right, 2 for up, and 3 for down.


The program will determine if the snake has hit anything by finding out the color of the pixel it advances to, and testing to see if it is the background color. If the pixel is the background color, the space is free and the snake grows by coloring that pixel. If it is not the background color, then either it is a wall or the body of the snake itself. In this case, the game ends and reports the player's score. Here is an outline of what the PlayGame function should do:


  1. Declare all needed variables

  2. Set the background mode to 3

  3. Initialize x and y to be the coordinates of the pixel in the center of the screen

  4. Initialize score to 0 and direction to 0 (i.e., up will be the initial direction)

  5. Clear the screen to background color using the ClearScreen function.

  6. Draw a border around the edge of the screen in a different color By making the border a different color than the background, the edge of the screen becomes a wall, and the game will automatically stop when the snake hits the edge. This way, we will not need to check for the edge as was needed for the Etch-a-Sketch® project.

  7. In a while (TRUE) loop, do the following tests and actions

    1. Check if direction is 0 (left), if so update x so that (x, y) is now one pixel to the left

    2. Check if direction is 1 (right), if so update x so that (x, y) is now one pixel to the right

    3. Check if direction is 2 (up), if so update y so that (x, y) is now one pixel higher

    4. Check if direction is 3 (down), if so update y so that (x, y) is now one pixel lower

    5. Check if color at (x,y) is not the background color (using the PeekPixel function), if so do something to attract the player's attention like flashing the screen red and return the score (this will terminate the function and thus end the game)

    6. Color the pixel at coordinates (x, y) the snake color (since it is at a free pixel)

    7. Increment the score by 1 (since a pixel was added to the snake)

    8. Check if the Left button has been pressed, if so set direction to 0

    9. Check if the Right button has been pressed, if so set direction to 1

    10. Check if the Up button has been pressed, if so set direction to 2

    11. Check if the Down button has been pressed, if so set direction to 3

    12. Delay for some amount of time (otherwise, the snake will be drawn too rapidly to control)


Note that this outline is both similar to and different from the Etch-a-Sketch® project outline.


Main Program

The main program then is just a loop that alternates between the start splash screen, playing the game, and the final score screen as follows.


int main(void)
{
   int finalScore;  /* holds the final score from playing the game */
   ham_Init();

   while(TRUE)
   {
      DisplayStartScreen ();
      finalScore = PlayGame();
      DisplayFinalScore (finalScore);
   }

   return 0;
}


Logistics

Create a new VisualHAM project for this assignment. Recall that after launching VH, the steps for doing this are:


  1. Click on the File menu and choose New, then Project. This gives you the dialog box to create one.

  2. In the new project dialog box, select [C] Empty, type in a project name (for example, snake), and give a place on your network drive space for a location (this needs to be specified using a drive letter, for example, I:\cs101\snake assuming you have a folder named cs101 on your network drive).

  3. In the left panel, there is a tree representation of the project. The code you write goes in the main.c file. Double-clicking on the entry will bring up the file in the main edit window.


All of the function definitions need to go before the main program code.


Assignment

This assignment is worth 60 points. They will be awarded as follows:


Put your name in a comment at the beginning of your program file. Email your completed program (the main.c file, not the project file) as an attachment to the instructor (hwang@evansville.edu) no later than 4:30pm on Wednesday, November 29.

From Feed the Snake Game by Real Apex http://www.feedthesnake.com

11/17/06 4