Friday, January 23, 2015

Anansi: The Player Ship


We now have a playfield, a sprite base class and a keyboard handler. It's time we add the player ship.

The class for the playership needs some information from us:

  • the user input for ship navigation
  • the boundary of the playfield so that the ship can't be navigated outside
  • the ship's speed

The ship is equipped with weapons. We'll add a cannon to it. The cannon can be fired, but needs to recharge itself, so that the firing won't happen too quickly.

There are several options to fire a bullet. One of them is that the player's ship spawns the bullets. But for that it would need to know about the bullet layer. So I'd rather prefer we only indicate that a bullet is fired and let the sprite manager, i. e. for now a method call in the game loop do the bullet spawning for us.

The player class:


public class Player extends SpriteBase {

 double playerShipMinX;
 double playerShipMaxX;
 double playerShipMinY;
 double playerShipMaxY;

 Input input;
 
 double speed;
 
 double cannonChargeTime = 6; // the cannon can fire every n frames 
 double cannonChargeCounter = cannonChargeTime; // initially the cannon is charged
 double cannonChargeCounterDelta = 1; // counter is increased by this value each frame 
 
 double cannonBullets = 5; // number of bullets which the cannon can fire in 1 shot (center, left, right)
 double cannonBulletSpread = 0.6; // dx of left and right bullets
 double cannonBulletSpeed = 8.0; // speed of each bullet

 public Player(Pane layer, Image image, double x, double y, double r, double dx, double dy, double dr, double health, double damage, double speed, Input input) {

  super(layer, image, x, y, r, dx, dy, dr, health, damage);

  this.speed = speed;
  this.input = input;
  
  init();
 }

 
 private void init() {
  
  // calculate movement bounds of the player ship
  // allow half of the ship to be outside of the screen 
  playerShipMinX = 0 - image.getWidth() / 2.0;
  playerShipMaxX = Settings.SCENE_WIDTH - image.getWidth() / 2.0;
  playerShipMinY = 0 - image.getHeight() / 2.0;
  playerShipMaxY = Settings.SCENE_HEIGHT -image.getHeight() / 2.0;
  
 }

 public void processInput() {
  
  // ------------------------------------
  // movement
  // ------------------------------------
  
     // vertical direction
     if( input.isMoveUp()) {
      dy = -speed;
     } else if( input.isMoveDown()) {
      dy = speed;
     } else {
      dy = 0d;
     }
     
     // horizontal direction
     if( input.isMoveLeft()) {
      dx = -speed;
     } else if( input.isMoveRight()) {
      dx = speed;
     } else {
      dx = 0d;
     }

 }
 
 @Override
 public void move() {
  
  super.move();
  
  // ensure the ship can't move outside of the screen
  checkBounds();
  
     
 }
 
 private void checkBounds() {

     // vertical
     if( Double.compare( y, playerShipMinY) < 0) {
      y = playerShipMinY;
     } else if( Double.compare(y, playerShipMaxY) > 0) {
      y = playerShipMaxY;
     }

     // horizontal
     if( Double.compare( x, playerShipMinX) < 0) {
      x = playerShipMinX;
     } else if( Double.compare(x, playerShipMaxX) > 0) {
      x = playerShipMaxX;
     }

 }
 
 @Override
 public void checkRemovability() {
  // TODO will be added later when the player ship explodes
 }

 public boolean isFirePrimaryWeapon() {
  
     boolean isCannonCharged = cannonChargeCounter >= cannonChargeTime;
     
     return input.isFirePrimaryWeapon() && isCannonCharged;
     
 }

 public void chargePrimaryWeapon() {
  
     // limit weapon fire
     // ---------------------------
     // charge weapon: increase a counter by some delta. once it reaches a limit, the weapon is considered charged
     cannonChargeCounter += cannonChargeCounterDelta;
     if( cannonChargeCounter > cannonChargeTime) {
      cannonChargeCounter = cannonChargeTime;
     }
     
 }

 public void unchargePrimaryWeapon() {
  
  // player bullet uncharged
  cannonChargeCounter = 0;

 }
 
 public double getPrimaryWeaponX() {
  return x + image.getWidth() / 2.0; // center of the ship
 }
 public double getPrimaryWeaponY() {
  return y;
 }
 
 public double getPrimaryWeaponBulletSpread() {
  return cannonBulletSpread;
 }
 public double getPrimaryWeaponBulletCount() {
  return cannonBullets;
 }
 public double getPrimaryWeaponBulletSpeed() {
  return cannonBulletSpeed;
 }
 
}


Now we have the playfield, scrolling environment, enemies, bullets, player and the input. What's left to do is to put it all together.

No comments:

Post a Comment