/*********************************************************************** * mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * ***********************************************************************/ package org.mt4j.util.animation; import java.util.ArrayList; /** * The Class Animation. * @author Christopher Ruff */ public class Animation implements IAnimationManagerListener{ /** The name. */ private String name; /** The interpolator. */ private Iinterpolator interpolator; /** The target object. */ private Object targetObject; /** The animation listeners. */ private ArrayList<IAnimationListener> animationListeners; /** The reset on finish. */ private boolean resetOnFinish; /** The trigger time. */ private long triggerTime; /** The trigger count down. */ private long triggerCountDown; /** The has started. */ private boolean hasStarted; /** * Instantiates a new animation. * * @param name the name * @param interpolator the interpolator * @param targetObject the target object */ public Animation(String name, Iinterpolator interpolator, Object targetObject) { this(name, interpolator, targetObject, 0); } /** * creates a new Animation object with the given interpolator. * <br> if animating a concrete object, the targetObject should * be passed as a parameter. If the Animation has no concrete target * "null" can be passed * * @param name the name * @param interpolator the interpolator * @param targetObject the target object * @param triggerTime the trigger time */ public Animation(String name, Iinterpolator interpolator, Object targetObject, int triggerTime) { super(); this.resetOnFinish = true; //Default this.name = name; this.interpolator = interpolator; this.targetObject = targetObject; animationListeners = new ArrayList<IAnimationListener>(); this.triggerTime = triggerTime; this.triggerCountDown = triggerTime; this.hasStarted = false; } // /** // * makes this animation object fire an animation event, // * should ony get called by the AnimationManager class // * @param e // */ // public void postEvent(AnimationEvent e){ // fireAnimationEvent(e); // // if (e.getId() == AnimationEvent.ANIMATION_ENDED){ // this.setEnabled(false); // if (this.isResetOnFinish()) // this.getInterpolator().resetInterpolator(); //// System.out.println("Animation FINISHED: " + this.getName()); // } // } /** * Start. */ public void start(){ if (this.getInterpolator().isFinished()){ System.err.println("Animation: " + this.getName() + " has finished! To start it again, call restart() or set Animation.setResetOnFinish(true)"); return; } AnimationManager.getInstance().addAnimation(this); AnimationManager.getInstance().addAnimationManagerListener(this); // System.out.println("Animation STARTED: " + this.getName()); // fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_STARTED, this, this.getTargetObject())); } /** * Restart. */ public void restart(){ this.getInterpolator().resetInterpolator(); this.triggerCountDown = this.getTriggerTime(); this.hasStarted = false; AnimationManager.getInstance().addAnimation(this); AnimationManager.getInstance().addAnimationManagerListener(this); // System.out.println("Animation RESTARTED: " + this.getName()); // fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_STARTED, this, this.getTargetObject())); } /** * Stop. */ public void stop(){ AnimationManager.getInstance().removeAnimation(this); AnimationManager.getInstance().removeAnimationManagerListener(this); // System.out.println("Animation FINISHED: " + this.getName()); //TODO fire? // fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_ENDED, this, this.getTargetObject())); } /** * Interface method of IAnimationManagerListener * <br>used to update the anmation (interpolate) with a given timedelta. * * @param ev the ev */ public void updateAnimation(AnimationUpdateEvent ev) { //System.out.println("animating " + a.getName()); if (triggerTime != 0){//If trigger is set triggerCountDown -= ev.getDeltaTime(); //if !<0? if (triggerCountDown <= 0){ //if trigger abgelaufen //Interpoliere mit neuerm zeitdelta auf neuen wert interpolator.interpolate(ev.getDeltaTime()); if (!interpolator.isFinished()){ if (!hasStarted){ hasStarted = true; this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_STARTED, this, this.getTargetObject())); }else{ this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_UPDATED, this, this.getTargetObject())); } }else{ //FIXME wenn gefinished, sollte der interpolator bei lastStepdelta und 0 zur�ckgeben, oder?? this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_ENDED, this, this.getTargetObject())); AnimationManager.getInstance().removeAnimation(this); AnimationManager.getInstance().removeAnimationManagerListener(this); this.triggerCountDown = this.getTriggerTime(); if (this.isResetOnFinish()){ this.getInterpolator().resetInterpolator(); this.triggerCountDown = this.triggerTime; this.hasStarted = false; } } }//if triggetcount not up, do nothing }else{//If no trigger is set interpolator.interpolate(ev.getDeltaTime()); if (!this.interpolator.isFinished()){ if (!this.hasStarted){ //Animation hasnt begun yet this.hasStarted = true; this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_STARTED, this, this.getTargetObject())); }else{ this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_UPDATED, this, this.getTargetObject())); } }else{ this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_ENDED, this, this.getTargetObject())); AnimationManager.getInstance().removeAnimation(this); AnimationManager.getInstance().removeAnimationManagerListener(this); if (this.isResetOnFinish()){ this.getInterpolator().resetInterpolator(); this.triggerCountDown = this.triggerTime; //Reset triggercountdown this.hasStarted = false; } }//end else interpol !finished }//end else trigger not set /* if (this.isEnabled() && !this.interpolator.isFinished()){ triggerCountDown -= ev.getDeltaTime(); if (triggerCountDown <= 0){ if (!this.hasStarted){ this.hasStarted = true; interpolator.interpolate(ev.getDeltaTime()); this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_STARTED, this, this.getTargetObject())); }else{ interpolator.interpolate(ev.getDeltaTime()); this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_STARTED, this, this.getTargetObject())); } } // Do the next interpolation iteration interpolator.interpolate(ev.getDeltaTime()); if (!this.interpolator.isFinished()){ if (!this.hasStarted){ //Animation hasnt begun yet triggerCountDown -= ev.getDeltaTime(); if (triggerCountDown <= 0){ this.hasStarted = true; this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_STARTED, this, this.getTargetObject())); } // if (this.getTriggerTime() > 0){ // this.setStartedTime(System.currentTimeMillis()); // if (System.currentTimeMillis() - this.getStartedTime() >= this.getTriggerTime()){ // // } // }else{ // hasStarted = true; // this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_STARTED, this, this.getTargetObject())); // } }else{ //System.out.println("Animation UPDATED: " + a.getName()); this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_UPDATED, this, this.getTargetObject())); } }else{ //If interpolation has reached target this.fireAnimationEvent(new AnimationEvent(this, AnimationEvent.ANIMATION_ENDED, this, this.getTargetObject())); AnimationManager.getInstance().removeAnimation(this); AnimationManager.getInstance().removeAnimationManagerListener(this); this.triggerCountDown = this.getTriggerTime(); this.setEnabled(false); if (this.isResetOnFinish()){ this.getInterpolator().resetInterpolator(); this.triggerCountDown = this.getTriggerTime(); this.hasStarted = false; } } } */ } /** * Gets the trigger time. * * @return the trigger time */ public long getTriggerTime() { return triggerTime; } /** * Sets the trigger time. * * @param triggerTime the new trigger time */ public void setTriggerTime(long triggerTime) { this.triggerTime = triggerTime; this.triggerCountDown = triggerTime; } /** * Fire animation event. * * @param anev the anev */ private void fireAnimationEvent(AnimationEvent anev) { synchronized(animationListeners) { for (int i = 0; i < animationListeners.size(); i++) { IAnimationListener listener = (IAnimationListener)animationListeners.get(i); listener.processAnimationEvent(anev); } } } /** * Checks if is reset on finish. * * @return true, if is reset on finish */ public boolean isResetOnFinish() { return resetOnFinish; } /** * Sets the reset on finish. * * @param resetOnFinish the new reset on finish */ public void setResetOnFinish(boolean resetOnFinish) { this.resetOnFinish = resetOnFinish; } /** * Adds the animation listener. * * @param listener the listener */ public synchronized Animation addAnimationListener(IAnimationListener listener){ if (!animationListeners.contains(listener)){ animationListeners.add(listener); } return this; } /** * Removes the animation listener. * * @param listener the listener */ public synchronized void removeAnimationListener(IAnimationListener listener){ if (animationListeners.contains(listener)){ animationListeners.remove(listener); } } /** * Removes the all animation listeners. */ public synchronized void removeAllAnimationListeners(){ animationListeners.clear(); } /** * Gets the animation listeners. * * @return the animation listeners */ public synchronized IAnimationListener[] getAnimationListeners(){ return (IAnimationListener[])animationListeners.toArray(new IAnimationListener[this.animationListeners.size()]); } /** * Gets the target object. * * @return the target object */ public Object getTargetObject() { return targetObject; } /** * Sets the target object. * * @param targetObject the new target object */ public void setTargetObject(Object targetObject) { this.targetObject = targetObject; } /** * Gets the interpolator. * * @return the interpolator */ public Iinterpolator getInterpolator() { return interpolator; } /** * Sets the interpolator. * * @param interpolator the new interpolator */ public void setInterpolator(Iinterpolator interpolator) { this.interpolator = interpolator; } /** * Gets the name. * * @return the name */ public String getName() { return name; } /** * Sets the name. * * @param name the new name */ public void setName(String name) { this.name = name; } }