/***************************************************** * Beginning Java Game Programming, 2nd Edition * by Jonathan S. Harbour * Chapter 3 - ASTEROIDS GAME *****************************************************/ import java.applet.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.*; import java.util.*; /***************************************************** * Primary class for the game inherits from Applet *****************************************************/ public class Asteroids extends Applet implements Runnable, KeyListener { //the main thread becomes the game loop Thread gameloop; //use this as a double buffer BufferedImage backbuffer; //the main drawing object for the back buffer Graphics2D g2d; //toggle for drawing bounding boxes boolean showBounds = false; //create the asteroid array int ASTEROIDS = 20; Asteroid[] ast = new Asteroid[ASTEROIDS]; //create the bullet array int BULLETS = 10; Bullet[] bullet = new Bullet[BULLETS]; int currentBullet = 0; //the player's ship Ship ship = new Ship(); //create the identity transform (0,0) AffineTransform identity = new AffineTransform(); //create a random number generator Random rand = new Random(); /***************************************************** * applet init event *****************************************************/ public void init() { //create the back buffer for smooth graphics backbuffer = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB); g2d = backbuffer.createGraphics(); //set up the ship ship.setX(320); ship.setY(240); //set up the bullets for (int n = 0; n getSize().width + 10) ship.setX(-10); //update ship's Y position ship.incY(ship.getVelY()); //wrap around top/bottom if (ship.getY() < -10) ship.setY(getSize().height + 10); else if (ship.getY() > getSize().height + 10) ship.setY(-10); } /***************************************************** * Update the bullets based on velocity *****************************************************/ public void updateBullets() { //move each of the bullets for (int n = 0; n < BULLETS; n++) { //is this bullet being used? if (bullet[n].isAlive()) { //update bullet's x position bullet[n].incX(bullet[n].getVelX()); //bullet disappears at left/right edge if (bullet[n].getX() < 0 || bullet[n].getX() > getSize().width) { bullet[n].setAlive(false); } //update bullet's y position bullet[n].incY(bullet[n].getVelY()); //bullet disappears at top/bottom edge if (bullet[n].getY() < 0 || bullet[n].getY() > getSize().height) { bullet[n].setAlive(false); } } } } /***************************************************** * Update the asteroids based on velocity *****************************************************/ public void updateAsteroids() { //move and rotate the asteroids for (int n = 0; n < ASTEROIDS; n++) { //is this asteroid being used? if (ast[n].isAlive()) { //update the asteroid's X value ast[n].incX(ast[n].getVelX()); //warp the asteroid at screen edges if (ast[n].getX() < -20) ast[n].setX(getSize().width + 20); else if (ast[n].getX() > getSize().width + 20) ast[n].setX(-20); //update the asteroid's Y value ast[n].incY(ast[n].getVelY()); //warp the asteroid at screen edges if (ast[n].getY() < -20) ast[n].setY(getSize().height + 20); else if (ast[n].getY() > getSize().height + 20) ast[n].setY(-20); //update the asteroid's rotation ast[n].incMoveAngle(ast[n].getRotationVelocity()); //keep the angle within 0-359 degrees if (ast[n].getMoveAngle() < 0) ast[n].setMoveAngle(360 - ast[n].getRotationVelocity()); else if (ast[n].getMoveAngle() > 359) ast[n].setMoveAngle(ast[n].getRotationVelocity()); } } } /***************************************************** * Test asteroids for collisions with ship or bullets *****************************************************/ public void checkCollisions() { //iterate through the asteroids array for (int m = 0; m 360) ship.setFaceAngle(5); break; case KeyEvent.VK_UP: //up arrow adds thrust to ship (1/10 normal speed) ship.setMoveAngle(ship.getFaceAngle() - 90); ship.incVelX(calcAngleMoveX(ship.getMoveAngle()) * 0.1); ship.incVelY(calcAngleMoveY(ship.getMoveAngle()) * 0.1); break; //Ctrl, Enter, or Space can be used to fire weapon case KeyEvent.VK_CONTROL: case KeyEvent.VK_ENTER: case KeyEvent.VK_SPACE: //fire a bullet currentBullet++; if (currentBullet > BULLETS - 1) currentBullet = 0; bullet[currentBullet].setAlive(true); //point bullet in same direction ship is facing bullet[currentBullet].setX(ship.getX()); bullet[currentBullet].setY(ship.getY()); bullet[currentBullet].setMoveAngle(ship.getFaceAngle() - 90); //fire bullet at angle of the ship double angle = bullet[currentBullet].getMoveAngle(); double svx = ship.getVelX(); double svy = ship.getVelY(); bullet[currentBullet].setVelX(svx + calcAngleMoveX(angle) * 2); bullet[currentBullet].setVelY(svy + calcAngleMoveY(angle) * 2); break; } } /***************************************************** * calculate X movement value based on direction angle *****************************************************/ public double calcAngleMoveX(double angle) { return (double) (Math.cos(angle * Math.PI / 180)); } /***************************************************** * calculate Y movement value based on direction angle *****************************************************/ public double calcAngleMoveY(double angle) { return (double) (Math.sin(angle * Math.PI / 180)); } }