?? ship.java
字號:
import net.jscience.math.kvm.MathFP;
import javax.microedition.lcdui.*;
import java.io.IOException;
/**
* Class to handle the drawing and movement of a little spaceship. Image is
* loaded in a Sprite from the ship.png file. This version adds a red version
* of the ship (the graphics for that are also in ship.png)
* @author Martin J. Wells
*/
public class Ship extends Actor
{
private static int SHIP_FRAME_WIDTH = 16;
private static int SHIP_FRAME_HEIGHT = 16;
private static final int ENEMY_IGNORE_DISTANCE = 100;
public static final int FP_22P5 = MathFP.toFP("22.5");
private static ImageSet playerShipImageSet;
private static ImageSet enemyShipImageSet;
private Sprite shipSprite;
private long msSinceLastAIUpdate; // The time since we last engaged the
// brain
private long msPerAIUpdate = 200; // Delay to run the brain code; since
// it's a slow thing to do we don't
// want it running every cycle.
private boolean isEnemy;
// Weapons fire.
private boolean firing; // Is the ship currently firing?
private int firingDelay=500; // The delay between shots (in ms)
private long timeLastFired; // Used to track when I can fire again
/**
* Constructs a new ship starting at a position with a default maximum
* velocity of 2 and thrust of 0.2.
* @param worldArg The world this actor is in.
* @param startX The starting x position.
* @param startY The starting y position.
*/
public Ship(World worldArg, boolean isEnemyArg, int startX, int startY)
{
super(worldArg, startX, startY, 0, 16, MathFP.toFP("2.0"), MathFP.toFP("0.2"),
0, MathFP.toFP("-0.8"), 23);
if (playerShipImageSet == null)
{
try
{
Image shipGraphic = Image.createImage("/ship.png");
// Extract out the image frames for the player ship.
Image[] playerShipFrames = ImageSet.extractFrames(shipGraphic,
0, 0, 4, 4, SHIP_FRAME_WIDTH, SHIP_FRAME_HEIGHT);
playerShipImageSet = new ImageSet(1);
playerShipImageSet.addState(playerShipFrames, 0);
// Extract out the image frames for the enemy ship. The red fighter
// frames start 4 frames across in the file (4 * 16).
Image[] enemyShipFrames = ImageSet.extractFrames(shipGraphic,
4*16, 0, 4, 4, SHIP_FRAME_WIDTH, SHIP_FRAME_HEIGHT);
enemyShipImageSet = new ImageSet(1);
enemyShipImageSet.addState(enemyShipFrames, 0);
}
catch (IOException ioe)
{
System.out.println("unable to load image");
}
}
// Set the ship sprite based on the type. If it's an enemy we use the
// red ship frames.
isEnemy = isEnemyArg;
if (isEnemy)
shipSprite = new Sprite(enemyShipImageSet, 0, 0);
else
shipSprite = new Sprite(playerShipImageSet, 0, 0);
}
/**
* Fires a Bullet by projecting a point just beyond the front of the Ship
* and then constructs a new Bullet facing the same direction as the Ship.
*/
public void fire()
{
int[] nosePos = Actor.getProjectedPos(getX()+ (SHIP_FRAME_WIDTH/2),
getY()+ (SHIP_FRAME_HEIGHT/2),
getDirection(), 12);
getWorld().addActor( new Bullet(getWorld(), nosePos[0], nosePos[1],
getDirection()) );
}
/**
* Cycling for the Ship calls Actor.cycle to handle movement. It then checks
* to see if this is an enemy type ship and updates the direction based on
* the relative angle of the player's ship from the the enemy one.
* @param deltaMS The amount of time that has passed since the last cycle
* (in milliseconds).
*/
public void cycle(long deltaMS)
{
super.cycle(deltaMS);
if (isEnemy)
{
// If insufficient time has passed to do an AI update we just add the
// deltaMS time to the counter. If enough time has passed it executes
// the Enemy AI code (this is only done periodically since it's
// typically expensive stuff you don't want to do every frame).
if (msSinceLastAIUpdate < msPerAIUpdate)
msSinceLastAIUpdate += deltaMS;
else
{
msSinceLastAIUpdate -= msPerAIUpdate; // take off one update's worth
// Calculate the distance to the player so we ignore cases where
// the player is too far away to bother with.
Ship playerShip = GameScreen.getGameScreen().getPlayerShip();
int d = distanceTo(playerShip);
if (d < ENEMY_IGNORE_DISTANCE)
{
// Figure out the angle we need to face to fly directly towards
// the player's ship.
int facingAngle = getFacingAngle(getX(), getY(), playerShip.getX(),
playerShip.getY());
// Set this to be our target direction. The Actor.cycle method
// will take care of turning this ship until it faces the target
// angle we set here.
setTargetDirection(facingAngle);
}
}
}
if (firing)
{
// Calculate the amount of time that has passed. If it's greater than
// the firing delay then the Ship is clear to fire again.
long timeSinceLastFire = (System.currentTimeMillis() - timeLastFired);
if (timeSinceLastFire > firingDelay)
{
int[] nosePos = Actor.getProjectedPos(getX()+ (SHIP_FRAME_WIDTH/2),
getY()+ (SHIP_FRAME_HEIGHT/2),
getDirection(), 12);
// Add the new bullet actor to our world.
getWorld().addActor( new Bullet(getWorld(), nosePos[0], nosePos[1],
getDirection()) );
// Update the time the last fire took place (now).
timeLastFired = System.currentTimeMillis();
}
}
}
public final void setFiring(boolean b)
{
firing = b;
}
/**
* Actor render method to draw the ship. In this code we set the frame
* corresponding to the direction the ship is facing. Note that the
* shipSprite is either a red or yellow ship based on the type specified
* in the constructor.
* @param graphics The graphics context upon which to draw the sprite frame.
* @param offsetX The amount to offset the x drawing position by.
* @param offsetY The amount to offset the y drawing position by.
*/
public void render(Graphics graphics, int offsetX, int offsetY)
{
int frame = MathFP.toInt(MathFP.div(MathFP.toFP(getDirection()),
FP_22P5));
shipSprite.setFrame(frame);
shipSprite.draw(graphics, getX()-offsetX, getY()-offsetY);
}
public int getHeight()
{
return SHIP_FRAME_HEIGHT;
}
public int getWidth()
{
return SHIP_FRAME_WIDTH;
}
/**
* @return The x position of the center of the ship
*/
public int getCenterX()
{
return getX() + getWidth() / 2;
}
/**
* @return The y position of the center of the ship
*/
public int getCenterY()
{
return getY() + getHeight() / 2;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -