Cookie Monster - Sprites in Processing



Download this program and run it in Processing.

What are Sprites?

We have made some simple video games using the normal drawing commands available in Processing.  That approach leads to complex, messy programs with lots of variables and lots of commands. 

A sprite is a moving character in a video game.  Each sprite is a package containing:
- variables with data about the position and speed of the Sprite
- methods that can do things like moving the Sprite, changing directions, hiding, etc.

By using a Sprite class, we gain several advantages :
- someone else can do all the really tricky coding
- we can hide all the complexity in the package, so our program only contains the control commands that we want to write

Cookie Monster Program

This program has 2 Sprites - the Cookie and the Player.  The user presses the arrow keys to move the Player around, to get it under the falling cookie and "eat" it.

Here is the code for the CookieMonster program.  It won't run by itself, because you also need the Sprite class (available in the .zip archive above).

Sprite player,cookie;

void setup()

  size(800, 600);
 
  textFont(createFont("Arial",36));
 
  frameRate(20);
  player = new Sprite("grinch",16);
  player.setSides(0,800,200,600,1);
  player.place(400,450);
 
  cookie = new Sprite("cookie.jpg");
  cookie.place(200,0);
  cookie.setSpeed(0,20);
  cookie.setSides(2);
}

int points = 0;

void draw()
{
  background(0);
 
  if(frameCount <= 100)
  {
    text("== Cookie Monster ==",50,50);
    text("Use the arrow keys to eat cookies",50,100);
    text("Starting automatically after 5 seconds",50,200); 
    return;
  } 
   
  fill(255);
  if(points >= 500)
  {  text("YOU WIN",350,300);
     text("Total time = " + frameCount / 20.0,350,350);
     noLoop();
  }
  else
  {  text(points,400,40);  }
 
  if(keyPressed)
  {
    if(keyCode==UP)
    { player.setSpeed(0,-5); }
   
    if(keyCode==DOWN)
    { player.setSpeed(0,5); }
   
    if(keyCode==LEFT)
    { player.setSpeed(-5,0); }
   
    if(keyCode==RIGHT)
    { player.setSpeed(5,0); }    
  }

  player.display();
  cookie.display(); 

  if(player.hit(cookie))
  {
    points = points + 100;
    cookie.place((int)random(700),0);
  }
 
}

The Cookie

The Cookie is quite simple.  It is a single image - Cookie.jpg - stored in the sketch folder.

In setup, the Cookie Sprite is created by these commands:

  cookie = new Sprite("cookie.jpg");  // load the image
  cookie.place(200,0);                // starting position
  cookie.setSpeed(0,20);              // speed of movement
  cookie.setSides(2);                 // side behavior = wrap around

The image is loaded, the cookie's starting position is set to (200,0), it's speed will be 0 across and 20 down, and it will wrap around when it reaches the bottom of the screen.

In the draw method, the Cookie only needs one single command:

  cookie.display();

That command does 2 things - draws the Cookie AND moves it.  We don't need a movement command like : cy = cy + 20; ,  because the Sprite code takes care of moving the Sprite - that's automatic.

The Player

The Player is considerably more complex than the Cookie.  The Player has 16 different images.  These are displayed one after another, creating an animation.

In setup, the Player Sprite is created by thise commands:

  player = new Sprite("grinch",16);
  player.setSides(0,800,200,600,1);
  player.place(400,450);

The new Sprite command load 16 images named : grinch0001.jpg, grinch0002.jpg, .... , grinch0015.jpg

The .setSides command says that the Player will STOP at the edges of the movement box, which extends from 0 to 800 across and from 200 to 600 up and down.

The .pl.ace command puts the Player at location (400,450). 

The Player will not move automatically, because there is no .setSpeed command.

Moving with keyPressed

