Package com.mlarktar.spacewar.sprites

Source Code of com.mlarktar.spacewar.sprites.Ship

/*
*  This file is part of jSpaceWar.
*
*  jSpaceWar is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  jSpaceWar is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with jSpaceWar.  If not, see <http://www.gnu.org/licenses/>.
*/
package com.mlarktar.spacewar.sprites;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

import com.mlarktar.spacewar.Parameters;
import com.mlarktar.spacewar.SoundEvents;
import com.mlarktar.spacewar.Space;

/**
* @author malar
*
* This class is the main class for the spaceships. It controls all the aspects
* of its movements, velocity and angle.
*/
public class Ship extends SpaceItem implements ActionListener {
  public static final int SHIPSIZE =
    Integer.parseInt(
      Parameters.getParameters().getProperty("ship.shipsize", "20"));
  public static final int MAXLEVEL =
    Integer.parseInt(
      Parameters.getParameters().getProperty("ship.maxlevel", "200"));
  public static final int SHIPHITPOINTS =
    Integer.parseInt(
      Parameters.getParameters().getProperty("ship.shiphitpoints", "20"));
  public static final int HYPERCOST =
    Integer.parseInt(
      Parameters.getParameters().getProperty("ship.hypercost", "8"));
  public static final int CLOAKCOST =
    Integer.parseInt(
      Parameters.getParameters().getProperty("ship.cloakcost", "1"));
  public static final double TURNSHIP =
    Double.parseDouble(
      Parameters.getParameters().getProperty("ship.turnship", "0.2"));
  public static final int PANICLEVEL =
    Integer.parseInt(
      Parameters.getParameters().getProperty("ship.paniclevel", "10"));
  public static final int ENERGYBUFFER =
    Integer.parseInt(
      Parameters.getParameters().getProperty("ship.energybuffer", "4"));
  public static final int ENERGYTOSHIELD =
    Integer.parseInt(
      Parameters.getParameters().getProperty(
        "ship.energytoshield",
        "50"));
  public static final int SHIELDTOENERGY =
    Integer.parseInt(
      Parameters.getParameters().getProperty(
        "ship.shieldtoenergy",
        "50"));
  public static final double BOOSTERSACCEL =
    Double.parseDouble(
      Parameters.getParameters().getProperty("ship.acceleration", "0.8"));

  // command constants
  public static final int CLOCKWISE = -1;
  public static final int COUNTERCLOCKWISE = 1;

  double angle;
  protected Space parent;
  private SoundEvents sounds;
  protected Ship enemy;
  private int shieldLevel = MAXLEVEL / 2;
  private int energyLevel = MAXLEVEL / 2;
  private int energyBuffer;
  private int boosterBuffer;
  private int misileBuffer;
  protected Timer timer;
  private boolean cloaking;
  private boolean doHyper;
  private boolean panic;
  private ShipRepresentation representation;

  /**
   * @return
   */
  public Space getParent() {
    return parent;
  }

  /**
   * @return true if the ship is running low on shields
   */
  public boolean isPanic() {
    /* cannot simply return panic because the ship AI or
     * the user might have solved the situation by shifting
     * energy
     */
    return shieldLevel < MAXLEVEL / 100 * PANICLEVEL;
  }

  /**
   * @return the current ship�s representation
   */
  public ShipRepresentation getRepresentation() {
    return representation;
  }

  /**
   * @param representation a class derived from ShipRepresentation
   */
  public void setRepresentation(ShipRepresentation representation) {
    this.representation = representation;
  }

  /**
   * @return current ship�s angle
   */
  public double getAngle() {
    return angle;
  }

  public Ship(int x, int y, Space parent) {
    super(x, y, 0, 0);
    this.angle = Math.atan2(vy, vx);
    this.parent = parent;
    this.timer = new Timer(500, this);
    this.sounds = new SoundEvents();
    this.representation = new ShipRepresentation();
  }

  /* Draws the spaceitem
   * @see SpaceItem#draw(java.awt.Graphics)
   */
  public void draw(Graphics g) {
    if (doHyper) {
      doHyper = false;
      Rectangle bounds = g.getClipBounds();
      x = Math.random() * bounds.width;
      y = Math.random() * bounds.height;
      sounds.playEvent(SoundEvents.HYPER);
    }
    if (!cloaking) {
      representation.draw(this, g);
    }
  }

  public void changeSpeed(double value) {
    super.changeSpeed(
      value * Math.cos(this.angle),
      value * Math.sin(this.angle));
  }

  public void engageBoosters() {
    if (energyLevel > 0) {
      ++boosterBuffer;
      if (boosterBuffer >= 5) {
        boosterBuffer = 0;
        --energyLevel;
      }
      changeSpeed(BOOSTERSACCEL);
    }
  }

  public void changeAngle(double value) {
    this.angle += value;
    final double TWOPI = Math.PI * 2;

    if (this.angle > TWOPI) {
      this.angle -= TWOPI;
    }
    if (this.angle < 0) {
      this.angle += TWOPI;
    }
  }

  public void turnShip(int direction) {
    if (Math.abs(direction) == COUNTERCLOCKWISE) {
      changeAngle(TURNSHIP * direction);
    }
  }

  public Rectangle getBounds() {
    return new Rectangle((int) x, (int) y, SHIPSIZE, SHIPSIZE);
  }

  /* Draw energy to create a misile if the energy depletes no misile can be fired
   *
   */
  public void fireMisile() {
    if (energyLevel > Misile.MISILECOST
      && misileBuffer < Misile.MISILEREPEAT) {
      --energyLevel;
      ++misileBuffer;
      Rectangle bounds = getBounds();
      parent.addSpaceItem(new Misile(this, parent));
      sounds.playEvent(SoundEvents.MISILE);
    }
  }

  /* Draw energy from the shield. If the shield energy depletes you are dead
   * @see SpaceItem#hit(SpaceItem)
   */
  public boolean hit(SpaceItem si) {
    shieldLevel -= si.getHitPoints();

    if (si.getHitPoints() >= SHIPHITPOINTS) {
      changeSpeedDelay(-vx + si.getVx(), -vy + si.getVy());
      sounds.playEvent(SoundEvents.BOUNCE);
    }

    if (shieldLevel <= 0) {
      stop();
    }

    if (!panic && shieldLevel < MAXLEVEL / 100 * PANICLEVEL) {
      panic = true;
      sounds.loopEvent(SoundEvents.AMB_FIN);
    }

    return shieldLevel <= 0;
  }

  /* A collition against a ship produces 20 hitpoints
   * @see SpaceItem#getHitPoints()
   */
  public int getHitPoints() {
    return SHIPHITPOINTS;
  }

  /**
   * @return
   */
  public int getEnergyLevel() {
    return energyLevel;
  }

  /**
   * @return
   */
  public int getShieldLevel() {
    return shieldLevel;
  }

  /* The ships energy is rechargeable. But it really does not matter much.
   * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
   */
  public void actionPerformed(ActionEvent e) {
    ++energyBuffer;
    if (misileBuffer > 0) {
      --misileBuffer;
    }
    if (energyBuffer == ENERGYBUFFER) {
      energyBuffer = 0;
      ++energyLevel;
    }
    if (cloaking && energyLevel >= CLOAKCOST) {
      energyLevel -= CLOAKCOST;
    } else {
      stopCloak();
    }
  }

  /** Fires a laser
   *
   */
  public void fireLaser() {
    if (energyLevel > LaserBeam.LASERCOST) {
      --energyLevel;
      parent.addSpaceItem(new LaserBeam(this, parent));
      sounds.playEvent(SoundEvents.LASER);
    }
  }

  /**
   *
   */
  public void shiftToEnergy() {
    if (shieldLevel > 1) {
      int shift = (int) ((double) shieldLevel / 100 * SHIELDTOENERGY);
      energyLevel += shift;
      shieldLevel -= shift;
    }
  }

  /**
   *
   */
  public void shiftToShield() {
    if (energyLevel > 1) {
      int shift = (int) ((double) energyLevel / 100 * ENERGYTOSHIELD);
      shieldLevel += shift;
      energyLevel -= shift;
    }
  }

  /**
   *
   */
  public void hyperSpace() {
    if (energyLevel > HYPERCOST) {
      energyLevel -= HYPERCOST;
      vx = 0;
      vy = 0;
      doHyper = true;
    }
  }

  public void startCloak() {
    if (energyLevel > CLOAKCOST)
      cloaking = true;
  }

  public void stopCloak() {
    cloaking = false;
  }

  public boolean isCloaked() {
    return cloaking;
  }

  /**
   * @return
   */
  public SoundEvents getSounds() {
    return sounds;
  }

  /**
   * @param events
   */
  public void setSounds(SoundEvents events) {
    sounds = events;
  }

  public Ship getEnemy() {
    return enemy;
  }

  public void setEnemy(Ship ship) {
    enemy = ship;
  }

  public void start() {
    timer.start();
  }

  public void stop() {
    if (timer != null)
      timer.stop();
  }

  public void dispose() {
    if (timer != null) {
      stop();
      timer.removeActionListener(this);
      timer = null;
    }
    parent = null;
    sounds = null;
    enemy = null;
  }
}
TOP

Related Classes of com.mlarktar.spacewar.sprites.Ship

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.