Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. A strange movement effect of a component over another one's speed
Forum Updated to NodeBB v4.3 + New Features

A strange movement effect of a component over another one's speed

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 2 Posters 884 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • tomyT Offline
    tomyT Offline
    tomy
    wrote on last edited by tomy
    #1

    Hi,

    Tried well to simply the QML code below to characterise the issue clearly:

    Ball.qml:

    import QtQuick 2.12
    
    Rectangle {
        width: 18; height: 18
        color: "white"
        radius: width/2
    
        property double xincrement: window.ran
        property double yincrement: window.ran
    }
    

    Racket.qml:

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

    main.qml:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.5
    
    Window {
        id: window
        visible: true
        width: 1200; height: 900
        color: "gray"
    
        Rectangle {
            id: table
            width: window.width / 1.15; height: window.height / 1.15
            y: 10
            anchors.horizontalCenter: parent.horizontalCenter
            property double ran: Math.random() + 0.5
            property int duration: 4
            property double step: 1.5
            color: "royalblue"
    
            Racket {
                id: blackRacket
                anchors.left: table.left
                anchors.leftMargin: width * 2
                y: table.height / 2
                color: "black"
            }
            Racket {
                id: redRacket
                anchors.right: table.right
                anchors.rightMargin: width * 2
                y: table.height / 2
                color: "red"
            }
            Ball {
                id: ball
                x: table.width/2
                y: table.height/2
            }
            Timer {
                interval: 40; repeat: true; running: true
    
                onTriggered: {
                    redRacket.yUwards = false
                    redRacket.yDwards = false
                    blackRacket.yUwards = false
                    blackRacket.yDwards = false
                }
            }
            Timer {
                interval: table.duration; repeat: true; running: true
    
                function hitsRightRacket() {
                    if ((ball.x + ball.width >= redRacket.x &&
                         ball.x <= redRacket.x + redRacket.width) &&
                            (ball.y + ball.height >= redRacket.y &&
                             ball.y <= redRacket.y + redRacket.height))
                        return true
                    return false
                }
                function hitsLeftRacket() {
                    if (((ball.x + ball.width >= blackRacket.x &&
                         ball.x < blackRacket.x + blackRacket.width)  &&
                            (ball.y + ball.height >= blackRacket.y &&
                             ball.y <= blackRacket.y + blackRacket.height))
                            || (ball.x <= 0))
                        return true
                    return false
                }
                function hitsRightWall() {
                    if (ball.x + ball.width >= table.width)
                        return true
                    return false
                }
                function hitsLeftWall() {
                    if (ball.x <= 0) return true
                    return false
                }
                function hitsUpperOrLowerWall(){
                    if (ball.y <= 0 || ball.y + ball.height >= table.height)
                        return true
                    return false
                }
    
                onTriggered: {
                    if (hitsRightRacket()) {
                        if (redRacket.yUwards) {
                            if (ball.yincrement == 0)
                                ball.yincrement = -table.ran
                            else if (ball.yincrement > 0)
                                ball.yincrement *= -1
                            interval = (table.duration/4)
                        }
                        else if (redRacket.yDwards) {
                            if (ball.yincrement == 0)
                                ball.yincrement = table.ran
                            else if (ball.yincrement < 0)
                                ball.yincrement *= -1
                            interval = (table.duration/4)
                        }
                        else {
                            ball.yincrement = 0
                            interval = (table.duration/2)
                        }
                        ball.xincrement *= -1
                    }
                    else if (hitsLeftRacket()) {
                        if(blackRacket.yUwards) {
                            if (ball.yincrement == 0)
                                ball.yincrement = -table.ran
                            else if (ball.yincrement > 0)
                                ball.yincrement *= -1
                            interval = (table.duration/4)
                        }
                        else if (blackRacket.yDwards) {
                            if (ball.yincrement == 0)
                                ball.yincrement = table.ran
                            else if (ball.yincrement < 0)
                                ball.yincrement *= -1
                            interval = (table.duration/4)
                        }
                        else {
                            ball.yincrement = 0
                            interval = (table.duration/2)
                        }
                        ball.xincrement *= -1
                    }
                    else if (hitsRightWall())
                        ball.xincrement *= -1
                    else if (hitsLeftWall())
                        ball.xincrement *= -1
                    else if (hitsUpperOrLowerWall())
                        ball.yincrement *= -1
    
                    // Move Ball
                    ball.x = ball.x + (ball.xincrement * table.step);
                    ball.y = ball.y + (ball.yincrement * table.step);
                }
            }
        }
    }
    

    I tested that on my Android device. The problem is that, when rackets are not moving the ball moves smoothly (and it's OK), but when I move either racket, it affects the speed of the ball, strangely! These two must be independent in terms of movement and speed, but in effect this issue takes place. I don't know why.

    Will you test this code on your Android device too, to see if the problem exits there as well. If yes, what could be the source of the issue and how to remedy that, please?

    Thanks beforehand.

    J.HilkJ 1 Reply Last reply
    0
    • tomyT tomy

      Hi,

      Tried well to simply the QML code below to characterise the issue clearly:

      Ball.qml:

      import QtQuick 2.12
      
      Rectangle {
          width: 18; height: 18
          color: "white"
          radius: width/2
      
          property double xincrement: window.ran
          property double yincrement: window.ran
      }
      

      Racket.qml:

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

      main.qml:

      import QtQuick 2.12
      import QtQuick.Window 2.12
      import QtQuick.Controls 2.5
      
      Window {
          id: window
          visible: true
          width: 1200; height: 900
          color: "gray"
      
          Rectangle {
              id: table
              width: window.width / 1.15; height: window.height / 1.15
              y: 10
              anchors.horizontalCenter: parent.horizontalCenter
              property double ran: Math.random() + 0.5
              property int duration: 4
              property double step: 1.5
              color: "royalblue"
      
              Racket {
                  id: blackRacket
                  anchors.left: table.left
                  anchors.leftMargin: width * 2
                  y: table.height / 2
                  color: "black"
              }
              Racket {
                  id: redRacket
                  anchors.right: table.right
                  anchors.rightMargin: width * 2
                  y: table.height / 2
                  color: "red"
              }
              Ball {
                  id: ball
                  x: table.width/2
                  y: table.height/2
              }
              Timer {
                  interval: 40; repeat: true; running: true
      
                  onTriggered: {
                      redRacket.yUwards = false
                      redRacket.yDwards = false
                      blackRacket.yUwards = false
                      blackRacket.yDwards = false
                  }
              }
              Timer {
                  interval: table.duration; repeat: true; running: true
      
                  function hitsRightRacket() {
                      if ((ball.x + ball.width >= redRacket.x &&
                           ball.x <= redRacket.x + redRacket.width) &&
                              (ball.y + ball.height >= redRacket.y &&
                               ball.y <= redRacket.y + redRacket.height))
                          return true
                      return false
                  }
                  function hitsLeftRacket() {
                      if (((ball.x + ball.width >= blackRacket.x &&
                           ball.x < blackRacket.x + blackRacket.width)  &&
                              (ball.y + ball.height >= blackRacket.y &&
                               ball.y <= blackRacket.y + blackRacket.height))
                              || (ball.x <= 0))
                          return true
                      return false
                  }
                  function hitsRightWall() {
                      if (ball.x + ball.width >= table.width)
                          return true
                      return false
                  }
                  function hitsLeftWall() {
                      if (ball.x <= 0) return true
                      return false
                  }
                  function hitsUpperOrLowerWall(){
                      if (ball.y <= 0 || ball.y + ball.height >= table.height)
                          return true
                      return false
                  }
      
                  onTriggered: {
                      if (hitsRightRacket()) {
                          if (redRacket.yUwards) {
                              if (ball.yincrement == 0)
                                  ball.yincrement = -table.ran
                              else if (ball.yincrement > 0)
                                  ball.yincrement *= -1
                              interval = (table.duration/4)
                          }
                          else if (redRacket.yDwards) {
                              if (ball.yincrement == 0)
                                  ball.yincrement = table.ran
                              else if (ball.yincrement < 0)
                                  ball.yincrement *= -1
                              interval = (table.duration/4)
                          }
                          else {
                              ball.yincrement = 0
                              interval = (table.duration/2)
                          }
                          ball.xincrement *= -1
                      }
                      else if (hitsLeftRacket()) {
                          if(blackRacket.yUwards) {
                              if (ball.yincrement == 0)
                                  ball.yincrement = -table.ran
                              else if (ball.yincrement > 0)
                                  ball.yincrement *= -1
                              interval = (table.duration/4)
                          }
                          else if (blackRacket.yDwards) {
                              if (ball.yincrement == 0)
                                  ball.yincrement = table.ran
                              else if (ball.yincrement < 0)
                                  ball.yincrement *= -1
                              interval = (table.duration/4)
                          }
                          else {
                              ball.yincrement = 0
                              interval = (table.duration/2)
                          }
                          ball.xincrement *= -1
                      }
                      else if (hitsRightWall())
                          ball.xincrement *= -1
                      else if (hitsLeftWall())
                          ball.xincrement *= -1
                      else if (hitsUpperOrLowerWall())
                          ball.yincrement *= -1
      
                      // Move Ball
                      ball.x = ball.x + (ball.xincrement * table.step);
                      ball.y = ball.y + (ball.yincrement * table.step);
                  }
              }
          }
      }
      

      I tested that on my Android device. The problem is that, when rackets are not moving the ball moves smoothly (and it's OK), but when I move either racket, it affects the speed of the ball, strangely! These two must be independent in terms of movement and speed, but in effect this issue takes place. I don't know why.

      Will you test this code on your Android device too, to see if the problem exits there as well. If yes, what could be the source of the issue and how to remedy that, please?

      Thanks beforehand.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      hi @tomy

      hard to tell, I don't think your example will compile, the table class seems to be missing.

      However, this seems to be the right place to look into QML-Profilling

      That will give you a detailed analyzation of what takes how much time, at least on the QML side of the application.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      tomyT 1 Reply Last reply
      0
      • J.HilkJ J.Hilk

        hi @tomy

        hard to tell, I don't think your example will compile, the table class seems to be missing.

        However, this seems to be the right place to look into QML-Profilling

        That will give you a detailed analyzation of what takes how much time, at least on the QML side of the application.

        tomyT Offline
        tomyT Offline
        tomy
        wrote on last edited by tomy
        #3

        @J.Hilk

        hard to tell, I don't think your example will compile, the table class seems to be missing.

        Hi,

        But it compiles. And table is the id of a Rectangle. Please look at the line 12 of main.qml.

        Still do I need to study that long paper?

        J.HilkJ 1 Reply Last reply
        0
        • tomyT tomy

          @J.Hilk

          hard to tell, I don't think your example will compile, the table class seems to be missing.

          Hi,

          But it compiles. And table is the id of a Rectangle. Please look at the line 12 of main.qml.

          Still do I need to study that long paper?

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @tomy said in A strange movement effect of a component over another one's speed:

          But it compiles. And table is the id of a Rectangle. Please look at the line 12 of main.qml.

          Still do I need to study that long paper?

          Oh, I'm sorry, I did not see that.
          Can't test it myself, as I don't have an android device with me these days.

          I would recommend studying it, it will go a long way in optimizing your current and any following QML-based project!


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          tomyT 1 Reply Last reply
          1
          • J.HilkJ J.Hilk

            @tomy said in A strange movement effect of a component over another one's speed:

            But it compiles. And table is the id of a Rectangle. Please look at the line 12 of main.qml.

            Still do I need to study that long paper?

            Oh, I'm sorry, I did not see that.
            Can't test it myself, as I don't have an android device with me these days.

            I would recommend studying it, it will go a long way in optimizing your current and any following QML-based project!

            tomyT Offline
            tomyT Offline
            tomy
            wrote on last edited by
            #5

            @J.Hilk

            Can't test it myself, as I don't have an android device with me these days.

            Will you test it on any iOS smartphone which might be to your hands? The Desktop kit handles that well but I'm almost sure it keeps the issue on smartphone operating systems.

            I would recommend studying it, it will go a long way in optimizing your current and any following QML-based project!

            Thanks. I will begin studying that too.

            1 Reply Last reply
            0
            • tomyT Offline
              tomyT Offline
              tomy
              wrote on last edited by tomy
              #6

              In Using QML Profiler I can't find Analyze > QML Profiler to profile the current application!

              0_1548685790537_Capture.PNG

              J.HilkJ 1 Reply Last reply
              0
              • tomyT tomy

                In Using QML Profiler I can't find Analyze > QML Profiler to profile the current application!

                0_1548685790537_Capture.PNG

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #7

                @tomy
                did you check in the menu bar ?

                0_1548686280567_f095f875-4258-42e9-8683-1e364bec3fa6-image.png


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                1 Reply Last reply
                1
                • tomyT Offline
                  tomyT Offline
                  tomy
                  wrote on last edited by tomy
                  #8

                  I read the beginning part of that paper and it's to me detailed and useful for advanced devs but doesn't make an impression on the behavior of the program based on the output of starting the application from the QML Profiler. I've saved the trace file and it shows that the program mainly (more than %96) is dealing with the last onTriggered part:

                  0_1548757688018_Capture.PNG

                  I also tried to change the code to some little extent by separating the table as a single component, not covering other components in the code anymore. But overall, no changes on the Android device yet!

                  tomyT 1 Reply Last reply
                  0
                  • tomyT tomy

                    I read the beginning part of that paper and it's to me detailed and useful for advanced devs but doesn't make an impression on the behavior of the program based on the output of starting the application from the QML Profiler. I've saved the trace file and it shows that the program mainly (more than %96) is dealing with the last onTriggered part:

                    0_1548757688018_Capture.PNG

                    I also tried to change the code to some little extent by separating the table as a single component, not covering other components in the code anymore. But overall, no changes on the Android device yet!

                    tomyT Offline
                    tomyT Offline
                    tomy
                    wrote on last edited by
                    #9

                    I think I found the source of the issue:

                    The last Timer in main.qml each time, alongside with moving the ball, needs also to measure the positions of the rackets for collision checks, and while the rackets are moving by the user, those positions (x, y) change, and it makes those snags for the ball's movement.

                    For that, I tried to define another Timer to separate the Ball's movement from collision checks. That is, one Timer merely for movement of the Ball, and another for collision checks.
                    But unfortunately, it couldn't solve the issue either!

                    As an another attempt, I went for using property binding rather than collision checks' Timer. I only used a simple Timer for moving the Ball, but once again, unfortunately, it couldn't solve the problem. :(

                    I'm not sure if the problem is with the code or the operating system. Because, the program works fine on the Desktop kit (on Windows) but when tested on my Android version 4.4.2 tablet, the problem comes up.

                    Here's the new version of the code. I tried to commentate important parts of that so that it reads easily.

                    If you don't want to read the code, at least test it on your Android/iOS device to see whether it's a code issue or platform problem, please.

                    Ball.qml and Racket.qml are as before and here is main.qml:

                    import QtQuick 2.12
                    import QtQuick.Window 2.12
                    import QtQuick.Controls 2.5
                    
                    Window {
                        id: window
                        visible: true
                        width: 1000; height: 800
                        color: "gray"
                        property double ran: Math.random() + 0.5
                        property int duration: 4
                        property double step: 1.5
                    
                            // The components
                            // --------------
                    
                            Rectangle {
                                id: table
                                width: window.width / 1.15; height: window.height / 1.15
                                y: 10
                                anchors.horizontalCenter: parent.horizontalCenter
                                color: "royalblue"
                            }
                            Racket {
                                id: blackRacket
                                anchors.left: table.left
                                anchors.leftMargin: width * 2
                                y: table.height / 2
                                color: "black"
                            }
                            Racket {
                                id: redRacket
                                anchors.right: table.right
                                anchors.rightMargin: width * 2
                                y: table.height / 2
                                color: "red"
                            }
                            Ball {
                                id: ball
                                x: table.width/2
                                y: table.height/2
                            }
                    
                                // A number of bool properties to catch the hit between
                                // the ball and rackets/walls
                    
                            property bool hitsRightRacket: {
                                    if ((ball.x + ball.width >= redRacket.x &&
                                         ball.x <= redRacket.x + redRacket.width) &&
                                            (ball.y + ball.height >= redRacket.y &&
                                             ball.y <= redRacket.y + redRacket.height))
                                        return true
                                    return false
                                }
                             onHitsRightRacketChanged: {
                                if(hitsRightRacket) {
                                    if (redRacket.yUwards) {
                                        if (ball.yincrement == 0)
                                            ball.yincrement = -ran
                                        else if (ball.yincrement > 0)
                                            ball.yincrement *= -1
                                        timer.interval = duration / 4
                                    }
                                    else if (redRacket.yDwards) {
                                        if (ball.yincrement == 0)
                                            ball.yincrement = ran
                                        else if (ball.yincrement < 0)
                                            ball.yincrement *= -1
                                        timer.interval = duration / 4
                                    }
                                    else {
                                        ball.yincrement = 0
                                        timer.interval = duration / 2
                                    }
                                    ball.xincrement *= -1
                                }
                            }
                    
                             property bool hitsLeftRacket: {
                                 if (((ball.x + ball.width >= blackRacket.x &&
                                      ball.x < blackRacket.x + blackRacket.width)  &&
                                         (ball.y + ball.height >= blackRacket.y &&
                                          ball.y <= blackRacket.y + blackRacket.height))
                                         || (ball.x <= 0))
                                     return true
                                 return false
                             }
                             onHitsLeftRacketChanged: {
                                 if(hitsLeftRacket) {
                                 if(blackRacket.yUwards) {
                                     if (ball.yincrement == 0)
                                         ball.yincrement = -ran
                                     else if (ball.yincrement > 0)
                                         ball.yincrement *= -1
                                     timer.interval = (duration/4)
                                 }
                                 else if (blackRacket.yDwards) {
                                     if (ball.yincrement == 0)
                                         ball.yincrement = ran
                                     else if (ball.yincrement < 0)
                                         ball.yincrement *= -1
                                     timer.interval = duration / 4
                                 }
                                 else {
                                     ball.yincrement = 0
                                     timer.interval = duration / 2
                                 }
                                 ball.xincrement *= -1
                               }
                             }
                    
                             property bool hitsLeftOrRightWall: {
                                    if (ball.x + ball.width >= table.x + table.width ||
                                           ball.x <= table.x)
                                        return true
                                    return false
                                }
                             onHitsLeftOrRightWallChanged: {
                                 if(hitsLeftOrRightWall)
                                     ball.xincrement *= -1
                                 }
                    
                             property bool hitsUpperOrLowerWall: {
                                 if (ball.y <= table.y || ball.y + ball.height >= table.height)
                                     return true
                                 return false
                              }
                             onHitsUpperOrLowerWallChanged: {
                                 if(hitsUpperOrLowerWall)
                                     ball.yincrement *= -1
                             }
                    
                             // Timers
                             //--------
                    
                             Timer {  // this timer repeatedly sets the four booleans to false so that
                                      // the closest racket upwards/downwards movement is caught
                                 interval: 50; repeat: true; running: true
                    
                                 onTriggered: {
                                     redRacket.yUwards = false
                                     redRacket.yDwards = false
                                     blackRacket.yUwards = false
                                     blackRacket.yDwards = false
                                 }
                             }
                    
                               Timer {   // This timer's job is merely moving the ball
                                    id: timer
                                    interval: duration; repeat: true; running: true
                    
                                onTriggered: {
                                    ball.x += ball.xincrement * step
                                    ball.y += ball.yincrement * step
                                }
                          }
                     }
                    
                    1 Reply Last reply
                    1
                    • J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by J.Hilk
                      #10

                      hi @tomy

                      good that you can narrow the issue down.

                      a suggestions, that should make the code a bit faster

                      bind the collision check to the x movement of the ball (onXChanged)
                      currently hitsLeftRacket depends on ball.x and ball.y and blackRacket.y each time any of those values changes, the whole expression is reevaluated -> 3 times check, when one would be enough.

                      property bool hitsLeftRacket: false //Initial state
                      property bool hitsRightRacket: false
                      property bool hitsLeftOrRightWall: false
                      
                      Ball {
                                  id: ball
                                  x: table.width/2
                                  y: table.height/2
                      
                                  onXChanged: {
                                       var ballXw = ball.x + ball.width;
                       
                                       if (((ballXw  >= blackRacket.x && ball.x < blackRacket.x + blackRacket.width)  &&
                                           (ball.y + ball.height >= blackRacket.y && ball.y <= blackRacket.y + blackRacket.height))
                                           || (ball.x <= 0))
                                            hitsLeftRacket = true
                                     else
                                            hitsLeftRacket = false 
                      
                                       if (( ballXw  >= redRacket.x && ball.x <= redRacket.x + redRacket.width) &&
                                              (ball.y + ball.height >= redRacket.y && ball.y <= redRacket.y + redRacket.height))
                                           hitsRightRacket= true
                                     else
                                            hitsRightRacket= false 
                      
                                      if (ballXw   >= table.x + table.width ||
                                             ball.x <= table.x)
                                             hitsLeftOrRightWall = true
                                      else
                                             hitsLeftOrRightWall = false
                                 }
                              }
                      

                      also if you make the Rackets and the ball part of the table (children) than x and y will be relative to the coordinates of the table, would simplify the left or right wall check:

                      hitsLeftOrRightWall  = (ballXw   >= table.width ||  ball.x <=0)
                      

                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      tomyT 1 Reply Last reply
                      1
                      • J.HilkJ J.Hilk

                        hi @tomy

                        good that you can narrow the issue down.

                        a suggestions, that should make the code a bit faster

                        bind the collision check to the x movement of the ball (onXChanged)
                        currently hitsLeftRacket depends on ball.x and ball.y and blackRacket.y each time any of those values changes, the whole expression is reevaluated -> 3 times check, when one would be enough.

                        property bool hitsLeftRacket: false //Initial state
                        property bool hitsRightRacket: false
                        property bool hitsLeftOrRightWall: false
                        
                        Ball {
                                    id: ball
                                    x: table.width/2
                                    y: table.height/2
                        
                                    onXChanged: {
                                         var ballXw = ball.x + ball.width;
                         
                                         if (((ballXw  >= blackRacket.x && ball.x < blackRacket.x + blackRacket.width)  &&
                                             (ball.y + ball.height >= blackRacket.y && ball.y <= blackRacket.y + blackRacket.height))
                                             || (ball.x <= 0))
                                              hitsLeftRacket = true
                                       else
                                              hitsLeftRacket = false 
                        
                                         if (( ballXw  >= redRacket.x && ball.x <= redRacket.x + redRacket.width) &&
                                                (ball.y + ball.height >= redRacket.y && ball.y <= redRacket.y + redRacket.height))
                                             hitsRightRacket= true
                                       else
                                              hitsRightRacket= false 
                        
                                        if (ballXw   >= table.x + table.width ||
                                               ball.x <= table.x)
                                               hitsLeftOrRightWall = true
                                        else
                                               hitsLeftOrRightWall = false
                                   }
                                }
                        

                        also if you make the Rackets and the ball part of the table (children) than x and y will be relative to the coordinates of the table, would simplify the left or right wall check:

                        hitsLeftOrRightWall  = (ballXw   >= table.width ||  ball.x <=0)
                        
                        tomyT Offline
                        tomyT Offline
                        tomy
                        wrote on last edited by
                        #11

                        @J.Hilk
                        Hi,
                        Thank you for your suggestions.
                        Binding the collision check to the Ball's X movement is nicer and more reasonable. I used this.

                        Making the table the parent of Ball and Rackets won't create that change in the appearance of code. Will it?

                        hitsLeftOrRightWall  = (ballXw  >= table.width ||  ball.x <=0)
                         // table is parent
                        hitsLeftOrRightWall  = (ballXw >= table.x + table.width || ball.x <= table.x)
                         // table isn't parent        
                        

                        Anyway, your suggestion is used in the code as below.
                        Unfortunately, when the ball hits the lower wall, it doesn't return upwards in practice and the condition for that in the onXChanged's body,
                        becomes true once again while it shouldn't!

                        But worse than this, although the code this way doesn't meat the specs of the game, when run on my Android device, the problem with the strange effect of rackets movements over ball's speed still exists! :( :(

                        It's really odd, and I checked the specs of the component Racket but nothing is clear to make the issue!

                        Window {
                            id: window
                            visible: true
                            width: 1000; height: 800
                            color: "gray"
                            property double ran: Math.random() + 0.5
                            property int duration: 4
                            property double step: 1.5
                            property bool hitsLeftRacket: false  //Initial state
                            property bool hitsRightRacket: false
                            property bool hitsLeftOrRightWall: false
                            property bool hitsUpperOrLowerWall: false
                            property int ballXw: ball.x + ball.width
                        
                                // The components
                                // --------------
                        
                                Rectangle {
                                    id: table
                                    width: window.width / 1.15; height: window.height / 1.15
                                    y: 10
                                    anchors.horizontalCenter: parent.horizontalCenter
                                    color: "royalblue"
                                }
                                Racket {
                                    id: blackRacket
                                    anchors.left: table.left
                                    anchors.leftMargin: width * 2
                                    y: table.height / 2
                                    color: "black"
                                }
                                Racket {
                                    id: redRacket
                                    anchors.right: table.right
                                    anchors.rightMargin: width * 2
                                    y: table.height / 2
                                    color: "red"
                                }
                                Ball {
                                    id: ball
                                    x: table.width/2
                                    y: table.height/2
                        
                                    onXChanged: {
                                      hitsLeftRacket = (((ballXw >= blackRacket.x &&
                                                ball.x < blackRacket.x + blackRacket.width) &&
                                               (ball.y + ball.height >= blackRacket.y &&
                                                ball.y <= blackRacket.y + blackRacket.height))|| (ball.x <= 0))
                        
                                      hitsRightRacket = ((ballXw >= redRacket.x &&
                                                ball.x <= redRacket.x + redRacket.width) &&
                                               (ball.y + ball.height >= redRacket.y &&
                                                ball.y <= redRacket.y + redRacket.height))
                        
                                      hitsLeftOrRightWall = (ballXw >= table.x + table.width ||
                                                             ball.x <= table.x)
                        
                                      hitsUpperOrLowerWall = (ball.y <= table.y ||
                                                             (ball.y + ball.height >= table.y + table.height))
                                    }
                                }
                        
                                Timer {
                                     interval: duration; repeat: true; running: true
                        
                                     onTriggered: {
                                      if(hitsRightRacket) {
                                        if (redRacket.yUwards) {
                                            if (ball.yincrement == 0)
                                                ball.yincrement = -ran
                                            else if (ball.yincrement > 0)
                                                ball.yincrement *= -1
                                            interval = duration / 4
                                        }
                                        else if (redRacket.yDwards) {
                                            if (ball.yincrement == 0)
                                                ball.yincrement = ran
                                            else if (ball.yincrement < 0)
                                                ball.yincrement *= -1
                                            interval = duration / 4
                                        }
                                        else {
                                            ball.yincrement = 0
                                            interval = duration / 2
                                        }
                                        ball.xincrement *= -1
                                    }
                        
                                   else if(hitsLeftRacket) {
                                     if(blackRacket.yUwards) {
                                         if (ball.yincrement == 0)
                                             ball.yincrement = -ran
                                         else if (ball.yincrement > 0)
                                             ball.yincrement *= -1
                                         interval = (duration/4)
                                     }
                                     else if (blackRacket.yDwards) {
                                         if (ball.yincrement == 0)
                                             ball.yincrement = ran
                                         else if (ball.yincrement < 0)
                                             ball.yincrement *= -1
                                         interval = duration / 4
                                     }
                                     else {
                                         ball.yincrement = 0
                                         interval = duration / 2
                                     }
                                     ball.xincrement *= -1
                                   }
                        
                                  else if(hitsLeftOrRightWall) ball.xincrement *= -1
                        
                                  else if(hitsUpperOrLowerWall) ball.yincrement *= -1
                        
                                    ball.x += ball.xincrement * step
                                    ball.y += ball.yincrement * step
                                 }
                            }
                        
                                 Timer {  // this timer repeatedly sets the four booleans to false so that
                                          // the closest racket upwards/downwards movement is caught
                                     interval: 50; repeat: true; running: true
                        
                                     onTriggered: {
                                         redRacket.yUwards = false
                                         redRacket.yDwards = false
                                         blackRacket.yUwards = false
                                         blackRacket.yDwards = false
                                     }
                                 }      
                            }
                        
                        
                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved