?? actor.java
字號(hào):
import net.jscience.math.kvm.MathFP;
import javax.microedition.lcdui.*;
/**
* An abstract base class for higher level Actors. This class handles basic
* position as well as maintaining a link to the GameScreen. A class extending
* this needs to implement the render, getHeight and getWidth methods as well
* as optionally overriding other methods like cycle to implement custom logic.
* This version now maintains a reference to the World in which it belongs.
* @author Martin J. Wells.
*/
abstract public class Actor
{
public static final int FP_PI2 = MathFP.mul(MathFP.PI, MathFP.toFP(2));
public static final int FP_DEGREES_PER_RAD = MathFP.div(MathFP.toFP(360), FP_PI2);
public static final int FP_ONE = MathFP.toFP(1);
private World world; // the world this actor is within.
private int xFP, yFP; // current position (as a MathFP)
private int lastXFP, lastYFP; // last position (used by cycle code)
private int realDir; // actual direction in degrees
private int alignedDir; // aligned direction
private int alignedDivDegreesFP; // degrees per facing division
private boolean wantAlignment; // turn auto alignment on
private int spinFP; // current spin rate (can be negative)
private int maxSpinRate; // maximum spin rate (in degrees per
// second)
private int xVelFP, yVelFP; // current velocity
private int xAccFP, yAccFP; // current acceleration
private int maxVelFP;
private int thrustFP;
private int bounceVelFP; // The amount of bounce when we hit
// something.
private boolean autoSpinning; // we set a flag to avoid over calling
// setSpin()
private int targetAngle;
private long fluff = 0;
/**
* Constructs an Actor at position x, y facing direction d and setting
* a maximum velocity and starting thrust. (Note the maxVelFPArg and
* thrustFPArg both must be MathFP values.) The alignedDivArg sets the
* number of distinct angles this Actor can face. A Ship with 16 facing
* images has 16 aligned divisions, which translates to an aligned division
* of 22.5 degrees (360 divided by 16). The aligned direction is used by the
* Actor class to make sure it can only face an angle that can be drawn.
* @param worldArg The world this actor belongs in.
* @param startX The starting x position of the new Actor.
* @param startY The starting y position of the new Actor.
* @param startDirection The starting direction
* @param alignedDivArg The number of aligned angle divisions.
* @param maxVelFPArg The maximum velocity.
* @param thrustFPArg The starting thrust.
* @param speedFPArg The starting velocity.
* @param bounceVelFPArg The level of bounce when colliding with something.
* @param maxSpinRateArg The maximum turn rate in degrees per second.
*/
public Actor(World worldArg, int startX, int startY, int startDirection,
int alignedDivArg, int maxVelFPArg, int thrustFPArg,
int speedFPArg, int bounceVelFPArg, int maxSpinRateArg)
{
world = worldArg;
xFP = MathFP.toFP(startX);
yFP = MathFP.toFP(startY);
maxVelFP = maxVelFPArg;
thrustFP = thrustFPArg;
setDirection(startDirection);
wantAlignment = false;
if (alignedDivArg > 0)
{
alignedDivDegreesFP = MathFP.div(360, alignedDivArg);
wantAlignment = true;
}
maxSpinRate = maxSpinRateArg;
bounceVelFP = bounceVelFPArg;
setVel(speedFPArg);
}
/**
* Changes the current speed of the actor by setting the velocity based on
* the current (aligned) direction.
* @param speedArg The speed to travel at.
*/
public final void setVel(int speedArg)
{
xVelFP = MathFP.mul(MathFP.toFP(speedArg), MathFP.cos(getRadiansFromAngle(alignedDir)));
yVelFP = MathFP.mul(MathFP.toFP(speedArg), -MathFP.sin(getRadiansFromAngle(alignedDir)));
// If you change this remember to change the cycle code
if (xVelFP > maxVelFP)
xVelFP = maxVelFP;
else if (xVelFP < -maxVelFP) xVelFP = -maxVelFP;
if (yVelFP > maxVelFP)
yVelFP = maxVelFP;
else if (yVelFP < -maxVelFP) yVelFP = -maxVelFP;
}
/**
* Gets the world this actor is currently within.
*/
public World getWorld()
{
return world;
}
/**
* Abstract render method that must be implemented by derived classes.
* This method is intended to be called by a Actor manager (such as a
* World class) to draw Actors on the screen.
* @param graphics The graphics context upon which to draw.
* @param offsetX The amount to offset the x drawing position by.
* @param offsetY The amount to offset the y drawing position by.
*/
abstract public void render(Graphics graphics, int offsetX, int offsetY);
/**
* Gets the spin rate for this Actor in degrees per second.
* @return The current spin (turning) rate.
*/
public int getSpin()
{
return MathFP.toInt(spinFP);
}
/**
* Set the spin rate for this Actor in degrees per second.
* @param newSpin The spin rate.
*/
public void setSpin(int newSpin)
{
spinFP = MathFP.toFP(newSpin);
}
/**
* Sets this Actors spin rate to be the maximum (set in the constructor).
*/
public final void setPeakSpin()
{
spinFP = MathFP.toFP(maxSpinRate);
}
/**
* Sets this Actors spin rate to be the negative maximum (set in the
* constructor). Use this to spin the Actor backwards (counter clockwise).
*/
public final void setNegPeakSpin()
{
spinFP = MathFP.toFP(-maxSpinRate);
}
/**
* Set an angle this actors wants to face; the actor will start spinning
* at its default spin rate towards the target angle - see cycle for
* the actual spin code.
*/
public final void setTargetDirection(int angle)
{
targetAngle = angle;
autoSpinning = false;
}
/**
* A cycle method that moves the Actor a distance relative to its current
* speed (the value of the speed int) and the amount of time that has passed
* since the last call to cycle (deltaMS). This code uses a fluff value in
* order to remember values too small to handle (below the tick level).
* @param deltaMS The number of milliseconds that have passed since the last
* call to cycle.
*/
public void cycle(long deltaMS)
{
int ticks = (int) (deltaMS + fluff) / 100;
// remember the bit we missed
fluff += (deltaMS - (ticks * 100));
if (ticks > 0)
{
int ticksFP = MathFP.toFP(ticks);
// move towards our target direction, if we have one
if (targetAngle != 0)
{
if (!autoSpinning)
{
// start spin in the dir of the target angle
setSpin(isClockwise(getDirection(),
targetAngle) ? -maxSpinRate : maxSpinRate);
}
// and check if we've made it to the target direction
if (getAlignedDirection(targetAngle) == getDirection())
{
setSpin(0);
setTargetDirection(0);
autoSpinning = false;
}
}
// spin based on degrees per tick
if (spinFP != 0)
setDirection(getRealDirection() +
MathFP.toInt(MathFP.mul(ticksFP, spinFP)));
// move based on our speed in pixels per ticks
if (thrustFP != 0)
{
// Calculate the acceleration for this cycle by multiplying the
// direction by the thrust on both x and y.
xAccFP = MathFP.mul(thrustFP,
MathFP.cos(getRadiansFromAngle(alignedDir)));
yAccFP = MathFP.mul(thrustFP,
-MathFP.sin(getRadiansFromAngle(alignedDir)));
// Increase the velocity by the amount of acceleration in this
// cycle.
xVelFP = MathFP.add(xVelFP, xAccFP);
yVelFP = MathFP.add(yVelFP, yAccFP);
}
// Fix the velocity to the maximum if it currently exceeds it.
if (xVelFP > maxVelFP)
xVelFP = maxVelFP;
else if (xVelFP < -maxVelFP) xVelFP = -maxVelFP;
if (yVelFP > maxVelFP)
yVelFP = maxVelFP;
else if (yVelFP < -maxVelFP) yVelFP = -maxVelFP;
// Remember previous values
lastXFP = xFP;
lastYFP = yFP;
// Adjust x
xFP = MathFP.add(xFP, MathFP.mul(xVelFP, ticksFP));
// Check if we collided with anything after the x movement
if (world.checkCollision(this))
{
xVelFP = MathFP.mul(xVelFP, bounceVelFP);
xFP = MathFP.add(lastXFP, xVelFP);
}
// Adjust Y. This code also handles a special case where the x
// collision may have caused the Actor to move (such as colliding with
// a teleport or level gateway). In this case our lastYFP is invalid
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -