import java.awt.*;
import java.lang.Math;
/** A HardlySprite that "points" to specific directions. It's expected you'll provied a Sequence that shows the
image rotated to point in appropriate directions (start out facing due right and progress in even angular
increments). PointSprites can either point in their current direction of movement or have a pointing direction
assigned to them through calls to setPointing().
*/
public class PointSprite extends HardlySprite {
Sequence spriteSeq;
int segments;
float arc;
boolean pointsToDirection = true;
static final float TWOPI = (float) (2 * Math.PI);
/** Creates a PointSprite, which can either point in the current direction of the sprite, or point in an arbitrary direction.
@param spriteSeq Sequence of images with all available directions. The first should point right (0 radians).
@param world SpriteWorld which contains the sprite
@param x Inital x-coordinate, in pixels
@param y Initial y-coordinate, in pixels
@param direction Initial direction, in radians, with 0 as due right
@param speed Initial speed, in pixels-per-second
@param behavior true if PointSprite should always point to current direction of movement, false if it
should not... ie, if the calling applet or another class will control the image with calls to setPointing()
*/
public PointSprite (Sequence spriteSeq, SpriteWorld world,
int x, int y,
float direction, float speed, boolean behavior) {
super (spriteSeq.imageAt(0), world, x, y, direction, speed);
this.spriteSeq = spriteSeq;
segments = spriteSeq.getLength();
arc = TWOPI / segments;
pointsToDirection = behavior;
if (pointsToDirection) {
changeImage (spriteSeq.imageAt ( whichSegment (direction)));
}// if
} // main constructor
/** Determines which image in the Sequence should be used. A PointSprite has an arc, determined by dividing
2 PI (ie, 360 degrees) by the number of images in the Sequence. For example, an 8-frame sequence has arcs of
45 degrees each. Pointed images are centered within this arc. Therefore, the first image, painted to face due right,
handles directions from 337.5 degrees (ie, -22.5) to 22.5. The next image is used from 22.5 degrees to 67.5, etc.
@param angle The angle to point towards, in radians
@return The index of the correct image in the Sequence
*/
private final int whichSegment (float angle) {
if (angle <= arc/2) return 0;
if (angle >= (TWOPI - arc/2)) return 0;
return (int) ((angle + arc/2) / arc);
} // whichSegment
/** Calls HardlySprite's setDirection, then changes the PointSprite's image to point in the current direction of
movement IF the PointSprite was set to do so when constructed.
@param direction Sprite's new movement direction in radians
*/
public final void setDirection (float direction) {
super.setDirection (direction);
if (pointsToDirection) {
changeImage (spriteSeq.imageAt ( whichSegment (direction)));
}// if
} // setDirection - radians
/** Calls HardlySprite's setDirection, then changes the PointSprite's image to point in the current direction of
movement IF the PointSprite was set to do so when constructed.
@param direction Sprite's new movement direction in degrees
*/
public final void setDirection (int degrees) {
super.setDirection (degrees);
if (pointsToDirection) {
changeImage (spriteSeq.imageAt ( whichSegment (degrees * TWOPI / 360)));
}// if
} // setDirection - degrees
/** Changes the sprite's image to point to the specified direction
@param direction The direction to point towards, in radians
*/
public final void setPointing (float direction) {
changeImage (spriteSeq.imageAt ( whichSegment (direction)));
} // setPointing - radians
/** Changes the sprite's image to point to the specified direction
@param degrees The direction to point towards, in degrees
*/
public final void setPointing (int degrees) {
changeImage (spriteSeq.imageAt ( whichSegment (degrees * TWOPI / 360)));
} // setPointing - degrees
/** Changes the Sequence used by this sprite. Notes its new arc and size, and changes onscreen image. Known
issue: image is changed to point in current direction, regardless of pointsToDirection value. For now, if you're
pointing to something other than the current movement direction, immediately call setPointing() after calling
changeSequence()
@param newSequence The new Sequence this sprite is to use
*/
public final void changeSequence (Sequence newSequence) {
spriteSeq = newSequence;
segments = spriteSeq.getLength();
arc = TWOPI / segments;
// note -- the next line assumes sprites point current direction after changeSequence. need to
// determine what to do if caller assumes responsibility for pointing and yet calls changeSequence!
changeImage (spriteSeq.imageAt ( whichSegment (this.getDirection())));
width = spriteImage.getWidth(world);
height = spriteImage.getWidth(world);
} // changeSequence
/** Calls HardlySprite's updatePosition() and adds no functionality. This version is final, in hopes of
restoring speed lost by making superclass' updatePosition() overridable.
*/
public final boolean updatePosition () {
super.updatePosition();
return true;
} // non-overridden updatePosition. I hope finalizing here will restore speed. AnimateSprite does a "real" override
} /* PointSprite */