有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使LibGDX动作moveTo()以曲线的形式从一点到另一点进行动画制作?

我正在LibGDX上做一个项目,我正在为我的一些精灵使用Scene2D演员。在这方面,我有一个精灵,它正在屏幕上某个地方繁殖,需要移动到屏幕上的另一个位置。为此,我在Actions中使用了moveTo(xPos, yPos, duration, interpolation)方法来制作移动动画

然而,当我使用这种方法时,演员按照我告诉它的方式移动,但它只在一条直线上移动,从点a到点B。我尝试了几种插值选项,如圆插值等,但它似乎只会影响动画线的速度

所以现在我的问题是:如何让我的动画从a到B画一条平滑的曲线(见图)? enter image description here

我目前正在使用以下代码制作动作动画:

adultCustomerPointActor.addAction(Actions.sequence(
    Actions.moveTo(300, 200, 2f, Interpolation.circle)
));

提前感谢您的帮助:)


共 (1) 个答案

  1. # 1 楼答案

    这是一个几何问题。使用向量,找到两点中间的点:

    vec1.set(bx, by).sub(ax, ay).scl(0.5f).add(ax, ay);
    

    从点之间的矢量获取另一个距离为90或270的矢量:

    vec2.set(bx, by).sub(ax, ay).rotate90().add(vec1);
    

    vec2可以缩放以调整圆弧的极端曲率。如果你不去管它,你会有一个四分之一圆。也可以将其缩放为负值以反转曲率

    然后把第二个向量加到第一个向量上,找到弧的中心点,我们称之为点C

    vec1.set(bx, by).sub(vec2); // CB
    vec3.set(ax, ay).sub(vec2); // CA
    float angle = vec1.angle(vec3);
    

    现在你需要一个从C点指向a点的向量。你将旋转这个向量直到它到达B点。所以你需要CA和CB之间的角度

    这里有一个非常简单的类来实现这个。它还不能用来决定你想让弧线上升还是下降,以及你想让它看起来有多极端。您可以使用getter/setter添加这些参数作为附加参数。我还没有测试它,所以可能需要一些调试

    public class ArcToAction extends MoveToAction {
        private float angle;
        private final Vector2 vec1 = new Vector2(), vec2 = new Vector2(), vec3 = new Vector2();
    
        @Override
        protected void begin () {
            super.begin();
            float ax = target.getX(getAlignment()); // have to recalculate these because private in parent
            float ay = target.getY(getAlignment());
            vec1.set(getX(), getY()).sub(ax, ay);
            vec2.set(vec1).rotate90();
            vec1.scl(0.5f).add(ax, ay);
            vec2.add(vec1);
            vec1.set(bx, by).sub(vec2); // CB
            vec3.set(ax, ay).sub(vec2); // CA
            angle = vec1.angle(vec3);
        }
    
        protected void update (float percent) {
            if (percent >= 1){
                target.setPosition(getX(), getY(), getAlignment());
                return;
            }
    
            vec1.set(vec3).rotate(percent * angle);
            target.setPosition(vec1.x, vec1.y, getAlignment());
        }
    
    }
    

    如果要支持自动池,可以添加如下方法:

    static public ArcToAction arcTo (float x, float y, float duration, Interpolation interpolation) {
        ArcToAction action = Actions.action(ArcToAction .class);
        action.setPosition(x, y);
        action.setDuration(duration);
        action.setInterpolation(interpolation);
        return action;
    }