CS 489.02 - Computers and Games - Spring 2009
Pick up the Peanuts


Loyola College > Department of Computer Science > Dr. James Glenn > CS 489.02 > Examples and Lecture Notes > Pick up the Peanuts


This applet uses Java 5 and so will not work without a recent version of the Java plugin.
Control your red player with the numeric keypad.

Code is also available in an archive.

PeanutsApplet.java

/*
<APPLET CODE="PeanutsApplet.class" WIDTH=600 HEIGHT=600></APPLET>
*/

import javax.swing.*;
import java.awt.*;

/**
 * An applet that displays a game.
 *
 * @author Jim Glenn
 * @version 0.1 from LiberationApplet of 1/8/2009
 */

public class PeanutsApplet extends JApplet
{
    public void init()
    {
	PeanutsModel model = new PeanutsModel();
	GameView view = new GameView(model);
	PeanutsControl control = new PeanutsControl(model);
	view.addKeyListener(control);

	getContentPane().setLayout(new BorderLayout());
	getContentPane().add(view, BorderLayout.CENTER);
    }
}

	

PeanutsControl.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * The controller for a game.  The controller handles the time and
 * the player's input.
 *
 * @author Jim Glenn
 * @version 0.1 1/20/2009 :)
 */

public class PeanutsControl extends GameControl
{
    /**
     * Creates a controller connected to the given game model.
     *
     * @param g a Pick Up The Peanuts game
     */

    public PeanutsControl(PeanutsModel m)
    {
	super(m);
    }

    private PeanutsModel getModel()
    {
	return (PeanutsModel)model;
    }

    public synchronized void keyPressed(KeyEvent e)
    {
	switch (e.getKeyCode())
	    {
	    case KeyEvent.VK_NUMPAD1:
		getModel().movePlayer(-1, 1);
		break;

	    case KeyEvent.VK_NUMPAD2:
		getModel().movePlayer(0, 1);
		break;

	    case KeyEvent.VK_NUMPAD3:
		getModel().movePlayer(1, 1);
		break;

	    case KeyEvent.VK_NUMPAD4:
		getModel().movePlayer(-1, 0);
		break;

	    case KeyEvent.VK_NUMPAD6:
		getModel().movePlayer(1, 0);
		break;

	    case KeyEvent.VK_NUMPAD7:
		getModel().movePlayer(-1, -1);
		break;

	    case KeyEvent.VK_NUMPAD8:
		getModel().movePlayer(0, -1);
		break;

	    case KeyEvent.VK_NUMPAD9:
		getModel().movePlayer(1, -1);
		break;
	    }
    }
}

PeanutsModel.java

/**
 * A game of Pick up the Peanuts.  Pick up the Peanuts has a player
 * and an elephant who race to pick up peanuts.
 *
 * @author Jim Glenn
 * @version 2K9 translated to Java
 * @version 1.0 1982 or so in Atari BASIC
 */

public class PeanutsModel extends GameModel
{
    /**
     * The objects in this game.  Distinguished objects (OK, all of them)
     * are kept separately from the list for easy access.
     */

    private Player player;
    private Elephant elephant;
    private Peanut peanut;

    /**
     * Creates a new Pick up the Peanut game with player and elephant
     * at their starting positions (left and right respectively)
     * and a randomly placed peanut.
     */

    public PeanutsModel()
    {
	// create player near middle of left edge
	player = new Player(0.1, 0.5);
	addSprite(player);

	// create elephant near middle of right edge

	elephant = new Elephant(0.9, 0.5);
	addSprite(elephant);

	// throw a peanut at a random location

	makePeanut();
    }

    /**
     * Returns the current peanut in this game.
     *
     * @return the peanut
     */

    public Peanut getPeanut()
    {
	return peanut;
    }

    /**
     * Forwards move events to the player.  The direction is given
     * as an x- and a y-component.
     *
     * @param dx -1, 0, or 1
     * @param dy -1, 0, or 1
     */

    public void movePlayer(int dx, int dy)
    {
	player.move(dx, dy);
    }

    /**
     * Places a new peanut randomly in this game.
     */

