📄 ship.java
字号:
/**
* An Actor that moves and turns like a spaceship.
*/
import net.jscience.math.kvm.MathFP;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
public class Ship extends Actor
{
private static ImageSet yellowShipImageSet;
private static ImageSet redShipImageSet;
private static ImageSet droneSet;
private static ImageSet shieldImageSet;
private static ImageSet turretImageSet;
private static ImageSet explosionSet;
private static final int ENEMY_IGNORE_DISTANCE = 70;
// ship instance
private Sprite shipSprite; // ship sprite graphics (this image is
// different based on the type above
private Sprite shieldSprite; // shielding effects (same for all)
private boolean firing; // am I firing?
private long timeLastFired; // used to track when I can fire again
private boolean showShields; // are my shields showing?
private int energy; // current reactor core energy level
private int energyMax; // max level
private int rechargeRate; // recharge rate (energy per sec)
private int msPerRecharge; // how many MS to equal one recharge
private long msSinceLastRecharge; // multicycle counter for recharge
private int firingDelay; // reload time
private boolean exploding; // death becomes me
private Sprite explodingSprite; // exploding animation
private int msPerAIUpdate; // how many MS to equal one AI update
private long msSinceLastAIUpdate; // multicycle counter for AI update
public Ship(World worldArg)
{
super(worldArg);
if (yellowShipImageSet == null)
{
System.out.println("oops, ship used but imageset not initialized.");
return;
}
shieldSprite = new Sprite(shieldImageSet, 0, 0);
explodingSprite = new Sprite(explosionSet, 0, 0);
}
/**
* Used as the ending warp tunnel graphics as well
*/
public final static ImageSet getShieldImageSet()
{
return shieldImageSet;
}
public static ImageSet getYellowShipImageSet()
{
return yellowShipImageSet;
}
/**
* Initialise an instance of a ship. May be called at any time to reuse this
* instance of the object as another type.
* @param typeArg
*/
public final void init(int typeArg, int x, int y)
{
energy = energyMax;
exploding = false;
showShields = false;
firing = false;
firingDelay = 500;
int alignedDiv = 16;
int thrustFP = 0;
int speed = 0;
int maxVel = 0;
int dir = 0;
int bounceVelFP = Actor.FP_MINUS_05;
int maxSpinRate = 23;
energyMax = 1000;
energy = energyMax;
rechargeRate = 50;
setType(typeArg);
switch (getType())
{
case PLAYER_SHIP:
shipSprite = new Sprite(yellowShipImageSet, 0, 0);
speed = 2;
maxVel = 2;
thrustFP = MathFP.toFP("1.0");
firing = StarAssault.getApp().isOptionAutoFire();
break;
case ENEMY_FIGHTER:
shipSprite = new Sprite(redShipImageSet, 0, 0);
speed = 1;
maxVel = 1;
thrustFP = MathFP.toFP("0.5");
firing = true;
firingDelay = 2000;
break;
case ENEMY_DRONE:
shipSprite = new Sprite(droneSet, 0, 0);
alignedDiv = 0;
dir = Tools.getRand(0, 359);
speed = maxVel = 1;
thrustFP = 0;
bounceVelFP = Actor.FP_MINUS_1;
break;
case ENEMY_TURRET:
rechargeRate = 0;
speed = 0;
maxSpinRate = 5;
energyMax = 200;
firingDelay = 2000;
shipSprite = new Sprite(turretImageSet, 0, 0);
firing = true;
break;
}
// ship settings
if (rechargeRate > 0)
msPerRecharge = 1000 / rechargeRate;
msPerAIUpdate = 1000;
reset();
super.init(null, x, y, thrustFP, MathFP.toFP(speed),
MathFP.toFP(maxVel), dir, alignedDiv, bounceVelFP, maxSpinRate);
}
public final static void setup()
{
Image shipImage = ImageSet.loadClippedImage("/ship.png", 0, 0);
Image explosionImage = ImageSet.loadClippedImage("/explode.png", 0, 0);
Image droneImage = ImageSet.loadClippedImage("/mine.png", 0, 0);
yellowShipImageSet = new ImageSet(16);
redShipImageSet = new ImageSet(16);
turretImageSet = new ImageSet(16);
shieldImageSet = new ImageSet(1);
explosionSet = new ImageSet(1);
droneSet = new ImageSet(1);
Image[] yellowDirImages = null;
Image[] redDirImages = null;
Image[] shieldImages = null;
Image[] turretImages = null;
Image[] explosionImages = ImageSet.extractFrames(explosionImage, 0, 0, 1, 4, 25, 25);
explosionSet.addState(explosionImages, 500);
Image[] droneImages = ImageSet.extractFrames(droneImage, 0, 0, 3, 2, 16, 16);
droneSet.addState(droneImages, 800);
//#ifdef nokia
//# yellowDirImages = ImageSet.extractFrames(shipImage, 0, 0, 5, 1, 16, 16);
//# yellowDirImages = ImageSet.getAxisReflections(yellowDirImages);
//# redDirImages = ImageSet.extractFrames(shipImage, 0, 16, 5, 1, 16, 16);
//# redDirImages = ImageSet.getAxisReflections(redDirImages);
//# turretImages = ImageSet.extractFrames(shipImage, 0, 3 * 16, 5, 1, 16, 16);
//# turretImages = ImageSet.getAxisReflections(turretImages);
//# shieldImages = ImageSet.extractFrames(shipImage, 0, 2 * 16, 4, 1, 16, 16);
//#else
yellowDirImages = ImageSet.extractFrames(shipImage, 0, 0, 4, 4, 16, 16);
redDirImages = ImageSet.extractFrames(shipImage, 4 * 16, 0, 4, 4, 16, 16);
turretImages = ImageSet.extractFrames(shipImage, 8 * 16, 0, 4, 4, 16, 16);
shieldImages = ImageSet.extractFrames(shipImage, 0, 4 * 16, 4, 1, 20, 20);
//#endif
// add the 16 states for the ship (representing the 16 directions)
for (int i = 0; i < 16; i++)
{
Image[] yellowFrame = {yellowDirImages[i]};
yellowShipImageSet.addState(yellowFrame, 0);
Image[] redFrame = {redDirImages[i]};
redShipImageSet.addState(redFrame, 0);
Image[] turretFrame = {turretImages[i]};
turretImageSet.addState(turretFrame, 0);
}
shieldImageSet.addState(shieldImages, 200);
}
public final int getWidth()
{
//#ifdef nokia
//# return 14;
//#else
return 16;
//#endif
}
public final int getHeight()
{
return getWidth();
}
public final void setFiring(boolean b)
{
firing = b;
}
public boolean isExploding()
{
return exploding;
}
public final void onCollision(Actor a)
{
if (a == null) return;
if (a.getOwner() != this)
{
if (a.isBullet())
{
Bullet b = (Bullet) a;
takeDamage(b.getDamage());
a.setCollidable(false);
}
}
// if we hit an enemy ship, then blow up the ship and cause
// damage to the player
if (!a.isBullet())
{
takeDamage(250);
}
if (this.getType() != PLAYER_SHIP)
{
exploding = true;
setCollidable(false);
// add to the score
GameScreen.getGameScreen().incScore(100);
}
}
public final void takeDamage(int damageLevel)
{
//#ifdef debug
// disable damage when debugging
//if (this.getType() == PLAYER_SHIP) return;
//#endif
energy -= damageLevel;
showShields = true;
if (energy < 0)
{
exploding = true;
showShields = false;
}
}
public final int getEnergy()
{
return energy;
}
public final int getEnergyMax()
{
return energyMax;
}
public final void cycle(long deltaMS)
{
super.cycle(deltaMS);
if (getType() == ENEMY_DRONE)
shipSprite.cycle(deltaMS);
if (exploding)
{
explodingSprite.cycle(deltaMS);
if (explodingSprite.getTotalCycles() > 0)
{
explodingSprite.reset();
if (getType() != PLAYER_SHIP)
suicide();
GameScreen.getGameScreen().notifyShipDied(this);
}
}
if (rechargeRate > 0 && energy < energyMax)
{
if (msSinceLastRecharge < msPerRecharge)
{
msSinceLastRecharge += deltaMS;
}
else
{
energy++;
msSinceLastRecharge -= msPerRecharge;
if (energy > energyMax) energy = energyMax;
}
}
if (showShields)
{
shieldSprite.cycle(deltaMS);
if (shieldSprite.getTotalCycles() > 0)
{
shieldSprite.reset();
showShields = false;
}
}
if (firing)
{
long timeSinceLastFire = (System.currentTimeMillis() - timeLastFired);
if (timeSinceLastFire > firingDelay)
{
int[] nosePos = Actor.getProjectedPos(getCenterX(), getCenterY(),
getDirection(), 12);
// get a bullet from the pool and init it to what we want
Bullet b = getWorld().getBulletFromPool();
b.init(Bullet.PLASMA_CANNON, this, nosePos[0], nosePos[1], getDirection());
timeLastFired = System.currentTimeMillis();
}
}
// do we have a brain?
if (getType() > ENEMY_AI_START)
{
// keep the update rate on the AI brain down to a minimum
if (msSinceLastAIUpdate < msPerAIUpdate)
msSinceLastAIUpdate += deltaMS;
else
{
msSinceLastAIUpdate -= msPerAIUpdate; // take off one update's worth
// check the distance to the player
int d = distanceTo(world.getPlayerShip());
if (d < ENEMY_IGNORE_DISTANCE && d > 0)
{
// they are within distance so lets turn toward them
int facingAngle = getFacingAngle(getX(), getY(), world.getPlayerShip().getX(),
world.getPlayerShip().getY());
//System.out.println(" xd=" + (getX() - world.getPlayerShip().getX()) +
// " yd=" + (getY() - world.getPlayerShip().getY()) +
// " angle=" + facingAngle);
setTargetDirection(facingAngle);
}
}
}
}
public final void suicide()
{
world.releaseShip(this);
}
public final void reset()
{
super.reset();
exploding = false;
energy = energyMax;
showShields = false;
}
public final void render(Graphics g, int offsetX, int offsetY)
{
if (exploding)
{
explodingSprite.draw(g, getX() - offsetX - 2, getY() - offsetY - 2);
}
else
{
// for non-transparent graphics we show a larger version of the shields
// under the ship (which has a slightly different visual effect)
//#ifndef nokia
if (showShields)
shieldSprite.draw(g, getX() - offsetX - 2, getY() - offsetY - 2);
//#endif
if (getType() != ENEMY_DRONE)
{
int s = MathFP.toInt(MathFP.div(MathFP.toFP(getDirection()), Actor.FP_225));
if (s != shipSprite.getCurrentState())
shipSprite.setState(s, false);
}
shipSprite.draw(g, getX() - offsetX, getY() - offsetY);
// with nokia we show the shields over the top of the ship
//#ifdef nokia
//# if (showShields)
//# shieldSprite.draw(g, getX() - offsetX, getY() - offsetY);
//#endif
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -