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 <rickbarrette@gmail.com>
This commit is contained in:
2012-04-02 13:36:30 -04:00
parent faeb1b790c
commit 88b8853c31
8 changed files with 265 additions and 78 deletions

View File

@@ -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);
@@ -66,12 +67,86 @@ public class Asteroid extends MovingSpaceObject implements Drawable {
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;
}
/**
@@ -90,4 +165,24 @@ public class Asteroid extends MovingSpaceObject implements Drawable {
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;
}
}

View File

@@ -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<Object>();
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<Object> 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) {
while (true){
if(isStarted) {
mGameFrame.repaintDisplay();
mGameFrame.getStatusBar().updateStatus();
mGameFrame.repaintDisplay();
mGameFrame.getStatusBar().updateStatus();
/*
* check for collsions
*/
Object o;
Collider c;
Vector<Object> wolrd = new Vector<Object>(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();
}
}

View File

@@ -27,4 +27,6 @@ package com.RickBarrette.asteroids;
*/
public interface Collider {
public boolean checkForCollision(Object o);
}

View File

@@ -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
@@ -58,6 +59,11 @@ public class Display extends JPanel {
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;
}
}

View File

@@ -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,6 +96,8 @@ public class GameFrame extends JFrame implements KeyListener{
xlistener = new menuListener();
mMenuNewGame.addActionListener(xlistener);
mMenuQuit.addActionListener(xlistener);
mMenuStartGame.addActionListener(xlistener);
mMenuPauseGame.addActionListener(xlistener);
addKeyListener(this);
@@ -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);
}
@@ -273,7 +300,6 @@ public class GameFrame extends JFrame implements KeyListener{
for(Object item : mGame.getWorld())
if(item instanceof MovingSpaceObject)
((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();
}
}

View File

@@ -35,7 +35,7 @@ public class Main {
public Main() {
AsteroidGame game = new AsteroidGame();
game.createGame();
game.start();
game.startGame();
}
/**

View File

@@ -73,57 +73,49 @@ public class MovingSpaceObject extends SpaceObject implements Moveable{
*/
@Override
public void move(int scrnWidth, int scrnHeight) {
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;
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);
// 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);
// 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);
}
/*
* 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);
// 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);
}
/**

View File

@@ -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;
}
/**