Basic Cannon

<< Basic Pong | OtherProjectsTrailIndex | LizardSplat >>

This is a keyboard driven "Tower Defense" type game. You can see a working version here.

Complete the gameOverCheck method of class BasicCannon. It should be a void method that checks for four possible conditions:

  1. A win is when there are no targets left (Hint: targets.size() returns the number of targets )
  2. A loss due to lack of both ammo and powder
  3. A loss due to a lack of ammo only
  4. A loss due to lack of powder

When one of these conditions exist, the String field message should report:

  1. "You win with XXX cannonballs and YYY gunpowder left!"
  2. "Game Over-- out of cannonballs and gunpowder"
  3. "Game Over-- out of cannonballs"
  4. "Game Over-- out of gunpowder"

BasicCannon.java

package cannon;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;


import javax.swing.Timer;


public class BasicCannon extends Applet implements ActionListener, KeyListener
{
	private Timer timer;

	/**
	 * These instance fields are for getting rid of flicker
	 * on the Windows platform-- the Applet will draw the 
	 * picture in memory before putting it on the screen
	 */
	private Image virtualMem;
	private Graphics g0;
	private Font font;
	private String message;


	/**
	 * game fields
	 */
	private int angle, force, ammo, powder;
	private ArrayList<CannonBall> balls;
	private ArrayList<Rectangle> targets;

	public static final int FLOOR=550;
	public void init(){
		timer = new Timer(10,this);
		font = new Font("Helvetica", Font.BOLD,  18);  
		message="Basic Cannon: Use arrow keys and space bar";

		addKeyListener(this);
		timer.start();
        angle=45;
        force=50;
        ammo=20;
        powder=500;
        balls = new ArrayList<CannonBall>();
        targets = new ArrayList<Rectangle>();
        for(int i=120; i< 800-40; i+=40){
        		targets.add(new Rectangle (i, FLOOR, 30, 10));
        }
	}
	public void paint (Graphics g)
	{
		//make a new buffer in case the applet size changed
		virtualMem = createImage(getWidth(),getHeight());
		g0 = virtualMem.getGraphics();
		g0.setColor(Color.BLACK);
		g0.fillRect(0, 0, this.getWidth(), this.getHeight());
		g0.setColor(Color.WHITE);
		g0.setFont(font);
		g0.drawString(message, 20, 20);
		g0.drawString(" Angle: "+angle, 20, 40);
		g0.drawString(" Force: "+force, 20, 60);
		g0.setColor(Color.YELLOW);
		g0.drawString("  Ammo: "+ammo, 420, 20);
		g0.drawString("Powder: "+powder, 420, 40);
		drawCastle(g0);
		for(CannonBall b:balls)
			b.draw(g0);
		g0.setColor(Color.YELLOW);
		for(Rectangle t:targets)
			g0.fillRect(t.x, t.y, t.width, t.height);
		g.drawImage(virtualMem,0,0,this);//set new display to Screen
	}
	public void update(Graphics g)
	{
		paint(g); //get rid of flicker with this method
	}


	@Override
	public void actionPerformed(ActionEvent e) {
		for(CannonBall b:balls)
			b.move(targets);

		int i=0;
		while(i<balls.size()){
			CannonBall b=balls.get(i);
			if (b.getY()>FLOOR)
				balls.remove(b);
			else
				i++;
		}
		gameOverCheck();
		repaint();

	}
	@Override
	public void keyTyped(KeyEvent e) {
	}
	@Override
	public void keyPressed(KeyEvent e) {
		int key=e.getKeyCode();
		if (key==KeyEvent.VK_DOWN ){
			angle--;
			if (angle<0)
				angle=0;
		}else if(key==KeyEvent.VK_UP){
			angle++;
			if (angle>90)
				angle=90;
		}else if(key==KeyEvent.VK_SPACE){

			if(powder-force<0){
				force=powder;
				powder=0;
			}else{
				powder-=force;
			}

			if (ammo>0 && force>0){ //fire!
				balls.add(new CannonBall(angle, force));
			}
			ammo--;
			if(ammo<0){
				ammo=0;
			}
		}else if(key==KeyEvent.VK_LEFT){
			force--;
			if(force<0)
				force=0;
		}else if(key==KeyEvent.VK_RIGHT){
			force++;
			if(force>100)
				force=100;
		}

		repaint();
	}


	@Override
	public void keyReleased(KeyEvent e) {}
	public void drawCastle(Graphics g)
	{
		g.setColor(Color.LIGHT_GRAY);
		Polygon castle = new Polygon();
		castle.addPoint(80, 260);
		castle.addPoint(120, 260);
		castle.addPoint(120, 270);
		castle.addPoint(110, 280);
		castle.addPoint(110, FLOOR);
		castle.addPoint(90, FLOOR);
		castle.addPoint(90, 280);
		castle.addPoint(80, 270);
		g.fillPolygon(castle);
	}
	private void gameOverCheck() {
		//your code here
	}

}

CannonBall.java

package cannon;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;

public class CannonBall {
	private Rectangle box;
	private double angle, force, time;
	public static final double G=5.8;
	public static final int x0=120;
	public static final int y0=250;
	private int size;
	public CannonBall(int angle, int force) {
		size=15;
		box = new Rectangle(x0,y0,size,size);
		this.angle=angle*Math.PI/180.0;
		this.force=force/1.9;
		time=0.0;
	}
	public CannonBall(int angle, int force, int size) {
		this(angle, force);
		this.size=size;

	}

	public void move(ArrayList<Rectangle> targets) {
		time+=0.1;
		int x=x0+(int)(time*force*Math.cos(angle));
		int y=y0+(int)(-1*time*force*Math.sin(angle)+0.5*G*time*time);
		box = new Rectangle(x,y,size,size);
		int i=0;
		while(i<targets.size()){
			Rectangle t=targets.get(i);
			if(box.intersects(t))
					targets.remove(t);
			else
				i++;
		}
	}

	public int getY() {
		return box.y+box.height;
	}
	public void draw(Graphics g){
		g.setColor(Color.RED);
		g.fillOval(box.x, box.y, box.width, box.height);
	}
	public Rectangle area() {

		return box;
	}

}