0

In my QML program I need to use Animations to test for a problem. Please run the code below on your system. I don't know why when I use this ParallelAnimation the ball doesn't reflect when it hits the walls!

Here is main.qml:

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 720
    height: 620

    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"
        }

        ParallelAnimation {
            id: anim
            NumberAnimation {
                target: ball
                properties: "x"
                to: timer.xMove
            }
            NumberAnimation {
                target: ball
                properties: "y"
                to: timer.yMove
            }
        }

        Timer {
            id: timer
            interval: 20; repeat: true; running: true
            property double xMove: ball.x + ball.xincrement
            property double yMove: ball.y + ball.yincrement

            onTriggered: {
                if(ball.x + ball.width >= table.width || ball.x <= 0)
                    ball.xincrement *= -1

                xMove += ball.xincrement
                yMove += ball.yincrement
                anim.restart()

                if(ball.y <= 0 || ball.y + ball.height >= table.height)
                    ball.yincrement *= -1
            }
        }
    }
}

And here's also Racket.qml:

import QtQuick 2.9

Rectangle {
    id: root
    width: 15; height: 65

    MouseArea {
        anchors.fill: root
        anchors.margins: -root.height
        drag.target: root
        drag.axis: Drag.YAxis
        drag.minimumY: 0
        drag.maximumY: 600
    }
}

EDIT1:

I used this code without Animations and it works well! (The dropped parts are the same)

...
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
        }
...

Timer {
            id: timer
            interval: 20; repeat: true; running: true

            onTriggered: {
                if(ball.x + ball.width >= table.width || ball.x <= 0)
                    ball.xincrement *= -1

                ball.x += ball.xincrement * 2.0
                ball.y += ball.yincrement * 2.0

                if(ball.y <= 0 || ball.y + ball.height >= table.height)
                    ball.yincrement *= -1
            }
        }
    }
}
opty
  • 27
  • 1
  • 9
  • Your question is something like this: I have a problem with Animation, your solution to eliminate Animation, that is the solution to any problem, I understand that the solution you were looking for is to solve your problem even with Animation, but it seems that it is not. – eyllanesc Jan 07 '18 at 19:42
  • Why did you down-voted the question and also deleted your answer!? I'm a new learner and may have many questions to learn things properly. – opty Jan 07 '18 at 19:47
  • I did not say the down-vote you mention, I eliminated my question as I thought that you already have your own solution. – eyllanesc Jan 07 '18 at 19:51
  • Sorry but I do not have a solution and as I stated in my question *"I need to use `Animation`s to test for a problem*". So using `Animation`s a new solution is needed. And also I may have questions and the question I asked was about the different behavior of the program with and without `Animations`. – opty Jan 07 '18 at 19:59
  • Have you tried my solution? – eyllanesc Jan 07 '18 at 20:00
  • Your question should be specific, if you have other questions create other posts, SO works. – eyllanesc Jan 07 '18 at 20:02
  • Yes, thanks. It works but why those many else-if are not needed in the version without Animations (sections EDIT1) because hitting the walls is independent of the way the ball moves. – opty Jan 07 '18 at 20:04
  • the problem with the use of the Timer that you will have in the future is that you will overload your application if you do not have an adequate handling, if you use Animation this will update the position in an appropriate way taking the refresh time from the window. – eyllanesc Jan 07 '18 at 20:07
  • A code should be clear, if you could not have problems like the one you had, the error I had is to have a "compact" code, I only separated it without adding more calculation, that is, at the computer level it had the same cost, it is preferred to use addition or subtraction, or inversion of signs that multiplication by -1 – eyllanesc Jan 07 '18 at 20:10

1 Answers1

0

Your problem is that PropertyAnimation has a default duration of 250 ms.

Adding

duration: 0

to both of your NumberAnimation will correct the problem and is equivalent to your second solution without animations.

However you can reproduce the exact same behavior with pure animation without any Timer:

ParallelAnimation {
    id: anim

    property double xMove: ball.x + ball.xincrement
    property double yMove: ball.y + ball.yincrement

    NumberAnimation {
        target: ball
        properties: "x"
        to: anim.xMove
        duration: 20
    }

    NumberAnimation {
        target: ball
        properties: "y"
        to: anim.yMove
        duration: 20
    }

    onStopped: {
        updatePosition()
    }

    Component.onCompleted: {
        updatePosition()
    }

    function updatePosition() {
        if(ball.x + ball.width >= table.width || ball.x <= 0)
            ball.xincrement *= -1

        if(ball.y <= 0 || ball.y + ball.height >= table.height)
            ball.yincrement *= -1

        anim.xMove += ball.xincrement
        anim.yMove += ball.yincrement
        anim.restart()
    }
}
augre
  • 2,011
  • 12
  • 18