// ROCKET AND ASTEROIDS (first pass) // This code is the basis for an object-oriented version of the old arcade game Asteroids! // The rocketship turns and fires thrusters, and // there are five asteroids tumbling around. // The Missile class represents Missiles fire by the ArmedRocket. // Currently the missiles ArrayList accumulates missiles as // they go off into infinite space. They should really be // destroyed when they go beyond the screen boundaries Rocket r1 = new Rocket(50, 60, 0); ArmedRocket ar2 ; Missile m1 ; ArrayList a ; ArrayList missiles ; // we can change the number of asteroids here. final int numAsteroids = 5; void setup() { background(0); size(400, 400); r1.drawMe(); ar2 = new ArmedRocket( width/2, height / 2, 0.5 ); //m1 = new Missile( width/2, height / 2, 0.5 ); a = new ArrayList(); for(int i = 0; i < numAsteroids; i++) { a.add( new Asteroid() ); } missiles = new ArrayList(); } void draw() { background(0); if (keyPressed) { if (key == CODED) { if (keyCode == RIGHT) { ar2.rotateClockwise(); } else if (keyCode == LEFT) { ar2.rotateCounterclockwise(); } else if (keyCode == UP) { Missile m1 = ar2.fire() ; if( m1 != null ) missiles.add( m1 ); } } else if (key == ' ') { ar2.fireThrusters(); } } for( Missile m : missiles ) { m.drawMe(); } ar2.drawMe(); for( int i= 0 ; i < a.size() ; i++ ) { // makes an asteroid disappear if we collide with it. can you think of a way // to make our rocket disappear? Asteroid aa = a.get( i ); if(!((abs(aa.xPos - ar2.xPos) < 20) && (abs(aa.yPos - ar2.yPos) < 20))) { aa.drawMe(); } for( int j= 0 ; j < missiles.size() ; j++ ) { Missile m = missiles.get( j ); if( aa.collision( m ) ) { aa.destroy( a ); missiles.remove( j ); } } } } class Asteroid { // fields float rotation = 0; float xPos, yPos; float velocityX, velocityY; long lastDrawMillis = 0; boolean large = true ; //constructor Asteroid() { xPos = random(0, width); yPos = random(0, height); rotation = random(0, TWO_PI); velocityX = sin(rotation)*10; velocityY = -cos(rotation)*10; } Asteroid( boolean isLarge, float xP, float yP, long lastMS) { large = isLarge ; xPos = xP; yPos = yP; lastDrawMillis = lastMS ; rotation = random(0, TWO_PI); velocityX = sin(rotation)*10; velocityY = -cos(rotation)*10; } boolean collision(Missile m) { if ((m.xPos >= xPos - 26 && m.xPos <= xPos + 22) && (m.yPos >= yPos - 24 && m.yPos <= yPos + 26)) return true; else return false; } void destroy(ArrayList asteroids) { asteroids.remove(this); if (large) { asteroids.add(new Asteroid(false, xPos, yPos, lastDrawMillis)); asteroids.add(new Asteroid(false, xPos, yPos, lastDrawMillis)); } } void drawMe() { long currentMillis = millis(); float timeSinceLastDraw = ((float)currentMillis - (float)lastDrawMillis)/1000; lastDrawMillis = currentMillis; xPos = xPos + velocityX * timeSinceLastDraw; yPos = yPos + velocityY * timeSinceLastDraw; if (xPos > width) { xPos -= width; } else if (xPos < 0) { xPos += width; } if (yPos > height) { yPos -= height; } else if (yPos < 0) { yPos += height; } pushMatrix(); translate(xPos, yPos); rotate(rotation); if( ! large ) scale( 0.5, 0.5 ); int[] xpts = { -20, 0, 18, 22, 5, 20, 17, -3, -17, -18, -26 }; int[] ypts = { -15, -24, -20, -5, 0, 10, 20, 26, 23, 14, 7 }; beginShape(POLYGON); for(int i = 0; i < 11; i++) { vertex(xpts[i], ypts[i]); } endShape(); popMatrix(); } } class Rocket { // fields float rotation = 0; float xPos; float yPos; final int halfWidth = 10; final int halfHeight= 10; float velocityX = 0; float velocityY = 0; long lastDrawMillis = 0; // constructor Rocket(int initialX, int initialY, float initialRot) { xPos = initialX; yPos = initialY; rotation = initialRot; } void drawMe() { long currentMillis = millis(); float timeSinceLastDraw = ((float)currentMillis - (float)lastDrawMillis)/1000; lastDrawMillis = currentMillis; xPos = xPos + velocityX * timeSinceLastDraw; yPos = yPos + velocityY * timeSinceLastDraw; if (xPos > width) { xPos -= width; } else if (xPos < 0) { xPos += width; } if (yPos > height) { yPos -= height; } else if (yPos < 0) { yPos += height; } pushMatrix(); translate(xPos, yPos); rotate(rotation); triangle(0, -halfHeight, -halfWidth, halfHeight, halfWidth,halfHeight); rectMode(CORNERS); rect(-halfWidth + 5, halfHeight, -halfWidth + 8, halfHeight + 3); rect(halfWidth - 8, halfHeight, halfWidth - 5, halfHeight + 3); popMatrix(); } void rotateClockwise() { rotation = rotation + 0.1; } void rotateCounterclockwise() { rotation = rotation - 0.1; } void fireThrusters() { velocityX = velocityX + sin(rotation) * 1; velocityY = velocityY - cos(rotation) * 1; } } class ArmedRocket extends Rocket { long cool = 0 ; // let the missile "gun" "cool off" before firing another missile ArmedRocket( int initialX, int initialY, float initialRot) { super( initialX, initialY, initialRot ); // println( "X = " + xPos + " y =" + yPos + " rot=" + rotation ); } Missile fire() { Missile m ; if( (millis() - cool) > 200 ) // let 200 ms pass before firing another { m = new Missile( xPos, yPos, rotation ); cool = millis(); } else m = null ; return( m ) ; } } class Missile { // fields float rotation = 0; float xPos, yPos; float velocityX, velocityY; long lastDrawMillis ; Missile( float initialX, float initialY, float initialRot) { xPos = initialX; yPos = initialY; rotation = initialRot; velocityX = sin(rotation) * 400.0; velocityY = -cos(rotation) * 400.0; lastDrawMillis = millis() ; } void drawMe() { long currentMillis = millis(); float timeSinceLastDraw = ((float)currentMillis - (float)lastDrawMillis)/1000; lastDrawMillis = currentMillis; xPos = xPos + velocityX * timeSinceLastDraw; yPos = yPos + velocityY * timeSinceLastDraw; pushMatrix(); translate(xPos, yPos); rotate(rotation); rect( 0, 0, 5, 20 ); popMatrix(); } }