From 88b8853c316605a6db9c6320fe8d6b8bcff6f043 Mon Sep 17 00:00:00 2001 From: Ricky Barrette Date: Mon, 2 Apr 2012 13:36:30 -0400 Subject: [PATCH] Finished bacis collioion handling, and bacis game life cycle funtions. the came can be started, pasused, restarted, won, and lost Signed-off-by: Ricky Barrette --- .../com/RickBarrette/asteroids/Asteroid.java | 117 ++++++++++++++++-- .../RickBarrette/asteroids/AsteroidGame.java | 79 ++++++++++-- .../com/RickBarrette/asteroids/Collider.java | 4 +- .../com/RickBarrette/asteroids/Display.java | 10 ++ .../com/RickBarrette/asteroids/GameFrame.java | 37 +++++- .../src/com/RickBarrette/asteroids/Main.java | 2 +- .../asteroids/MovingSpaceObject.java | 90 ++++++-------- .../src/com/RickBarrette/asteroids/Ship.java | 4 +- 8 files changed, 265 insertions(+), 78 deletions(-) diff --git a/Asteroids/src/com/RickBarrette/asteroids/Asteroid.java b/Asteroids/src/com/RickBarrette/asteroids/Asteroid.java index d596abe..397a3a0 100644 --- a/Asteroids/src/com/RickBarrette/asteroids/Asteroid.java +++ b/Asteroids/src/com/RickBarrette/asteroids/Asteroid.java @@ -28,12 +28,14 @@ import java.awt.Graphics; * * @author ricky barrette */ -public class Asteroid extends MovingSpaceObject implements Drawable { +public class Asteroid extends MovingSpaceObject implements Collider, Drawable { private final int mNumberSplit; private final int mHitsLeft; private final int mRadius; private AsteroidGame mGame; + private double mMinVelocity; + private double mMaxVelocity; /** * Creates a new Asteroid @@ -42,18 +44,17 @@ public class Asteroid extends MovingSpaceObject implements Drawable { * @param y * @param xVelocity * @param yVelocity - * @param numberSplit - * number of smaller asteroids to create after being blown up - * @param hitsLeft - * number of hits left + * @param numberSplit number of smaller asteroids to create after being blown up + * @param hitsLeft number of hits left * @author ricky barrette */ - public Asteroid(double x, double y, double minVelocity, double maxVelocity, - int radius, int numberSplit, int hitsLeft, AsteroidGame game) { + public Asteroid(double x, double y, double minVelocity, double maxVelocity, int radius, int numberSplit, int hitsLeft, AsteroidGame game) { mGame = game; mColor = Color.GRAY; mX = x; mY = y; + mMinVelocity = minVelocity; + mMaxVelocity = maxVelocity; double vel = minVelocity + Math.random() * (maxVelocity - minVelocity); mAngle = 2 * Math.PI * Math.random(); // random direction mXVelocity = vel * Math.cos(mAngle); @@ -65,13 +66,87 @@ public class Asteroid extends MovingSpaceObject implements Drawable { mVelocityDecay = 1; isActive = true; } - + + /** + * Creates a smaller asteroid + * @param minVelocity + * @param maxVelocity + * @return new smaller asteroid + * @author ricky barrette + */ + public Asteroid createSplitAsteroid(double minVelocity, double maxVelocity){ + //when this asteroid gets hit by a shot, this method is called + //numSplit times by AsteroidsGame to create numSplit smaller + //asteroids. Dividing the radius by sqrt(numSplit) makes the + //sum of the areas taken up by the smaller asteroids equal to + //the area of this asteroid. Each smaller asteroid has one + //less hit left before being completely destroyed. + return new Asteroid(mX,mY, minVelocity, maxVelocity, (int) (mRadius/Math.sqrt(mNumberSplit)), mNumberSplit, mHitsLeft-1, mGame); + } + + /** + * Called when the Asteroid needs to be drawn + * (non-Javadoc) + * @see com.RickBarrette.asteroids.Drawable#draw(java.awt.Graphics) + */ @Override public void draw(Graphics g) { g.setColor(mColor); - g.fillOval((int) (mX - mRadius + .5), (int) (mY - mRadius + .5), - (int) (2 * mRadius), (int) (2 * mRadius)); + g.fillOval((int) (mX - mRadius + .5), (int) (mY - mRadius + .5), (int) (2 * mRadius), (int) (2 * mRadius)); + } + /** + * @return the asteroid's radius + * @author ricky barrette + */ + public int getRadius() { + return mRadius; + } + + /** + * Checks for a collision with the ship + * @param ship + * @return true if there is a collision + * @author ricky barrette + */ + public boolean shipCollision(Ship ship) { + /* + * Use the distance formula to check if the ship is touching this + * asteroid: Distance^2 = (x1-x2)^2 + (y1-y2)^2 ("^" denotes + * exponents). If the sum of the radii is greater than the + * distance between the center of the ship and asteroid, they are + * touching. + * if (shipRadius + asteroidRadius)^2 > (x1-x2)^2 + (y1-y2)^2, + * then they have collided. + * It does not check for collisions if the ship is not active + * (the player is waiting to start a new life or the game is paused). + */ + if ( Math.pow(mRadius + ship.getRadius(), 2) > Math.pow(ship.getX() - mX, 2) + Math.pow(ship.getY() - mY, 2)){ + return true; + } + return false; + } + + /** + * Checks for a collision with s shot + * @param shot + * @return true if there is a collision + * @author ricky barrette + */ + public boolean shotCollision(Shot shot) { + if( Math.pow(mRadius, 2) > Math.pow(shot.getX() - mX, 2) + Math.pow(shot.getY() - mY, 2)){ + /* + * if there is a collsion, and there are hits left, + * create new astroids, and remove self + */ + if(mHitsLeft > 0) + for(int i = 0; i < mNumberSplit; i++) + mGame.addElement(createSplitAsteroid(mMinVelocity, mMaxVelocity)); + + mGame.removeElement(this); + return true; + } + return false; } /** @@ -84,10 +159,30 @@ public class Asteroid extends MovingSpaceObject implements Drawable { mX += scrnHeight + 2 * mRadius; else if (mX > scrnHeight + mRadius) mX -= scrnHeight + 2 * mRadius; - + if (mY < 0 - mRadius) mY += scrnWidth + 2 * mRadius; else if (mY > scrnWidth + mRadius) mY -= scrnWidth + 2 * mRadius; } + + /** + * Called when a collision check needs to be made. + * Only checks for ship and shots + * (non-Javadoc) + * @see com.RickBarrette.asteroids.Collider#checkForCollision(java.lang.Object) + */ + @Override + public boolean checkForCollision(Object o) { + + if(o instanceof Ship) { + return shipCollision((Ship) o); + } + + if(o instanceof Shot) { + return shotCollision((Shot) o); + } + + return false; + } } \ No newline at end of file diff --git a/Asteroids/src/com/RickBarrette/asteroids/AsteroidGame.java b/Asteroids/src/com/RickBarrette/asteroids/AsteroidGame.java index d737073..7c7e6f7 100644 --- a/Asteroids/src/com/RickBarrette/asteroids/AsteroidGame.java +++ b/Asteroids/src/com/RickBarrette/asteroids/AsteroidGame.java @@ -40,6 +40,7 @@ public class AsteroidGame extends Thread { public AsteroidGame() { mGameFrame = new GameFrame(this); //TODO simulate game play unitll game ist started + this.start(); } /** @@ -50,6 +51,10 @@ public class AsteroidGame extends Thread { public void addElement(Object o) { if(o instanceof Shot) mGameFrame.getStatusBar().setShotCount(mGameFrame.getStatusBar().getShotCount()+1); + + if(o instanceof Asteroid) + mGameFrame.getStatusBar().setAsteroidCount(mGameFrame.getStatusBar().getAsteroidCount()+1); + mWorld.addElement(o); } @@ -60,7 +65,8 @@ public class AsteroidGame extends Thread { public void createGame() { mWorld = new Vector(); mWorld.add(new Ship(100,100,0,.35,.98,.4,1)); - mWorld.add(new Asteroid(500, 500, 1, 10, 50, 3, 3, this)); + addElement(new Asteroid(500, 500, 1, 10, 50, 3, 3, this)); + mGameFrame.getStatusBar().setShipCount(3); } public Vector getWorld() { @@ -81,6 +87,7 @@ public class AsteroidGame extends Thread { */ public void newGame() { mWorld.clear(); + mGameFrame.setDisplayText(null); createGame(); } @@ -90,6 +97,7 @@ public class AsteroidGame extends Thread { */ public synchronized void pause(){ isStarted = false; + mGameFrame.setDisplayText("Paused"); } /** @@ -100,6 +108,9 @@ public class AsteroidGame extends Thread { public void removeElement(Object o) { if(o instanceof Shot) mGameFrame.getStatusBar().setShotCount(mGameFrame.getStatusBar().getShotCount()-1); + + if(o instanceof Asteroid) + mGameFrame.getStatusBar().setAsteroidCount(mGameFrame.getStatusBar().getAsteroidCount()-1); mWorld.removeElement(o); } @@ -110,11 +121,31 @@ public class AsteroidGame extends Thread { */ @Override public void run() { - while(isStarted) { - - mGameFrame.repaintDisplay(); - mGameFrame.getStatusBar().updateStatus(); - + while (true){ + if(isStarted) { + + mGameFrame.repaintDisplay(); + mGameFrame.getStatusBar().updateStatus(); + + /* + * check for collsions + */ + Object o; + Collider c; + Vector wolrd = new Vector(mWorld); + for (int i = 0; i < wolrd.size(); i++){ + o = wolrd.get(i); + if(o instanceof Collider){ + c = (Collider) o; + for(int index = 0; index < wolrd.size(); index++) + if(c.checkForCollision(wolrd.get(index))) + //check to see if the ship blew up + if(wolrd.get(index) instanceof Ship) + downShip(); + } + } + + } /* * sleep till next time */ @@ -126,6 +157,34 @@ public class AsteroidGame extends Thread { } } + /** + * When this methods is called, the player's ship is down. + * @author ricky barrette + */ + private void downShip() { + System.out.println("Ship collision dected"); + /* + * remove the players ship's + */ + Object o; + for (int i = 0; i < mWorld.size(); i++){ + o = mWorld.get(i); + if(o instanceof Ship) + mWorld.remove(i); + } + + mGameFrame.getStatusBar().setShipCount(mGameFrame.getStatusBar().getShipCount() -1); + + if(mGameFrame.getStatusBar().getShipCount() > 0){ + pause(); + mWorld.add(new Ship(100,100,0,.35,.98,.4,1)); + mGameFrame.setDisplayText("You died, press start when ready."); + } else { + mGameFrame.setDisplayText("Game Over"); + } + mGameFrame.repaint(); + } + /** * @return the number of objects in the world * @author ricky barrette @@ -138,12 +197,10 @@ public class AsteroidGame extends Thread { * Starts the game * @author ricky barrette */ - @Override - public synchronized void start(){ - + public synchronized void startGame(){ + mGameFrame.setDisplayText(null); mGameFrame.setMovingSpaceObjectsEnabled(true); - isStarted = true; - super.start(); + } } \ No newline at end of file diff --git a/Asteroids/src/com/RickBarrette/asteroids/Collider.java b/Asteroids/src/com/RickBarrette/asteroids/Collider.java index 1f6a1b1..b7f13cf 100644 --- a/Asteroids/src/com/RickBarrette/asteroids/Collider.java +++ b/Asteroids/src/com/RickBarrette/asteroids/Collider.java @@ -27,4 +27,6 @@ package com.RickBarrette.asteroids; */ public interface Collider { -} + public boolean checkForCollision(Object o); + +} \ No newline at end of file diff --git a/Asteroids/src/com/RickBarrette/asteroids/Display.java b/Asteroids/src/com/RickBarrette/asteroids/Display.java index 29d0f7a..b90cd86 100644 --- a/Asteroids/src/com/RickBarrette/asteroids/Display.java +++ b/Asteroids/src/com/RickBarrette/asteroids/Display.java @@ -36,6 +36,7 @@ public class Display extends JPanel { private static final long serialVersionUID = -9105117186423881937L; private AsteroidGame mGame; private Container mContainer; + private String mText; /** * Creates a new Dispay @@ -57,6 +58,11 @@ public class Display extends JPanel { @Override public void paintComponent(Graphics g) { super.paintComponent(g); + + if(mText != null){ + g.setColor(Color.ORANGE); + g.drawString(mText, this.getHeight() /2 , this.getWidth() / 2); + } /* * Move & Draw the world's objects @@ -72,4 +78,8 @@ public class Display extends JPanel { ((Drawable) item).draw(g); } } + + public void setDisplayText(String string) { + mText = string; + } } \ No newline at end of file diff --git a/Asteroids/src/com/RickBarrette/asteroids/GameFrame.java b/Asteroids/src/com/RickBarrette/asteroids/GameFrame.java index 04b52c4..b64b8d7 100644 --- a/Asteroids/src/com/RickBarrette/asteroids/GameFrame.java +++ b/Asteroids/src/com/RickBarrette/asteroids/GameFrame.java @@ -51,6 +51,10 @@ public class GameFrame extends JFrame implements KeyListener{ private menuListener xlistener; private AsteroidGame mGame; + private JMenuItem mMenuStartGame; + + private JMenuItem mMenuPauseGame; + /** * Creates a new GameFrame * @@ -67,10 +71,15 @@ public class GameFrame extends JFrame implements KeyListener{ mMenu = new JMenu("File"); mMenuNewGame = new JMenuItem("New Game"); + mMenuStartGame = new JMenuItem("Start"); + mMenuPauseGame = new JMenuItem("Pause"); mMenuQuit = new JMenuItem("Quit"); mMenu.add(mMenuNewGame); mMenu.addSeparator(); + mMenu.add(mMenuStartGame); + mMenu.add(mMenuPauseGame); + mMenu.addSeparator(); mMenu.add(mMenuQuit); mMenuBar.add(mMenu); @@ -87,7 +96,9 @@ public class GameFrame extends JFrame implements KeyListener{ xlistener = new menuListener(); mMenuNewGame.addActionListener(xlistener); mMenuQuit.addActionListener(xlistener); - + mMenuStartGame.addActionListener(xlistener); + mMenuPauseGame.addActionListener(xlistener); + addKeyListener(this); setDefaultCloseOperation(EXIT_ON_CLOSE); @@ -102,6 +113,16 @@ public class GameFrame extends JFrame implements KeyListener{ mDisplay.repaint(); } + /** + * (non-Javadoc) + * @see java.awt.Component#repaint() + */ + @Override + public void repaint() { + mDisplay.repaint(); + super.repaint(); + } + private class menuListener implements ActionListener { public void actionPerformed(ActionEvent e) { @@ -110,6 +131,12 @@ public class GameFrame extends JFrame implements KeyListener{ mDisplay.repaint(); } + if (e.getActionCommand().equals("Start")) { + mGame.startGame(); + } + if (e.getActionCommand().equals("Pause")) { + mGame.pause(); + } if (e.getActionCommand().equals("Quit")) System.exit(0); } @@ -272,8 +299,7 @@ public class GameFrame extends JFrame implements KeyListener{ public void setMovingSpaceObjectsEnabled(boolean b) { for(Object item : mGame.getWorld()) if(item instanceof MovingSpaceObject) - ((MovingSpaceObject) item).setActive(b); - + ((MovingSpaceObject) item).setActive(b); } /** @@ -282,4 +308,9 @@ public class GameFrame extends JFrame implements KeyListener{ public Status getStatusBar() { return mStatusBar; } + + public void setDisplayText(String string) { + mDisplay.setDisplayText(string); + this.repaint(); + } } \ No newline at end of file diff --git a/Asteroids/src/com/RickBarrette/asteroids/Main.java b/Asteroids/src/com/RickBarrette/asteroids/Main.java index f695949..4fe149f 100644 --- a/Asteroids/src/com/RickBarrette/asteroids/Main.java +++ b/Asteroids/src/com/RickBarrette/asteroids/Main.java @@ -35,7 +35,7 @@ public class Main { public Main() { AsteroidGame game = new AsteroidGame(); game.createGame(); - game.start(); + game.startGame(); } /** diff --git a/Asteroids/src/com/RickBarrette/asteroids/MovingSpaceObject.java b/Asteroids/src/com/RickBarrette/asteroids/MovingSpaceObject.java index 67105a0..0767591 100644 --- a/Asteroids/src/com/RickBarrette/asteroids/MovingSpaceObject.java +++ b/Asteroids/src/com/RickBarrette/asteroids/MovingSpaceObject.java @@ -73,57 +73,49 @@ public class MovingSpaceObject extends SpaceObject implements Moveable{ */ @Override public void move(int scrnWidth, int scrnHeight) { - - if(Main.DEBUG){ - System.out.println("Move "+ scrnWidth +" x "+ scrnHeight); - System.out.println("angle "+mAngle); - System.out.println("xVelocity = "+mXVelocity); - System.out.println("yVelocity = "+mYVelocity); - System.out.println("yX = "+mX); - System.out.println("yY = "+mY); - } - - /* - * this is backwards from typical polar coordinates - * because positive y is downward. - */ - if (isTurningLeft) - mAngle -= mRotationalSpeed; - /* - * Because of that, adding to the angle is - * rotating clockwise (to the right) - */ - if (isTurningRight) - mAngle += mRotationalSpeed; - - // Keep angle within bounds of 0 to 2*PI - if (mAngle > (2 * Math.PI)) - mAngle -= (2 * Math.PI); - else if (mAngle < 0) - mAngle += (2 * Math.PI); - - // adds accel to velocity in direction pointed - if (isAccelerating) { - if(Main.DEBUG) - System.out.println("accelerating by "+mAcceleration); + if(isActive){ + /* + * this is backwards from typical polar coordinates + * because positive y is downward. + */ + if (isTurningLeft) + mAngle -= mRotationalSpeed; + /* + * Because of that, adding to the angle is + * rotating clockwise (to the right) + */ + if (isTurningRight) + mAngle += mRotationalSpeed; + + // Keep angle within bounds of 0 to 2*PI + if (mAngle > (2 * Math.PI)) + mAngle -= (2 * Math.PI); + else if (mAngle < 0) + mAngle += (2 * Math.PI); - // calculates components of accel and adds them to velocity - mXVelocity += mAcceleration * Math.cos(mAngle); - mYVelocity += mAcceleration * Math.sin(mAngle); + // adds accel to velocity in direction pointed + if (isAccelerating) { + if(Main.DEBUG) + System.out.println("accelerating by "+mAcceleration); + + // calculates components of accel and adds them to velocity + mXVelocity += mAcceleration * Math.cos(mAngle); + mYVelocity += mAcceleration * Math.sin(mAngle); + } + + // move the space object by adding velocity to position + mX += mXVelocity; + mY += mYVelocity; + + /* + * slows ship down by percentages (velDecay + * should be a decimal between 0 and 1 + */ + mXVelocity *= mVelocityDecay; + mYVelocity *= mVelocityDecay; + + wrapSpace(scrnHeight, scrnWidth); } - - // move the space object by adding velocity to position - mX += mXVelocity; - mY += mYVelocity; - - /* - * slows ship down by percentages (velDecay - * should be a decimal between 0 and 1 - */ - mXVelocity *= mVelocityDecay; - mYVelocity *= mVelocityDecay; - - wrapSpace(scrnHeight, scrnWidth); } /** diff --git a/Asteroids/src/com/RickBarrette/asteroids/Ship.java b/Asteroids/src/com/RickBarrette/asteroids/Ship.java index 91467d3..d21d181 100644 --- a/Asteroids/src/com/RickBarrette/asteroids/Ship.java +++ b/Asteroids/src/com/RickBarrette/asteroids/Ship.java @@ -44,7 +44,7 @@ public class Ship extends MovingSpaceObject implements Drawable { /* * radius of circle used to approximate the ship */ - private final int radius = 6; + private final int mRadius = 6; /** * Creates a new ship @@ -140,7 +140,7 @@ public class Ship extends MovingSpaceObject implements Drawable { * @author ricky barrette */ public double getRadius() { - return radius; + return mRadius; } /**