TFGGame/src/tfg/AnimatedSprite.java

173 lines
5.1 KiB
Java

package tfg;
import org.jsfml.graphics.IntRect;
import org.jsfml.graphics.Sprite;
import org.jsfml.system.Vector2f;
import org.jsfml.system.Vector2i;
/**
* A sprite that supports animation.
* @author Ritchie Cunningham
*/
public class AnimatedSprite {
/**
* Speed of animation in Hz.
*/
private final float animationSpeed = 15;
/**
* The frame (stage) in the animation.
*/
private int animationFrame = 0;
/**
* Keeps track of time between frame changes.
*/
private int frameCounter = 0;
/**
* Whether or not the sprite is currently animated.
*/
private boolean animating = false;
/**
* The position at which the sprite is rendered.
*/
private Vector2f spritePosition = new Vector2f(0,0);
/**
* The sprite to animate.
*/
private Sprite animatedSprite;
/**
* Location of the entity this sprite represents.
*/
private Location entityLoc;
/**
* Size of the sprite.
*/
private final Vector2i spriteSize = new Vector2i(32, 48);
/**
* Create a new animated sprite.
* @param s The sprite to animate.
* @param l The location of the entity the sprite represents.
*/
public AnimatedSprite(Sprite s, Location l) {
animatedSprite = s;
entityLoc = l;
}
/**
* Start the animation.
*/
public void startWalkingAnimation() {
startAnimation();
}
/**
* Update animation.
*/
public void animate() {
if(animating) { /* Then update animation. */
if(frameCounter >= animationSpeed) { /* If 15Hz has passed. */
stopAnimation();
} else {
/* Get the position between old and new. */
spritePosition = entityLoc.interpolate(animationSpeed, frameCounter);
Vector2i entityPos = entityLoc.getPosition(); /* Get the entity position. */
/* Subtract new position from starting position to get a number from 0.0 - 1.0. */
Vector2f animationProgress =
Vector2f.sub(spritePosition, new Vector2f(entityPos.x,entityPos.y));
/* Take the abs value because we're measuring distance. */
float change = Math.abs(animationProgress.x+animationProgress.y);
/* Determine frame based on position. */
if(change >= 0.f && change < .25f) {
animationFrame = 0;
} else if(change >= .25f && change < .5f) {
animationFrame = 1;
} else if(change >=.5f && change < .75f) {
animationFrame = 2;
} else if(change >= .75f && change <= 1.0f) {
animationFrame = 3;
}
}
frameCounter++; /* Increment on each update to keep track of time. */
}
}
/**
* Stop the animation.
*/
private void stopAnimation() {
/* Reset the following. */
animating = false;
frameCounter = 0;
animationFrame = 0;
}
/**
* Start the animation.
*/
private void startAnimation() {
animating = true;
}
/**
* Determine whether or not the animation completed.
* @return If the animation finished.
*/
public boolean finishedAnimating() {
return !animating;
}
/**
* Update the entity position.
* @param l The new location.
*/
public void updatePosition(Location l) {
entityLoc = l; /* Update the entity lcoation. */
Vector2i entityPos = entityLoc.getPosition(); /* Get Pos from last location. */
spritePosition = new Vector2f(entityPos.x, entityPos.y); /* Update sprite pos. */
}
/**
* Get the animated sprite to draw it.
* @return The anumated sprite.
*/
public Sprite getSprite() {
/* Set texture based on direction and animation frame. */
animatedSprite.setTextureRect(getTextureCoords());
/* Set sprite position */
animatedSprite.setPosition(new Vector2f(spritePosition.x * spriteSize.x,
(spritePosition.y*spriteSize.x)-(spriteSize.y-spriteSize.x)));
return animatedSprite;
}
private IntRect getTextureCoords() {
int topX = animationFrame * 32; /* x coord of the image. */
int topY = 0; /* Top y coord of the image. */
/* Match the correct image to the direction. */
switch(entityLoc.getDirection()) {
case NORTH:
topY = 144;
break;
case SOUTH:
topY = 0;
break;
case EAST:
topY = 96;
break;
case WEST:
topY = 48;
break;
}
/* Create and return an int rectangle. */
IntRect textureCoordsRect = new IntRect(topX, topY, spriteSize.x, spriteSize.y);
return textureCoordsRect;
}
/**
* Get the size of the sprite as a vector.
* @return Integer vector containing the sprite size.
*/
public Vector2i getSpriteSize() {
return spriteSize;
}
}