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:
- A win is when there are no targets left (Hint:
targets.size()
returns the number of targets ) - A loss due to lack of both
ammo
andpowder
- A loss due to a lack of
ammo
only - A loss due to lack of
powder
When one of these conditions exist, the String field message
should report:
- "You win with XXX cannonballs and YYY gunpowder left!"
- "Game Over-- out of cannonballs and gunpowder"
- "Game Over-- out of cannonballs"
- "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; } }