    private void makePeanut()
    {
	if (peanut != null)
	    {
		removeSprite(peanut);
	    }

	peanut = new Peanut(Math.random(), Math.random());
	addSprite(peanut);
    }

    /**
     * Handles collisions between the given objects.
     *
     * @param s1 a sprite
     * @param s2 a sprite that has collided with s1
     */

    protected void handleCollision(Sprite s1, Sprite s2)
    {
	if (s1 instanceof Peanut || s2 instanceof Peanut)
	    {
		// swap to make s1 the one that ate the peanut

		if (s1 instanceof Peanut)
		    {
			Sprite temp = s1;
			s1 = s2;
			s2 = temp;
		    }

		if (s1 instanceof Player)
		    {
			// player ate the peanut
		    }
		else
		    {
			// elephant ate the peanut
		    }

		// make a new peanut

		makePeanut();
	    }
	else
	    {
		// must be player/elephant

		player.trample();
	    }
    }
}

PeanutsWindow.java

import javax.swing.*;
import java.awt.*;

/**
 * A window that displays a game.
 *
 * @author Jim Glenn
 * @version 0.1 from LiberationApplet of 1/8/2009
 */

public class PeanutsWindow extends JFrame
{
    public PeanutsWindow()
    {
	super("Pick up the Peanuts 2K9");

	PeanutsModel model = new PeanutsModel();
	GameView view = new GameView(model);
	PeanutsControl control = new PeanutsControl(model);
	view.addKeyListener(control);

	getContentPane().setLayout(new BorderLayout());
	getContentPane().add(view, BorderLayout.CENTER);
    }

    
    public static void main(String[] args)
    {
	JFrame win = new PeanutsWindow();
	win.setSize(600, 600);
	win.setVisible(true);
	win.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
}

	

Peanut.java

import java.awt.Color;

/**
 * A peanut in Pick up the Peanuts.
 *
 * @author Jim Glenn
 * @version 0.1 1/20/2009
 */

public class Peanut extends Sprite
{
    /**
     * The size of a peanut.
     */

    public static final double DEFAULT_SIZE = 0.01;

    /**
     * Creates a new peanut at the given position.
     * The peanut will be red.
     *
     * @param initX an x-coordinate within the world this peanut will be in
     * @param initY a y-coordinate within the world this peanut will be in
     */

    public Peanut(double initX, double initY)
    {
	super(initX, initY, DEFAULT_SIZE, Color.ORANGE);
    }
}

Player.java

import java.awt.Color;

/**
 * A human player in Pick up the Peanuts.
 *
 * @author Jim Glenn
 * @version 0.1 1/21/2009
 */

public class Player extends Sprite
{
    /**
     * The size of the human player.
     */

    public static final double DEFAULT_SIZE = 0.025;

    /**
     * The amount of time, in seconds, that this player takes to recover
     * from being trampled.
     */

    private static final double RECOVERY_TIME = 0.5;

    /**
     * Constants for state.
     */

    private static final int STATE_TRAMPLED = 1;

    /**
     * The direction this player will go when it recovers from being trampled.
     */

    private int recoverDx;
    private int recoverDy;

    /**
     * Creates a new human player at the given position.
     * The player will be red.
     *
     * @param initX an x-coordinate within the world this playwe will be in
     * @param initY a y-coordinate within the world this Player will be in
     */

    public Player(double initX, double initY)
    {
	super(initX, initY, DEFAULT_SIZE, Color.RED);
    }

    /**
     * Returns the maximum speed of this player.
     *
     * @return the speed
     */

    public double getMaximumSpeed()
    {
	return 0.2;
    }

    /**
     * Changes the velocity of this player so that it is moving in
     * the given direction.  Its speed will be set to the maximum.
     *
     * @param dx -1, 0, or 1
     * @param dy -1, 0, or 1
     */

    public void move(int dx, int dy)
    {
	if (getState() != STATE_TRAMPLED)
	    {
		setVelocity(getMaximumSpeed() * dx, getMaximumSpeed() * dy);
	    }
	else
	    {
		recoverDx = dx;
		recoverDy = dy;
	    }
    }

    /**
     * Tramples this player.  This player will not be able to move until
     * it recovers.
     */

