Asteroids
AsteroidsGame.java¶
import acm.program.*;
import acm.graphics.*;
import java.awt.Color;
import java.awt.event.*;
import java.util.*;
import java.applet.AudioClip;
import acm.util.MediaTools;
public class AsteroidsGame extends GraphicsProgram
{
// uncomment out the line below in version 0.4.1
private ArrayList<Asteroid> asteroids;
private boolean playing, respawned;
private GLabel notificationLabel, scoreLabel, livesLabel;
// uncomment out the line below in version 0.4.1
private Ship ship;
// uncomment out the line below in version 0.5.2
// (and don't forget to write bullets = new ArrayList<Bullet>() in the initializeVariables method!)
private ArrayList<Bullet> bullets;
private int level, numLivesRemaining, score;
private AudioClip thrustClip, fireClip, bigBangClip, mediumBangClip, smallBangClip;
//
//
// Runtime Methods
public void run() {
// code for version 0.1.1 goes here
initVars();
setBackground(Color.black);
while (playing) {
animationLoop();
}
}
public void animationLoop() {
updatePositions();
if (checkForCollisions(ship) != null) {
shipCollided();
}
checkForBulletCollisions();
if(asteroids.size() == 0){
level++;
remove(ship);
initShip();
initAsteroids();
}
scoreLabel.setText("Score: "+score);
livesLabel.setText("Lives: " + numLivesRemaining);
pause(5);
}
private void updatePositions(){
for(Asteroid a : asteroids){
a.updatePosition();
}
for(int i = 0; i<bullets.size(); i++){
if(bullets.get(i).stillMoving()){
bullets.get(i).updatePosition();
} else {
remove(bullets.remove(i));
}
}
ship.updatePosition();
}
private void checkForBulletCollisions(){
for(int i=0; i<bullets.size(); i++){
Asteroid collidedAsteroid = checkForCollisions(bullets.get(i));
//hit asteroid
if(collidedAsteroid != null){
remove(bullets.remove(i));
remove(asteroids.remove(asteroids.indexOf(collidedAsteroid)));
if(!(collidedAsteroid instanceof SmallAsteroid)){ //regular or medium asteroid (need to make another)
if(collidedAsteroid instanceof MediumAsteroid){ //medium asteroid
score += 50;
mediumBangClip.play();
}
else { //regular asteroid
score += 20;
bigBangClip.play();
}
shotAsteroid(collidedAsteroid);
} else {//hit small asteroid
score += 100;
smallBangClip.play();
}
}
}
}
//
//
// Init Methods
public void initVars() {
thrustClip = MediaTools.loadAudioClip("thrust.wav");
fireClip = MediaTools.loadAudioClip("fire.wav");
bigBangClip = MediaTools.loadAudioClip("bangLarge.wav");
mediumBangClip = MediaTools.loadAudioClip("bangMedium.wav");
smallBangClip = MediaTools.loadAudioClip("bangSmall.wav");
level = 0;
numLivesRemaining = 3;
score = 0;
notificationLabel = new GLabel("(up) = thrust, (left) = rotate left, (right) = rotate right, (space) = fire, (H) = Hyperspace Click mouse to continue");
notificationLabel.setColor(Color.WHITE);
notificationLabel.setFont("Courier-Plain-12");
notificationLabel.setLocation((getWidth()-notificationLabel.getWidth())/2, getHeight()/2-40);
add(notificationLabel);
scoreLabel = new GLabel("Score:"+score);
scoreLabel.setColor(Color.WHITE);
scoreLabel.setFont("Courier-Plain-10");
scoreLabel.setLocation(16, 16);
add(scoreLabel);
livesLabel = new GLabel("Lives: " + numLivesRemaining);
livesLabel.setColor(Color.WHITE);
livesLabel.setFont("Courier-Plain-10");
livesLabel.setLocation(16, 25);
add(livesLabel);
// uncomment out the line below in version 0.3
initShip();
asteroids = new ArrayList<Asteroid>();
initAsteroids();
bullets = new ArrayList<Bullet>();
playing = true;
respawned = false;
}
private void initAsteroids() {
// code for version 0.3.1 goes here
for (int i = 0; i < level+3; i ++){
Asteroid a = new Asteroid(getWidth(), getHeight());
a.setLocation(Math.random() * getWidth(), Math.random()*getHeight());
a.rotate(Math.random()*180 - 90);
asteroids.add(a);
}
for (Asteroid a : asteroids){
a.increaseVelocity(1);
add(a);
}
}
private void initShip(){
ship = new Ship(getWidth(), getHeight());
ship.setLocation(getWidth()/2, getHeight()/2);
respawned = true;
add(ship);
}
//
//
// Event Methods
private void shotAsteroid(Asteroid asteroid){
double angle = Math.random() * 360;
for (int i = 0; i < 3; i++){
Asteroid a = asteroid instanceof MediumAsteroid ? new SmallAsteroid(getWidth(), getHeight()): new MediumAsteroid(getWidth(), getHeight());
a.setLocation(asteroid.getX(), asteroid.getY());
a.rotate(angle + 120*i);
if(a instanceof MediumAsteroid){
a.increaseVelocity(1.5);
} else{
a.increaseVelocity(2);
}
asteroids.add(a);
add(a);
}
asteroids.remove(asteroid);
remove(asteroid);
}
public void mouseClicked(MouseEvent e){
remove(notificationLabel);
}
private void shipCollided(){
if (!respawned){
numLivesRemaining--; // for now so i can debug
}
if (numLivesRemaining == 0) {
playing = false;
gameOver();
} else {
remove(ship);
initShip();
}
}
public void keyPressed(KeyEvent e){
if (e.getKeyCode()==KeyEvent.VK_RIGHT)
ship.rotate(-15); // rotate a bit clockwise
if (e.getKeyCode()==KeyEvent.VK_LEFT)
ship.rotate(15);
if (e.getKeyCode()==KeyEvent.VK_UP){
if (respawned) respawned = false; //as soon as you move you lose immunity
ship.increaseVelocity(0.3);
}
if (e.getKeyCode()==KeyEvent.VK_SPACE){
Bullet b = ship.makeBullet(getWidth(), getHeight());
b.increaseVelocity(3);
add(b);
bullets.add(b);
}
if (e.getKeyCode()==KeyEvent.VK_H){
ship.setLocation(Math.random() * getWidth(), Math.random()*getHeight());
}
}
private Asteroid checkForCollisions(GVectorPolygon obj)
{
for (Asteroid a:asteroids)
if (a.getBounds().intersects(obj.getBounds()))
{
return a;
}
return null;
}
public void gameOver(){
removeAll();
asteroids.clear();
bullets.clear();
GLabel gameOverLabel = new GLabel("Game Over!");
gameOverLabel.setFont("Helvetica-Plain-64");
gameOverLabel.setColor(Color.WHITE);
gameOverLabel.setLocation(getWidth()/2 - gameOverLabel.getWidth()/2, 100);
add(gameOverLabel);
GLabel stats = new GLabel("You made it to level " + level + " with a score of " + score + ".");
stats.setFont("Helvetica-Plain-22");
stats.setColor(Color.WHITE);
stats.setLocation(getWidth()/2 - stats.getWidth()/2, getHeight()/2-stats.getHeight()/2);
add(stats);
}
}
Asteroid.java¶
import acm.graphics.*;
import java.awt.Color;
import java.util.*;
public class Asteroid extends GVectorPolygon
{
private double rotation;
public Asteroid(int windowWidth, int windowHeight)
{
super(windowWidth, windowHeight);
rotation = Math.random();
addVertex(25, -45);
addVertex(-25, -45);
addVertex(-50, 0);
addVertex(-25, 45);
addVertex(25, 45);
addVertex(50, 0);
recenter();
}
@Override
public void updatePosition(){
rotate(rotation);
super.updatePosition();
}
}
Ship.java¶
import java.awt.Color;
public class Ship extends GVectorPolygon
{
public Ship(int windowWidth, int windowHeight)
{
// write this in version 0.4
super(windowWidth, windowHeight);
addVertex(-3, 0);
addVertex(-10, 10);
addVertex(10, 0);
addVertex(-10, -10);
rotate(90);
recenter();
}
// you'll add a method here in version 0.5.1
public Bullet makeBullet(int windowWidth, int windowHeight){
Bullet b = new Bullet(windowWidth, windowHeight);
b.rotate(getTheta());
b.setLocation(getX(), getY());
return b;
}
}
Bullet.java¶
import java.awt.Color;
public class Bullet extends GVectorPolygon {
private int numTurns;
private static final int MAXTURNS=150;
public Bullet(int windowWidth, int windowHeight) {
super(windowWidth, windowHeight);
numTurns = 0;
addVertex(-1, 1);
addVertex(1, 1);
addVertex(1, -1);
addVertex(-1, -1);
recenter();
setFilled(true);
}
// complete this in version 0.
public boolean stillMoving() {
return numTurns < MAXTURNS;
}
@Override
public void updatePosition(){
numTurns ++;
super.updatePosition();
}
}
Last update:
June 5, 2023
Created: June 5, 2023
Created: June 5, 2023