The user presses the arrow keys to move the Player.  These commands take care of moving the Player around:

  if(keyPressed)
  {
    if(keyCode==UP)
    { player.setSpeed(0,-5); }
   
    if(keyCode==DOWN)
    { player.setSpeed(0,5); }
   
    if(keyCode==LEFT)
    { player.setSpeed(-5,0); }
   
    if(keyCode==RIGHT)
    { player.setSpeed(5,0); }    
  }

  player.display();

Notice that the .setSpeed commands take care of moving the Player, which moves automatically when .display executes.

Eating the Cookies

The .hit command checks whether two Sprites have collided - whether they are overlapping.  These commands check whether the Player and the Cookie are touching:

  if(player.hit(cookie))
  {
    points = points + 100;
    cookie.place((int)random(700),0);
  }

After the cookie is touched, it moves to a random x-position, at the top of the screen (y=0).

Notice that cookie.hit(player) would do exactly the same thing as player.hit(cookie) .

The Score

Every time the Player eats a Cookie, he scores 100 points - using the command:

    points = points + 100;

The following command displays the score at the top of the screen:

    text(points,400,40);

Winning the Game

The game ends when the Player has 500 points - after eating 5 Cookies.  Here are the commands to check the score:

  if(points >= 500)
  {  text("YOU WIN",350,300);
     text("Total time = " + frameCount / 20.0,350,350);
     noLoop();
  }

Frames

The Draw method executes automatically, over and over again - normally at 60 frames per second.  This program uses a slower speed of 20 frames per seconds, set by this command:

    frameRate(20);

At the end of the game, the total number of seconds played are calculated by this command:

    text("Total time = " + frameCount / 20.0  ,  350 , 350 );  

frameCount is a system variable that counts the number of frames that have been displayed.  Dividing by 20.0 changes frameCount into seconds.

Adding More Sprites

Adding a new Sprite (monster) is relatively straightforward, buy involves several steps.

Rules and Strategy

The rules and strategy for your game are implemented by various if.. commands that respond to events like one Sprite hitting another. 
The appearance of the game depends largely on the animations you create.

Creating Animations

It's possible to create an animation by using a graphics program, like GIMP, to draw a series of frames, where each frame is slightly different than the previous frame.  But drawing animations is quite time-consuming.  There are plenty of GIF Animations available on Google Images - search for "GIF Animation".

Find a good GIF animation and save a copy on your local hard-disk.  This is a single file containing several different frames.  You need to extract the frames into separate images.  You can do this at the following web-site:
   http://ezgif.com/split
At the web-site, upload your .GIF animation.  The web-site will automatically separate your animation into separate images that you can copy into the data folder of your program. Save the files into the DATA folder in your program.  Then rename them so the all look like this:

      picture0000.jpg     picture0001.jpg    picture0002.jpg ......

Or you might end up with .GIF or .PNG files, but those will work too.

Movement

Speed - The .setSpeed(x,y) command tells how far across and how far up and down the Sprite will move after each .display command.

Sides - When a Sprite reaches the edge of the screen, it behaves as specified in the .setSides command:
                .setSides(xmin, xMax, ymin, yMax, mode)

           The first 4 numbers tell the limits of movement.
           MODE tells what to do when the Sprite reaches an edge:
             0 = no action, keep moving
             1 = stop moving at the edge
             2 = wrap around to the oppoite edge
             3 = bounce in opposite direction

Practice

  1. Add another object using some small picture. Make a new Sprite and place it in the middle of the screen.
  2. Make your new Sprite move to the left (.setSpeed).
  3. Add another if(player.hit(yourNewSprite))
    to score points when you touch the new Sprite.
  4. Use .setSides to make your Sprite stop moving at the edge of the screen.
  5. Add another new Sprite.  It should move diagonally and bounce off the edges.
  6. Add another .hit command so that the bouncing Sprite is an enemy.
    If you touch it (or it hits you) then you lose 100 points.
  7. Add a new command so that whenever the enemy hits you, your player
    jumps back to the bottom of the screen.