Qt QML NumberAnimation.duration行为

Qt QML NumberAnimation.duration行为,qt,animation,qml,game-physics,Qt,Animation,Qml,Game Physics,我试图让玩家在QML中顺利地移动到目的地。我正在使用NumberAnimation设置x、y位置变化的动画。NumberAnimation的持续时间应与玩家必须行驶的距离成比例,以便玩家以相同的速度移动,而不管他们离目的地有多远 import QtQuick 1.1 Item { width: 720 height: 720 MouseArea { anchors.fill: parent onClicked: {

我试图让玩家在QML中顺利地移动到目的地。我正在使用
NumberAnimation
设置x、y位置变化的动画。
NumberAnimation
的持续时间应与玩家必须行驶的距离成比例,以便玩家以相同的速度移动,而不管他们离目的地有多远

import QtQuick 1.1

Item {
    width: 720
    height: 720

    MouseArea {
        anchors.fill: parent
        onClicked: {
            var newXDest = mouse.x - player.width / 2;
            var newYDest = mouse.y - player.height / 2;
            var dist = player.distanceFrom(newXDest, newYDest);
            // Make duration proportional to distance.
            player.xMovementDuration = dist; // 1 msec per pixel
            player.yMovementDuration = dist; // 1 msec per pixel
            console.log("dist = " + dist);
            player.xDest = newXDest;
            player.yDest = newYDest;
        }
    }

    Rectangle {
        id: player
        x: xDest
        y: yDest
        width: 32
        height: 32
        color: "blue"
        property int xDest: 0
        property int yDest: 0
        property int xMovementDuration: 0
        property int yMovementDuration: 0

        function distanceFrom(x, y) {
            var xDist = x - player.x;
            var yDist = y - player.y;
            return Math.sqrt(xDist * xDist + yDist * yDist);
        }

        Behavior on x {
            NumberAnimation {
                duration: player.xMovementDuration
//                duration: 1000
            }
        }

        Behavior on y {
            NumberAnimation {
                duration: player.yMovementDuration
//                duration: 1000
            }
        }
    }

    Rectangle {
        x: player.xDest
        y: player.yDest
        width: player.width
        height: player.height
        color: "transparent"
        border.color: "red"
    }
}
我的问题可以通过运行上面的应用程序并执行以下步骤来演示:

  • 单击屏幕右下角
  • 立即单击屏幕中央(或靠近左上角)
  • 在第二次单击时(矩形仍在移动),矩形的数字动画似乎停止了(这是我想要的),但它假定了目标的位置(不是我想要的)。相反,我希望动画停止,矩形假设它停止的位置,然后继续到新的目标

    import QtQuick 1.1
    
    Item {
        width: 720
        height: 720
    
        MouseArea {
            anchors.fill: parent
            onClicked: {
                var newXDest = mouse.x - player.width / 2;
                var newYDest = mouse.y - player.height / 2;
                var dist = player.distanceFrom(newXDest, newYDest);
                // Make duration proportional to distance.
                player.xMovementDuration = dist; // 1 msec per pixel
                player.yMovementDuration = dist; // 1 msec per pixel
                console.log("dist = " + dist);
                player.xDest = newXDest;
                player.yDest = newYDest;
            }
        }
    
        Rectangle {
            id: player
            x: xDest
            y: yDest
            width: 32
            height: 32
            color: "blue"
            property int xDest: 0
            property int yDest: 0
            property int xMovementDuration: 0
            property int yMovementDuration: 0
    
            function distanceFrom(x, y) {
                var xDist = x - player.x;
                var yDist = y - player.y;
                return Math.sqrt(xDist * xDist + yDist * yDist);
            }
    
            Behavior on x {
                NumberAnimation {
                    duration: player.xMovementDuration
    //                duration: 1000
                }
            }
    
            Behavior on y {
                NumberAnimation {
                    duration: player.yMovementDuration
    //                duration: 1000
                }
            }
        }
    
        Rectangle {
            x: player.xDest
            y: player.yDest
            width: player.width
            height: player.height
            color: "transparent"
            border.color: "red"
        }
    }
    

    正确的行为-忽略移动速度变得不成比例-可以通过将
    NumberAnimation.duration
    s设置为1000来查看。

    我认为您正在寻找平滑的数据。在动画完成之前,只有两种类型的动画可以很好地处理目标更改。这就是平滑动画和SpringAnimation。这两种方法都使用当前位置和速度来确定下一帧中的位置。其他动画类型沿预定曲线移动位置


    简单地将NumberAnimation更改为SmoothDanimation可以使您的示例在我看来是正确的。

    SmoothDanimation的唯一问题是它不再是一条直线;当向某些目的地移动时,玩家沿着曲线行走,直到它们与目的地的x或y位置成一条直线,然后沿着该轴移动剩下的部分。这对我来说是个问题,因为弯曲的运动可以看到玩家在他们不应该看到的地形上行走。我知道我的问题中没有提到这一点,但我想我还是在这里指出这一点,以防你有什么建议。