package com.arretadogames.pilot.render; import android.graphics.RectF; import com.arretadogames.pilot.render.opengl.GLCanvas; /** * Animation class<br> * A container to hold several sprites that together makes an Animation, all * sprites have a time that the frame lasts. This class is also a manager to * draw frames based on time. */ public class Animation { private static RectF auxRect = new RectF(); private String name; private Sprite[] sprites; private boolean repeat; private float animationRate = 1; private int currentKeyFrameIndex = -1; private float currentFrameTimeLeft = 0; public Animation(String name, Sprite[] sprites) { this.name = name; this.currentKeyFrameIndex = 0; this.sprites = sprites; this.currentFrameTimeLeft = sprites[currentKeyFrameIndex].getTime(); this.repeat = true; // Default } public void setRepeat(boolean repeat) { this.repeat = repeat; } public boolean isRepeatable() { return this.repeat; } public String getName() { return this.name; } public void render(GLCanvas canvas, PhysicsRect phyRect, float timeElapsed) { // Prepare rect to draw auxRect.left = phyRect.left * GLCanvas.physicsRatio; auxRect.top = phyRect.top * GLCanvas.physicsRatio; auxRect.right = phyRect.right * GLCanvas.physicsRatio; auxRect.bottom = phyRect.bottom * GLCanvas.physicsRatio; render(canvas, auxRect, timeElapsed); } public void render(GLCanvas canvas, RectF rect, float timeElapsed) { // Figure out which frame is currently selected if (sprites[currentKeyFrameIndex].getTime() > 0) { float currentTimeElapsed = timeElapsed * animationRate; while (currentTimeElapsed > 0) { float timeElapsedBefore = currentTimeElapsed; currentTimeElapsed -= currentFrameTimeLeft; currentFrameTimeLeft -= timeElapsedBefore; if (currentFrameTimeLeft < 0) { // Frame Expired nextFrame(); if (currentFrameTimeLeft == 0) break; // if frame is suppose to be infinite } } } // Draw canvas.drawBitmap(sprites[currentKeyFrameIndex].getSourceSheet(), sprites[currentKeyFrameIndex].getFrameRect(), rect); } public void resetIfInfinite() { if (currentFrameTimeLeft == 0) { this.currentKeyFrameIndex = 0; this.currentFrameTimeLeft = sprites[currentKeyFrameIndex].getTime(); } } private void nextFrame() { currentKeyFrameIndex++; if (currentKeyFrameIndex >= sprites.length) { if (repeat) { currentKeyFrameIndex = 0; currentFrameTimeLeft = sprites[currentKeyFrameIndex].getTime(); } else { currentFrameTimeLeft = 0; // Keep infinite time currentKeyFrameIndex = sprites.length - 1; // The last frame } } else { currentFrameTimeLeft = sprites[currentKeyFrameIndex].getTime(); } } public void setAnimationRate(float multiplier) { animationRate = multiplier; } @Override protected Animation clone() { Animation an = new Animation(name, sprites); setRepeat(repeat); return an; } public float getTotalDuration() { float totalDuration = 0; for (Sprite s : sprites) { totalDuration += s.getTime(); } return totalDuration; } }