移动小部件时 QML 性能问题会影响彼此的移动



这是揭示问题的最小版本的代码:

桌面套件 (Windows) 上玩游戏时移动球拍不会影响球的移动速度,但在 Android 设备上运行时,移动球拍会影响球的移动速度,就好像它们的运动被绑在一起一样。
请问有什么解决方案?

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 720
height: 620
title: qsTr("Movement Test")
Rectangle {
id: table
anchors.fill: parent
color: "gray"
Rectangle {
id: ball
property double xincrement: Math.random() + 0.5
property double yincrement: Math.random() + 0.5
width: 15
height: width
radius: width / 2
color: "white"
x: 300; y: 300
}
Racket {
id: myRacket
x: table.width - 50
y: table.height/3
color: "blue"
}
Timer {
interval: 5; repeat: true; running: true
function collision() {
if((ball.x + ball.width >= myRacket.x  &&
ball.x < myRacket.x + myRacket.width) &&
(ball.y + ball.height >= myRacket.y &&
ball.y <= myRacket.y + myRacket.height))
return true
return false
}
onTriggered: {
if(ball.x + ball.width >= table.width)
running = false
else if(ball.x <= 0)
ball.xincrement *= -1
else if (collision())
ball.xincrement *= -1
ball.x = ball.x + (ball.xincrement * 1.5);
ball.y = ball.y + (ball.yincrement * 1.5);
if(ball.y <= 0 || ball.y + ball.height >= table.height)
ball.yincrement *= -1
}
}
}
}

Racket.qml

import QtQuick 2.9
Rectangle {
id: root
width: 15; height: 65
property int oldY: y
property bool yUwards: false
property bool yDwards: false
onYChanged: {
if(y > oldY)  yDwards = true
else if (y < oldY)  yUwards = true
oldY = y
}
MouseArea {
anchors.fill: parent
anchors.margins: -root.height
drag.target: root
focus: true
hoverEnabled: true
pressAndHoldInterval: 0
drag.axis: Drag.YAxis
drag.minimumY: table.y
drag.maximumY: table.height - root.height - 10
}
}

Qt尝试每~16-17ms渲染一次。如果将计时器设置为 5ms,它将尝试每帧触发 3 - 4 次。

正在发生的其他事情可能会阻碍它保持这种速度。如果设备功率较低,则此效果可能比其他设备上更明显。

要查看Timer是否达到设定速率,您可以使用以下方法打印当前ms部分时间:

console.log(Qt.formatTime(new Date(), "zzz"))

如果Timer达到全速,则记录的值应为 5 个公寓。如果没有,它将与 5 不同。

最简单的方法是设置球将移动到的目标位置,并对该运动进行动画处理(使用Animation-Type)。Animation应注意保持移动速度,即使在帧速率可能下降的情况下也是如此。

如果要手动执行此操作,则应使用onAfterRendering插槽(我想到Window),而不是使用计时器。当屏幕上有东西移动并触发渲染时,就会触发此操作。这也是检查碰撞的理想时刻。

然后,您需要根据其速度、当前位置和经过的时间计算新位置。后者您可以从 JSDate()-object 获取,或者使用QElapsedTimer以某种方式公开它C++

最新更新