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; } }