画布动画

时间:2013-02-20 10:47:37

标签: android animation canvas surfaceview

我已经四处寻找帮助,但我找不到任何答案。目前,当我想在一个表面视图中为一个球设置动画时,我称之为:

  1. 将surfaceview中的动画变量设置为扩展AnimationModule(扩展AnimationSet)的自定义类,该类会在每次绘制时更改球的属性

  2. 然后在每次绘制时调用它,直到AnimationModule达到其maxCount,此时它调用其继承的AnimationListener.onAnimationEnd

  3. surfaceview接收此回调,然后声明动画变量null,以便它不再在每次绘制时调用它

  4. 目前这种方式还行,但感觉非常糟糕和笨重 - 我真的很想使用其他人使用的经过试验和测试的方法,因为我对动画非常陌生。

    在另一个问题,这是我必须使用扩展view.animation动画,所以ScaleAnimation,TranslateAnimation等,这是一切都很好的转移球在屏幕上,但是当我来到像动画更复杂的东西它是canvas的透视图.polyToPoly我必须为这种情况创建一个扩展view.animation的新类,或者不用它来创建。

    AnimationModule类:

    public abstract class AnimationModule extends AnimationSet{
    
    protected AnimationListener listener;
    protected CreatureView attacker;
    protected CreatureView defender;
    protected BattleCanvas canvas;
    protected long increment=0;
    protected long individualIncrement=0;
    protected float interpolation=0;
    private boolean finished=false;
    private ArrayList<Animation> animations = new ArrayList<Animation>();
    private int currentAnimation=0;
    private long totalTime=0;
    
    public interface OnAnimationFinishedListener{
        public void OnAnimationFinished();
    }
    
    public AnimationModule(boolean shareInterpolator){
        super(shareInterpolator);
        init();
    }
    
    public void setCanvas(BattleCanvas canvas){
        this.canvas=canvas;
    }
    
    public void setCreatures(CreatureView attacker, CreatureView defender){
        this.attacker=attacker;
        this.defender=defender;
        Log.i("anim","attacker :"+String.valueOf(attacker.getCreature().getBaseName()));
    }
    
    public AnimationModule(boolean shareInterpolator, AnimationController controller){
        super(shareInterpolator);
    
    }
    
    private void init(){
    
        setFillAfter(true);
    
    }
    public boolean isFinished(){
        return finished;
    }
    
    @Override
    public void addAnimation(Animation a){
        Log.i("Animation","adding animation");
        animations.add(a);
        computeDuration();
        //super.addAnimation(a);
        finished=false;
    }
    
    @Override
    public void setAnimationListener(AnimationListener a){
        super.setAnimationListener(a);
        this.listener=a;
    }
    
    @Override
    public boolean getTransformation(long increment, Transformation transform){
        //super.getTransformation(increment, transform);
        if(animations.size()>currentAnimation)
        animations.get(currentAnimation).getTransformation(individualIncrement, transform);
        return true;
    }
    
    public void draw(){
    
    
    }
    
    public void update(){
        if(animations.size()>0){
        Log.i("Animation",String.valueOf(individualIncrement));
        Log.i("Animation",String.valueOf((animations.get(currentAnimation).getRepeatCount()+1)));
        Log.i("Animation",String.valueOf(animations.get(currentAnimation).getDuration()));
        if(individualIncrement>animations.get(currentAnimation).getDuration()*(animations.get(currentAnimation).getRepeatCount()+1)){
            if(animations.size()>currentAnimation+1){
                currentAnimation++;
                individualIncrement=0;
            }else{
                finished();
                return;
            }
        }
        Log.i("module","on animation "+String.valueOf(currentAnimation));
    
        increment();
        if(increment>=getDuration()){
            finished();
    
        }
        }
    }
    
    
    
    protected long computeDuration(){
        long duration=0;
        Iterator<Animation> iterator = animations.iterator();
        while (iterator.hasNext()) {
            Animation a = iterator.next();
            duration=duration+a.computeDurationHint();
        }
        totalTime=duration;
        setDuration(duration);
        Log.i("Animation","duration set to "+String.valueOf(duration));
        return duration;
    }
    
    private void finished(){
        finished=true;
        if(listener!=null)
        listener.onAnimationEnd(this);
    }
    
    private void increment(){
        increment++;
        individualIncrement++;
        if(getDuration()!=0){
        float far = increment/getDuration();
        interpolation=far;      
        }
        else
            interpolation=0;
    }
    
    }
    

    扩展AnimationModule的示例动画:

    class BiteAnimation extends AnimationModule{
    
    
        private float fromSy;
        private float fromSx;
        private ColorAnimation flash;
    
        public BiteAnimation(boolean shareInterpolator){
            super(shareInterpolator);
    
    
    
        }
    
    
        @Override
        public void setCanvas(BattleCanvas canvas){
            super.setCanvas(canvas);
    
        fromSy=defender.getSy();
    
            fromSx=defender.getSx();
    
            ScaleAnimation scale = new ScaleAnimation(fromSx,fromSx,fromSy,fromSy/2, defender.size/2, defender.size/2);
    
            scale.setDuration(50);
            scale.setRepeatMode(2);
            scale.setRepeatCount(1);
    
            addAnimation(scale);
    
             flash = new ColorAnimation(defender.getAdd(), Color.WHITE, ColorAnimation.TYPE_ADD, defender);
             flash.setDuration(50);
             flash.setRepeatMode(2);
             flash.setRepeatCount(1);
    
        }
    
        @Override
        public void update() {
            super.update();
             Transformation t = new Transformation();
    
             Log.i("Animation","increment: "+String.valueOf(individualIncrement));
                        getTransformation(individualIncrement, t);
                        defender.getMatrix().postConcat(t.getMatrix());
    
                   flash.getTransformation(individualIncrement, null);
    
    
        }
    
    }
    

    正如你所看到的,自定义animationModule只是将它的变换应用到它正在变换画布的objet(在这种情况下是一个后卫​​)。然后在surfaceview上绘制防御者时使用此画布。

    就像我说的那样,这感觉非常糟糕,我可以帮助我实现对象动画。

0 个答案:

没有答案