Lunarlander

back

Notes

Use the left and right arrow keys to rotate the ship. Press the up arrow key to turn on the engine.

Try to land the ship safely on the ground. You must land gently or the ship will explode!

Source

/* @pjs preload="ship.png, ground.png, explosion.png"; */


Spritesheet ship;
PImage ground;
PImage explosion;

float ROTATION_SPEED = 2.8;
float ACCELERATION = 0.25;
float MAX_SPEED = 2.5;
float DRAG = 1;
float GRAVITY = 0.05;

boolean leftKeyDown, rightKeyDown, upKeyDown;

float angle = -90;
PVector shipPosition;
PVector shipVelocity;
PVector shipAcceleration;
float angularVelocity;

int ship_frame;

ArrayList explosions = new ArrayList();

void setup(){
  size(640, 480);
  
  imageMode(CENTER);
  
  // Load images
  ground = loadImage("ground.png");
  explosion = loadImage("explosion.png");
  ship = new Spritesheet(loadImage("ship.png"), 2);
  shipPosition = new PVector(64, 64, 0);
  shipVelocity = new PVector(0,0,0);
  shipAcceleration = new PVector(0,0,0);
}

void draw(){
  background(#333333);
  
  if(leftKeyDown){
    angularVelocity = -ROTATION_SPEED; 
  }else if(rightKeyDown){
    angularVelocity = ROTATION_SPEED;
  }else{
    angularVelocity = 0; 
  }
  
  if(upKeyDown){
    shipAcceleration.set(cos(radians(angle)) * ACCELERATION, sin(radians(angle)) * ACCELERATION, 0);
    ship_frame = 1; 
  }else{
    shipAcceleration.set(0, 0, 0);
    ship_frame = 0; 
  }
  
  // Create some ground, adjust because of imageMode(CENTER)
  for(int i = 0; i < width; i += ground.width){
     image(ground, i + 16, height - ground.height/2); 
  }  
  
  shipVelocity.add(shipAcceleration);
  shipVelocity.limit(MAX_SPEED);
  if(shipAcceleration.mag() == 0){
    shipVelocity.mult(DRAG);
  }
  shipPosition.add(shipVelocity);
  
  shipVelocity.y += GRAVITY;
  
  angle += angularVelocity;
  
  // Keep the ship on the screen
  if(shipPosition.x > width) shipPosition.x = 0;
  if(shipPosition.x < 0) shipPosition.x = width;
  if(shipPosition.y > height - ground.height * 1.5){
    shipPosition.y = height - ground.height * 1.5;
    
    if(abs(shipVelocity.y) > 1.25 || abs(shipVelocity.x) > 0.3){
      explosions.add(new Explosion(explosion, 4, (int)shipPosition.x, (int)shipPosition.y));
      shipPosition.set(64, 64);
    }
    shipVelocity.y = 0;
  }
  
  pushMatrix();
  translate(shipPosition.x, shipPosition.y);
  rotate(radians(angle));
  image(ship.getFrame(ship_frame), 0, 0);
  popMatrix();
  
  ArrayList deadExplosions = new ArrayList();
  for(Explosion s : explosions){
     s.display();
     if(s.isDead()){
       deadExplosions.add(s);
     }
  }
  for(Explosion s : deadExplosions){
    explosions.remove(s);
  }
}

void keyPressed(){
  if(key == CODED){
     if(keyCode == LEFT){
       leftKeyDown = true;
     }
     if(keyCode == RIGHT){
       rightKeyDown = true;
     }
     if(keyCode == UP){
       upKeyDown = true;
     }
  }
}

void keyReleased(){
  if(key == CODED){
     if(keyCode == LEFT || keyCode == RIGHT){
        leftKeyDown = rightKeyDown = false;
     }
     if(keyCode == UP){
       upKeyDown = false;
     }
  }
}

class Spritesheet{
 PImage[] frames;
 
 Spritesheet(PImage img, int noFrames){
  int frameHeight = img.height / noFrames;
  frames = new PImage[noFrames];
  for(int i = 0; i < frames.length; i++){
    frames[i] = img.get(0, frameHeight * i, img.width, frameHeight);
  }
 }
 
 PImage getFrame(int frame){
   if(frame < frames.length)
     return frames[frame];
   return null;
 }
}

class Explosion{
 PImage[] frames;
 float currentFrame;
 int x;
 int y;
 
 Explosion(PImage img, int noFrames, int x, int y){
  int frameWidth = img.width / noFrames;
  frames = new PImage[noFrames];
  for(int i = 0; i < frames.length; i++){
    frames[i] = img.get(frameWidth * i, 0, frameWidth, img.height);
  }
  this.x = x;
  this.y = y;
 }
 
 void display(){
   currentFrame = (currentFrame + 0.5);
   if(currentFrame < frames.length){
     image(frames[(int)currentFrame], x, y);
   }
 }
 
 boolean isDead(){
   return currentFrame >= frames.length;
 }
}

Warning: Cannot load module "http" because required module "raphf" is not loaded in Unknown on line 0