0

Here is a minimal version of a code revealing the problem which is:

Moving the racket when playing the game on the Desktop kit (Windows) doesn't affect the speed of ball's movement but when run on an Android device, moving the racket affects the speed of ball's movement as though their movements have been tied together.
What solution is there for that, please?

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
    }
}
opty
  • 27
  • 1
  • 9

1 Answers1

0

Qt tries to render every ~16-17ms. If you set your timer to 5ms, it will try to trigger it 3 - 4 times per frame.

Other things that are happening might hinder it from keeping that pace. If the device is less powerfull this effect might be more visible than on other devices.

To see, whether the Timer achievs the set rate, you can print the current ms part of the time with:

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

The logged values shall be 5 appart, if the Timer achives full speed. It will be different from 5 if it doesn't.

The easiest way would be to set a target location where the ball will move to, and animate that movement (using a Animation-Type). The Animation shall take care, that the movement speed will be kept, even in cases where the frame rate might drop.

If you want to do it manually, instead of using the timer, you should use the onAfterRendering-slot (I think of Window). This will be triggered when ever something has moved on the screen and triggered rendering. This is also the ideal moment to check collisions.

You then need to calculate the new position depnding on its velocity, the current position and the elapsed time. Latter you can get either from the JS Date()-object, or you expose it somehow form C++ using a QElapsedTimer

  • Thank you. I tested the app on a new and powerful device but the same result. For the `console.log`, I put it under the `onTriggered: {` and the range of outputs was: 933, 938, ~ 008, 024, ~ 142, 143, 159, ~ 375, 379 ~ 400 ~ 500 ~~ 900, and once again repeating this. They aren't exactly 5 apart. About the `onAfterRendering`and other stuff, would you change the code to the way you say? I'm new in QML and these might take days if I set them. – opty Jan 04 '18 at 09:19
  • No, unfortunately my time is very limited right now. – derM - not here for BOT dreams Jan 04 '18 at 09:58
  • OK, so please bear this in mind for when you're more free. Thanks. – opty Jan 04 '18 at 11:36