    public void trample()
    {
	if (getState() != STATE_TRAMPLED)
	    {
		setState(STATE_TRAMPLED);
		recoverDx = 0;
		recoverDy = 0;
	    }
    }

    /**
     * Updates this player.
     *
     * @param t the time since the last update
     * @param m the model this player belongs to
     */

    public void update(double t, GameModel m)
    {
	if (getState() == STATE_TRAMPLED)
	    {
		if (getStateTime() > RECOVERY_TIME)
		    {
			setState(STATE_NORMAL);
			setVelocity(recoverDx, recoverDy);
		    }
		else
		    {
			setVelocity(0, 0);
		    }
	    }
	
	super.update(t, m);

	// do wraparound

	if (x < getBoundingRadius() / 2)
	    {
		x = m.getWidth() - getBoundingRadius() / 2;
	    }
	else if (x + getBoundingRadius() / 2 > m.getWidth())
	    {
		x = getBoundingRadius() / 2;
	    }

	if (y < getBoundingRadius() / 2)
	    {
		y = m.getHeight() - getBoundingRadius() / 2;
	    }
	else if (y + getBoundingRadius() / 2 > m.getHeight())
	    {
		y = getBoundingRadius() / 2;
	    }
    }
}

Elephant.java

import java.awt.Color;
import java.awt.geom.*;

/**
 * A human player in Pick up the Peanuts.
 *
 * @author Jim Glenn
 * @version 0.1 1/21/2009
 */

public class Elephant extends Sprite
{
    /**
     * The size of an elephant.
     */

    public static final double DEFAULT_SIZE = 0.025;

    /**
     * Creates a new elephant at the given position.
     * The elephant will be gray.
     *
     * @param initX an x-coordinate within the world this elephant will be in
     * @param initY a y-coordinate within the world this elephant will be in
     */

    public Elephant(double initX, double initY)
    {
	super(initX, initY, DEFAULT_SIZE, Color.GRAY);
    }

    /**
     * Returns the maximum speed of this elephant.
     *
     * @return the speed
     */

    public double getMaximumSpeed()
    {
	return 0.2;
    }

    /**
     * Updates this elephant.
     *
     * @param t the time since the last update
     * @param m the model this player belongs to
     */

    public void update(double t, GameModel m)
    {
    }

    public GeneralPath getOutline()
    {
	double r = getBoundingRadius();

	double earTop = y - r * Math.cos(Math.PI / 4);
	double earXOff = r * Math.sin(Math.PI / 4);
	double earLeft = x - earXOff;
	double earRight = x + earXOff;

	double trunkY = y + r * Math.cos(Math.PI / 10);
	double trunkOff = r * Math.sin(Math.PI / 10);
	double trunkLeft = x - trunkOff;
	double trunkRight = x + trunkOff;

	// we should be able to do a little better than this very
	// crude rendering of an elephant's head

	GeneralPath outline = new GeneralPath();
	outline.moveTo((float)earLeft, (float)earTop);
	outline.lineTo((float)(earLeft + r / 4), (float)earTop);
	outline.lineTo((float)(earRight - r / 4), (float)earTop);
	outline.lineTo((float)earRight, (float)earTop);
	outline.lineTo((float)earRight, (float)(y + r / 8));
	outline.lineTo((float)(earRight - r / 4), (float)(y + r / 8));
	outline.lineTo((float)(earRight - r / 4), (float)(y + r / 2));
	outline.lineTo((float)trunkRight, (float)(y + r / 2));
	outline.lineTo((float)trunkRight, (float)trunkY);
	outline.lineTo((float)trunkLeft, (float)trunkY);
	outline.lineTo((float)trunkLeft, (float)(y + r / 2));
	outline.lineTo((float)(earLeft + r / 4), (float)(y + r / 2));
	outline.lineTo((float)(earLeft + r / 4), (float)(y + r / 8));
	outline.lineTo((float)earLeft, (float)(y + r / 8));
	outline.closePath();

	return outline;
    }

}
This code can also be downloaded from the files
PeanutsApplet.java, PeanutsControl.java, PeanutsModel.java, PeanutsWindow.java, Peanut.java, Player.java, and Elephant.java.