可以更新其他对象值的动画类

时间:2014-03-16 13:00:17

标签: java animation

我想要一个可以通过不同项目重用的Animations类。问题是我如何让类改变另一个对象的成员(例如位置)。这是一个非常简化的版本,它将如何运作以及它可以做什么。

public class Animation() {

    private float currValue, targetValue, duration;

    public Animation(currValue, targetValue, duration) {
        this.currValue = currValue; 
        this.targetValue = targetValue;
        this.duration = duration;
    }

    public void update() {
        // Here I would update its currValue based on duration and target
    }
}

因此,当我想制作动画时,我会说矩形的位置:

class Rectangle {

    private float x, y;
    private Animation a;

    public Rectangle (x, y) {
        this.x = x;
        this.y = y;
        this.a = new Animation(x, 100, 1000); // Duration in ms
    }

    public void update() {
        a.update(); // Update animation
    }
}

显然这不起作用,因为Animation不会更新Rectangle的x值。只考虑一个解决方案,即传递Rectangle实例和字段名称“x”,然后使用Reflection API更新值。但这似乎是一个非常糟糕的解决方案。

有什么建议吗?我应该以不同的方式设计我的代码吗?

1 个答案:

答案 0 :(得分:2)

在这种情况下,反思不一定是一个糟糕的解决方案。事实上,它是一个非常通用的解决方案,允许客户端优雅的代码。但是,当然,人们应该注意一般使用反射的注意事项。

这种动画的一种非常务实的方法是"分解"动画实际上做了什么:在你的情况下,即改变一些float值。所以一种分离"客户"代码和实现可能如下:

interface FloatSetter {
    void setFloat(float f);
}

public class Animation 
{
    private float currValue, targetValue, duration;
    private FloatSetter floatSetter;

    public Animation(
        float currValue, float targetValue, float duration,
        FloatSetter floatSetter) 
    {
        this.currValue = currValue; 
        this.targetValue = targetValue;
        this.duration = duration;
        this.floatSetter = floatSetter;
    }

    public void update() 
    {
        ...
        floatSetter.setFloat(currValue);
    }
}

然后你可以将FloatSetter的适当实现传递给你的Animation - 可能是通过一个匿名的内部类:

class Rectangle 
{
    private float x, y;
    private Animation a;

    public Rectangle(float fx, float fy) {
        this.x = fx;
        this.y = fy;
        FloatSetter floatSetter = new FloatSetter()
        {
            @Override
            public void setFloat(float f)
            {
                this.x = f;
            }
        });
        this.a = new Animation(x, 100, 1000, floatSetter);
    }

    public void update() {
        a.update(); // Update animation
    }
}

顺便说一句:根据您要实现的目标,我建议Animation实例放入Rectangle。但我认为这只是一个表明你意图的草图。

重要:您应该明确了解"时间框架":https://java.net/projects/timingframework。它是本书章节的附带代码"肮脏的富客户端" (http://filthyrichclients.org/)Chet Haase和Romain Guy,他们肯定知道他们的东西。该库是非常复杂而灵活的实现,您显然希望在那里实现。 (它们也支持使用反射(https://java.net/projects/timingframework/sources/svn/content/trunk/timingframework-core/src/main/java/org/jdesktop/core/animation/timing/PropertySetter.java?rev=423)的泛型" PropertySetter"但这只是一个帮助类来定义一般的" TimingTarget",这是复杂的版本我在上面描绘的" FloatSetter"