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. Offer me a good QML exercise
Forum Updated to NodeBB v4.3 + New Features

Offer me a good QML exercise

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
41 Posts 4 Posters 14.8k Views 3 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 tomy

    @J.Hilk
    Thank you.
    Timer was very useful. I wrote this:

    import QtQuick 2.8
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 800
        height: 600
        title: qsTr("The Ping Pong game")
    
        Rectangle {
            id: table
            width: 700; height: 500
            border.width: 10
            border.color: "black"
            color: "royalblue"
    
       Racket {
           id: redRacket
           x: 630; y: 100
           color: "red"
       }
    
       Racket {
           id: blackRacket
           x: 50; y: 100
           color: "black"
       }
    
       Ball {
           id: ball
           x: table.width/2 - 50
           y: table.height/2
           property double ran: Math.random() + 0.5
           property double xincrement: ran
           property double yincrement: ran
       }
    
       Column {
           spacing: 3
           x: table.width/2
           y: 10
              Repeater {
                model: 21
                 delegate: Rectangle {
                          width: 5
                          height: 20
                          color: "white"
                       }
                 }
           }
    
       Timer {
         interval: 5; repeat: true; running: true
    
            onTriggered: {
                ball.x = ball.x + (ball.xincrement * 2.0);
                ball.y = ball.y + (ball.yincrement * 2.0);
    
                if((ball.x + ball.width  >= redRacket.x)  &&
                  ((ball.y + ball.height >= redRacket.y)  &&
                   (ball.y + ball.height <= redRacket.y + redRacket.height)))
                       ball.xincrement *= (-1);
    
                if((ball.x - ball.width  <= blackRacket.x)  &&
                  ((ball.y + ball.height >= blackRacket.y)  &&
                   (ball.y + ball.height <= blackRacket.y + blackRacket.height)))
                       ball.xincrement *= (-1);
    
                 if(ball.y <= 0 || ball.y + ball.height >= table.height)
                      ball.yincrement *= (-1);
               }
            }
        }
     }
    

    It works fine but the players can't shoot the ball towards a target they want! The rackets are this way only for defending. I need to alter the code so that when the racket has speed upward or downward hitting the ball, the ball goes and gets acceleration on that direction. The real game has that feature.
    How can I do that, please?

    After that I'll go for other missing parts for the game.

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

    @tomy
    well, first you'll need to somehow monitor if the racket moved up or down as its last movement.

    I don't see how in the code examples you posted how you manage the "Racket-Movement" .

    but it doesn't matter much, it can be a property of the Racket Item

    #untested Stuff
    e.g:

    Rectangle {
           id: redRacket
           x: 630; y: 100
           color: "red"
    
           property int oldY: 100
           
           property bool upMovement: false
    
          onYChanged:{
              upMovement = y -oldY < 0  ? true : false
              oldY = y
          }
    
           width: 50
           height: 100
       }
    

    and when the Ball hits the racket you decrease the duration, and depending on the up or down movement you change the angle

    function onCollisionWithRacket(){
        root.duration = root.duration -10
        if(redRacket.upMovement){
            //Angle to the Top
        }else{
            //Angle to the bottom
        }
    }
    

    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
      well, first you'll need to somehow monitor if the racket moved up or down as its last movement.

      I don't see how in the code examples you posted how you manage the "Racket-Movement" .

      but it doesn't matter much, it can be a property of the Racket Item

      #untested Stuff
      e.g:

      Rectangle {
             id: redRacket
             x: 630; y: 100
             color: "red"
      
             property int oldY: 100
             
             property bool upMovement: false
      
            onYChanged:{
                upMovement = y -oldY < 0  ? true : false
                oldY = y
            }
      
             width: 50
             height: 100
         }
      

      and when the Ball hits the racket you decrease the duration, and depending on the up or down movement you change the angle

      function onCollisionWithRacket(){
          root.duration = root.duration -10
          if(redRacket.upMovement){
              //Angle to the Top
          }else{
              //Angle to the bottom
          }
      }
      
      tomyT Offline
      tomyT Offline
      tomy
      wrote on last edited by tomy
      #21

      @J.Hilk
      Thanks.
      I tried to make the work done and here is the code.
      I don't use the prior versions of the code (above) but this one.

      Ball.qml and Racket.qml are as before but main.qml is completely as below.

      As you see I haven't used a function and I don't know if it's needed or not.
      If possible please run that code to see its function. I don't think it's flawless.
      The code also to me is very messy. If it can make the work done using little changes, what to do for removing the problems from that please?

      import QtQuick 2.8
      import QtQuick.Window 2.2
      
      Window {
          visible: true
          width: 800
          height: 600
          title: qsTr("The PingPong Game")
      
          Rectangle {
              id: table
              width: 700; height: 500
              border.width: 10
              border.color: "black"
              color: "royalblue"
      
         Racket {
             id: redRacket
             x: 630; y: 100
             color: "red"
             property int  rOldy: y
             property bool rYmovement: false
             onYChanged: {
                 rYmovement = y - rOldy < 0 ? true : false
                 rOldy = y
             }
         }
      
         Racket {
             id: blackRacket
             x: 50; y: 100
             color: "black"
             property int  bOldy: y
             property bool bYmovement: false
             onYChanged: {
                 bYmovement = y - bOldy < 0 ? true : false
                 bOldy = y
             }
         }
      
         Ball {
             id: ball
             x: table.width/2 - 50
             y: table.height/2
             property double ran: Math.random() + 0.5
             property double xincrement: ran
             property double yincrement: ran
         }
      
         Column {
             spacing: 3
             x: table.width/2
             y: 10
                Repeater {
                  model: 21
                   delegate: Rectangle {
                            width: 5
                            height: 20
                            color: "white"
                         }
                   }
             }
      
         Timer {
           interval: 15; repeat: true; running: true
      
              onTriggered: {
                  ball.x = ball.x + (ball.xincrement * 2.0);
                  ball.y = ball.y + (ball.yincrement * 2.0);
      
                  if((ball.x + ball.width  >= redRacket.x)  &&
                    ((ball.y + ball.height >= redRacket.y)  &&
                     (ball.y + ball.height <= redRacket.y + redRacket.height)))
                      if(redRacket.rYmovement) {
                           ball.yincrement *= -1
                           ball.xincrement *= -1
                          redRacket.rYmovement = false
                         }
                       else ball.xincrement *= -1
      
                  if((ball.x - ball.width  <= blackRacket.x)  &&
                    ((ball.y + ball.height >= blackRacket.y)  &&
                     (ball.y + ball.height <= blackRacket.y + blackRacket.height)))
                      if(blackRacket.bYmovement) {
                           ball.yincrement *= -1
                           ball.xincrement *= -1
                          blackRacket.bYmovement = false
                         }
                       else ball.xincrement *= -1
      
                   if(ball.y <= 0 || ball.y + ball.height >= table.height)
                        ball.yincrement *= -1
                 }
             }
          }
       }
      
      
      J.HilkJ 1 Reply Last reply
      0
      • tomyT tomy

        @J.Hilk
        Thanks.
        I tried to make the work done and here is the code.
        I don't use the prior versions of the code (above) but this one.

        Ball.qml and Racket.qml are as before but main.qml is completely as below.

        As you see I haven't used a function and I don't know if it's needed or not.
        If possible please run that code to see its function. I don't think it's flawless.
        The code also to me is very messy. If it can make the work done using little changes, what to do for removing the problems from that please?

        import QtQuick 2.8
        import QtQuick.Window 2.2
        
        Window {
            visible: true
            width: 800
            height: 600
            title: qsTr("The PingPong Game")
        
            Rectangle {
                id: table
                width: 700; height: 500
                border.width: 10
                border.color: "black"
                color: "royalblue"
        
           Racket {
               id: redRacket
               x: 630; y: 100
               color: "red"
               property int  rOldy: y
               property bool rYmovement: false
               onYChanged: {
                   rYmovement = y - rOldy < 0 ? true : false
                   rOldy = y
               }
           }
        
           Racket {
               id: blackRacket
               x: 50; y: 100
               color: "black"
               property int  bOldy: y
               property bool bYmovement: false
               onYChanged: {
                   bYmovement = y - bOldy < 0 ? true : false
                   bOldy = y
               }
           }
        
           Ball {
               id: ball
               x: table.width/2 - 50
               y: table.height/2
               property double ran: Math.random() + 0.5
               property double xincrement: ran
               property double yincrement: ran
           }
        
           Column {
               spacing: 3
               x: table.width/2
               y: 10
                  Repeater {
                    model: 21
                     delegate: Rectangle {
                              width: 5
                              height: 20
                              color: "white"
                           }
                     }
               }
        
           Timer {
             interval: 15; repeat: true; running: true
        
                onTriggered: {
                    ball.x = ball.x + (ball.xincrement * 2.0);
                    ball.y = ball.y + (ball.yincrement * 2.0);
        
                    if((ball.x + ball.width  >= redRacket.x)  &&
                      ((ball.y + ball.height >= redRacket.y)  &&
                       (ball.y + ball.height <= redRacket.y + redRacket.height)))
                        if(redRacket.rYmovement) {
                             ball.yincrement *= -1
                             ball.xincrement *= -1
                            redRacket.rYmovement = false
                           }
                         else ball.xincrement *= -1
        
                    if((ball.x - ball.width  <= blackRacket.x)  &&
                      ((ball.y + ball.height >= blackRacket.y)  &&
                       (ball.y + ball.height <= blackRacket.y + blackRacket.height)))
                        if(blackRacket.bYmovement) {
                             ball.yincrement *= -1
                             ball.xincrement *= -1
                            blackRacket.bYmovement = false
                           }
                         else ball.xincrement *= -1
        
                     if(ball.y <= 0 || ball.y + ball.height >= table.height)
                          ball.yincrement *= -1
                   }
               }
            }
         }
        
        
        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #22

        @tomy

        to make it a bit cleaner, if you for example moved some stuff to the Ball and Racket qml-files

        //Racket
        import QtQuick 2.8
        
        Rectangle {
            id: root
            width: 15; height: 50
            x: 400; y: 100
            color: "red"
        
            property int oldY: y
            property bool yMovement: false
            onYChanged: {
                yMovement = y - oldY < 0 ? true : false
                oldY = y
            }
        
            MouseArea {
                anchors.fill: parent
                drag.target: root
                drag.axis: Drag.YAxis
                drag.minimumY: 10
                drag.maximumY: 440
            }
        }
        
        //Ball.qml
        import QtQuick 2.8
        
        Rectangle {
            width: 20; height: 20
            x: 250; y: 250
            color: "white"
            radius: width/2
        
            property double ran: Math.random() + 0.5
            property double xincrement: ran
            property double yincrement: ran
        }
        

        Besides that I don't see what the problem is, theres at least 1 bug I run into whilst playing, x) but thats part of coding.

        If you thinks the animation is a but stuttery thats to be expected, you replaced a propertyanimation with a Timer and x/y changes.

        I believe, PropertyAnimation does some internal stuff to make the animation as smooth as possible, a change each refresh frame e.g. Where as with a timer aproeach you are fixed to 5 ms updates and in that you only increase the distance the ball is moved. That gonna look like jumps eventually ;-)


        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

          to make it a bit cleaner, if you for example moved some stuff to the Ball and Racket qml-files

          //Racket
          import QtQuick 2.8
          
          Rectangle {
              id: root
              width: 15; height: 50
              x: 400; y: 100
              color: "red"
          
              property int oldY: y
              property bool yMovement: false
              onYChanged: {
                  yMovement = y - oldY < 0 ? true : false
                  oldY = y
              }
          
              MouseArea {
                  anchors.fill: parent
                  drag.target: root
                  drag.axis: Drag.YAxis
                  drag.minimumY: 10
                  drag.maximumY: 440
              }
          }
          
          //Ball.qml
          import QtQuick 2.8
          
          Rectangle {
              width: 20; height: 20
              x: 250; y: 250
              color: "white"
              radius: width/2
          
              property double ran: Math.random() + 0.5
              property double xincrement: ran
              property double yincrement: ran
          }
          

          Besides that I don't see what the problem is, theres at least 1 bug I run into whilst playing, x) but thats part of coding.

          If you thinks the animation is a but stuttery thats to be expected, you replaced a propertyanimation with a Timer and x/y changes.

          I believe, PropertyAnimation does some internal stuff to make the animation as smooth as possible, a change each refresh frame e.g. Where as with a timer aproeach you are fixed to 5 ms updates and in that you only increase the distance the ball is moved. That gonna look like jumps eventually ;-)

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

          @J.Hilk

          I replaced the PropertyAnimation with Timer because I didn't know how to achieve what I have now without Timer but with PropertyAnimation.
          The Timer works fine with smoothness but in this example I'd changed the interval from 2 to 15 to slow the movement of the ball for better testing.

          The game has defects even in this point unfortunately. And it's the feature of targeting.
          The if(redRacket.rYmovement) conditions code don't work as expected. I should think over them so that they work as needed.
          But a question here, does the y coordinate change relate to the "last" movement of the racket before the ball hits it?

          J.HilkJ 1 Reply Last reply
          0
          • tomyT tomy

            @J.Hilk

            I replaced the PropertyAnimation with Timer because I didn't know how to achieve what I have now without Timer but with PropertyAnimation.
            The Timer works fine with smoothness but in this example I'd changed the interval from 2 to 15 to slow the movement of the ball for better testing.

            The game has defects even in this point unfortunately. And it's the feature of targeting.
            The if(redRacket.rYmovement) conditions code don't work as expected. I should think over them so that they work as needed.
            But a question here, does the y coordinate change relate to the "last" movement of the racket before the ball hits it?

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

            @tomy

            I changed the timer stuff a bit, to make it more readable, what happens

               Timer {
                 interval: 15; repeat: true; running: true
            
                 function hitsRightRacket(){
                     if(ball.x +ball.width >= redRacket.x  && ball.x < redRacket.x + redRacket.width){
                         if(ball.y >= 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){
                         if(ball.y >= blackRacket.y && ball.y <= blackRacket.y+blackRacket.height)
                             return true
                     }
                     return false
                 }
            
                 function hitsRightWall(){
                     if(ball.x +ball.width >= table.width)
                         return true
                     else
                         return false
                 }
            
                 function hitsLeftWall(){
                     if(ball.x <= 0)
                         return true
                     else
                         return false
                 }
            
                 function hitsUpperOrLowerWall(){
                     if(ball.y <= 0 || ball.y + ball.height >= table.height)
                          return true
                     return false
                 }
            
                 property bool lastHitLeft: false
                 property bool lastHitRight: false
            
                    onTriggered: {
                        if(hitsRightWall()){
                            console.log("Point Left Side")
                            running = false
                        }else if(hitsLeftWall()){
                            console.log("Point Right Side")
                            running = false
                        }else if(hitsLeftRacket() && !lastHitLeft){
                            console.log("Hits Black Racket",blackRacket.yMovement)
                            lastHitLeft = true
                            lastHitRight = false
                            if(blackRacket.yMovement){
                                ball.yincrement *= -1
                                ball.xincrement *= -1
                             }else
                                ball.xincrement *= -1
                        }else if(hitsRightRacket() && !lastHitRight){
                            console.log("Hits Red Racket",redRacket.yMovement)
                            lastHitLeft = false
                            lastHitRight = true
                            if(redRacket.yMovement) {
                                 ball.yincrement *= -1
                                 ball.xincrement *= -1
                               }
                             else ball.xincrement *= -1
                        }else if(hitsUpperOrLowerWall())
                            ball.yincrement *= -1
            
                        //Move Ball
                        ball.x = ball.x + (ball.xincrement * 2.0);
                        ball.y = ball.y + (ball.yincrement * 2.0);
                       }
                   }
            

            This showed me that you'll need a better case handleing for ball movement and racket movement,

            • ball moves towards y = 0 and Racket moves towards y = 0
            • ball moves towards y = 0 and Racket moves towards y = table height
            • ball moves towards y = table and Racket moves towards y = 0
            • ball moves towards y = table Racket moves towards y = table height

            currently you're only checking in what direction the racket moved,


            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

              I changed the timer stuff a bit, to make it more readable, what happens

                 Timer {
                   interval: 15; repeat: true; running: true
              
                   function hitsRightRacket(){
                       if(ball.x +ball.width >= redRacket.x  && ball.x < redRacket.x + redRacket.width){
                           if(ball.y >= 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){
                           if(ball.y >= blackRacket.y && ball.y <= blackRacket.y+blackRacket.height)
                               return true
                       }
                       return false
                   }
              
                   function hitsRightWall(){
                       if(ball.x +ball.width >= table.width)
                           return true
                       else
                           return false
                   }
              
                   function hitsLeftWall(){
                       if(ball.x <= 0)
                           return true
                       else
                           return false
                   }
              
                   function hitsUpperOrLowerWall(){
                       if(ball.y <= 0 || ball.y + ball.height >= table.height)
                            return true
                       return false
                   }
              
                   property bool lastHitLeft: false
                   property bool lastHitRight: false
              
                      onTriggered: {
                          if(hitsRightWall()){
                              console.log("Point Left Side")
                              running = false
                          }else if(hitsLeftWall()){
                              console.log("Point Right Side")
                              running = false
                          }else if(hitsLeftRacket() && !lastHitLeft){
                              console.log("Hits Black Racket",blackRacket.yMovement)
                              lastHitLeft = true
                              lastHitRight = false
                              if(blackRacket.yMovement){
                                  ball.yincrement *= -1
                                  ball.xincrement *= -1
                               }else
                                  ball.xincrement *= -1
                          }else if(hitsRightRacket() && !lastHitRight){
                              console.log("Hits Red Racket",redRacket.yMovement)
                              lastHitLeft = false
                              lastHitRight = true
                              if(redRacket.yMovement) {
                                   ball.yincrement *= -1
                                   ball.xincrement *= -1
                                 }
                               else ball.xincrement *= -1
                          }else if(hitsUpperOrLowerWall())
                              ball.yincrement *= -1
              
                          //Move Ball
                          ball.x = ball.x + (ball.xincrement * 2.0);
                          ball.y = ball.y + (ball.yincrement * 2.0);
                         }
                     }
              

              This showed me that you'll need a better case handleing for ball movement and racket movement,

              • ball moves towards y = 0 and Racket moves towards y = 0
              • ball moves towards y = 0 and Racket moves towards y = table height
              • ball moves towards y = table and Racket moves towards y = 0
              • ball moves towards y = table Racket moves towards y = table height

              currently you're only checking in what direction the racket moved,

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

              @J.Hilk
              Hi,
              Thank you for your assistance.

              If we divide the task into part I and II, the first part I think is almost done! Please take a look at the code below and if possible please run the program on your system. It works fine for me.

              In part I, I need two extra components I think: one, a series of buttons for starting, resuming and finishing the game when it's not over yet. And second, some sound for goals and when a player wins the game.
              If we can complete part I, I assume part II will be about networking! :)

              Ball.qml:

              import QtQuick 2.9
              
              Rectangle {
                  width: 12; height: 12
                  x: 250; y: 250
                  color: "white"
                  radius: width/2
                  property double ran: Math.random() + 0.5
                  property double xincrement: ran
                  property double yincrement: ran
              }
              
              

              Counter.qml:

              import QtQuick 2.9
              
              Rectangle {
                  width: 40; height: 50
                  color: "lightskyblue"
                  property int count: 0
              
                  Text {
                      id: text
                      anchors.centerIn: parent
                      text: count.toString()
                      color: "gray"
                      font.bold: true
                      font.pixelSize: 30
                  }
              }
              

              Light.qml:

              import QtQuick 2.9
              
              Rectangle {
                  width: 50; height: 50
                  border.width: 5
                  border.color: "silver"
                  radius: width/2
                  property bool start: false
              }
              
              

              Racket.qml:

              import QtQuick 2.9
              
              Rectangle {
                  id: root
                  width: 12; height: 40
                  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
                      drag.target: root
                      drag.axis: Drag.YAxis
                      drag.minimumY: table.y - 20
                      drag.maximumY: table.y + table.height - 60
                  }
              }
              
              

              WinBox.qml:

              import QtQuick 2.9
              
              Text {
                   width: 50; height: 50
                   text: "WINNER"
                   color: "royalblue"
                   font.bold: true
                   font.pixelSize: 40
                   visible: false
              }
              

              main.qml:

              import QtQuick 2.9
              import QtQuick.Window 2.2
              
              Window {
                  visible: true
                  width: 820
                  height: 620
                  title: qsTr("The PingPong Game")
                  color: "gray"
              
                  Rectangle {
                      x: 10; y: 10
                      width: 800; height: 500
                      color: "white"
                  }
              
                  Rectangle {
                      id: table
                      x: 20; y: 20
                      width: 780; height: 480
                      color: "royalblue"
                      property int count: 1
                      property bool turn: false
                      property bool lightState: false
              
                      Racket {
                          id: redRacket
                          x: table.width - 30; y: 100
                          color: "red"
                      }
              
                      Racket {
                          id: blackRacket
                          x: table.x; y: 100
                          color: "black"
                      }
              
                      Ball {
                          id: ball
                          x: table.width/2
                          y: table.height/2
                      }
              
                      Column {
                          spacing: 3
                          x: table.width/2
                          Repeater {
                              model: 21
                              delegate: Rectangle {
                                  width: 5
                                  height: 20
                                  color: "white"
                              }
                          }
                      }
              
                      Counter {
                          id: rightCounter
                          x: table.width / 2 + 90
                          y: 50
                      }
              
                      Counter {
                          id: leftCounter
                          x: table.width / 4 + 70
                          y: 50
                      }
              
                      Light {
                          id: rightLight
                          x: table.width/2 + 80
                          y: table.height + 20
                          color: "silver"
                      }
              
                      Light {
                          id: leftLight
                          x: table.width/2 - 120
                          y: table.height + 20
                          color: "lime"
                      }
              
                      WinBox {
                          id: rightWin
                          x: table.width/2 + 160
                          y: table.height + 40
                      }
              
                      WinBox {
                          id: leftWin
                          x: table.width/2 - 350
                          y: table.height + 40
                      }
              
                      Timer {
                          interval: 40; repeat: true; running: true
              
                          onTriggered: {
                              redRacket.yUwards = false
                              redRacket.yDwards = false
                              blackRacket.yUwards = false
                              blackRacket.yDwards = false
                          }
                      }
              
                      Timer {
                          id: out_timer
                          interval: 1; repeat: false; running: false
              
                          function lightChange() {
                              if (table.lightState) {
                                  rightLight.color = "silver"
                                  leftLight.color= "lime"
                                }
              
                              else {
                                  rightLight.color = "lime"
                                  leftLight.color= "silver"
                                }
                              table.lightState = !table.lightState
                          }
              
                          onTriggered: {
                              ball.xincrement = Math.random() + 0.5
                              ball.yincrement = Math.random() + 0.5
              
                              if( table.count % 5 == 0) {
                                  table.turn = !table.turn
                                  lightChange()
                              }
              
              
                               if(table.turn)
                                  ball.xincrement *= -1
              
                              ball.x = table.width/2
                              ball.y = table.height/2
              
                              if (ball.yincrement > 1.1)
                                  ball.yincrement *= -1
              
                              in_timer.restart()
                              table.count++
                          }
                      }
              
                      Timer {
                          id: in_timer
                          interval: duration; repeat: true; running: true
                          property int duration: 2
              
                          function hitsRightWall() {
                              if (ball.x + ball.width >= table.width)
                                  return true
                              else return false
                          }
              
                          function hitsLeftWall() {
                              if(ball.x <= 0) return true
                              else return false
                          }
              
                          property bool lastHitLeft: false
                          property bool lastHitRight: false
              
                          onTriggered: {
              
                              if(hitsRightWall()) {
                                  in_timer.stop()
                                  leftCounter.count++
                                  out_timer.interval = 2000
                                  out_timer.running = true
                              }
              
                              else if(hitsLeftWall()) {
                                  in_timer.stop()
                                  rightCounter.count++
                                  out_timer.interval = 2000
                                  out_timer.running = true
                              }
              
                              ball.x = ball.x + (ball.xincrement * 2.0);
                              ball.y = ball.y + (ball.yincrement * 2.0);
              
                              if ((ball.x + ball.width >= redRacket.x  &&
                                   ball.x < redRacket.x + redRacket.width / 3) &&
                                      (ball.y + ball.height >= redRacket.y - 10 &&
                                       ball.y <= redRacket.y + redRacket.height))
                              {
                                  if(redRacket.yUwards) {
                                      if(ball.yincrement == 0)
                                          ball.yincrement = -ball.ran
                                      else if(ball.yincrement > 0)
                                          ball.yincrement *= -1
                                      interval = duration/2
                                  }
                                  else if (redRacket.yDwards) {
                                      if(ball.yincrement == 0)
                                          ball.yincrement = ball.ran
                                      else if(ball.yincrement < 0)
                                          ball.yincrement *= -1
                                      interval = duration/2
                                  }
                                  else {
                                      ball.yincrement = 0
                                      interval = duration
                                  }
              
                                  ball.xincrement *= -1
                              }
              
                              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))
                              {
                                  if(blackRacket.yUwards) {
                                      if(ball.yincrement == 0)
                                          ball.yincrement = -ball.ran
                                      else if(ball.yincrement > 0)
                                          ball.yincrement *= -1
                                      interval = duration/2
                                  }
                                  else if (blackRacket.yDwards) {
                                      if(ball.yincrement == 0)
                                          ball.yincrement = ball.ran
                                      else if(ball.yincrement < 0)
                                          ball.yincrement *= -1
                                      interval = duration/2
                                  }
                                  else {
                                      ball.yincrement = 0
                                      interval = duration
                                  }
              
                                  ball.xincrement *= -1
                              }
              
                              if(ball.x <= 0 || ball.x + ball.width >= table.width)
                                  ball.xincrement *= (-1);
              
                              if(ball.y <= 0 || ball.y + ball.height >= table.height)
                                  ball.yincrement *= -1
              
                              if(rightCounter.count + leftCounter.count == 21) {
                                     in_timer.stop()
                                  if(rightCounter.count > leftCounter.count)
                                      rightWin.visible = true
                                  else if (rightCounter.count < leftCounter.count)
                                      leftWin.visible = true
                                  else {
                                      rightWin.visible = true
                                      leftWin.visible = true
                                  }
                              }
                          }            
                      }
                  }
              }
              
              
              1 Reply Last reply
              0
              • J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #26

                Looks great! You're defenitly on the right track.

                However I have a bug to report. I managed to catch the ball in the racket. That's the reasdon why I introtuced the 2 properties lastHitLeft and lastHitRight in my previous post. You still have them in your code, but they are not used.
                0_1513750776832_catch.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.

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

                  Looks great! You're defenitly on the right track.

                  However I have a bug to report. I managed to catch the ball in the racket. That's the reasdon why I introtuced the 2 properties lastHitLeft and lastHitRight in my previous post. You still have them in your code, but they are not used.
                  0_1513750776832_catch.PNG

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

                  @J.Hilk
                  Hi, thanks.

                  Well, I laid those factors and ran the code. Unfortunately it made the issue more prominent! The ball passes through the ball obliquely.

                  So I think I must return back to the version without them and the issue is subtle! It happens when a racket tries to hit the ball from the top/down moving downwards/upwards and the ball gets stuck in the upper/lower edge of the racket. I think I should work on this.

                  Previously I was thinking of making the racket thinner to prevent this bug. But I try to find a more logical way.

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

                    Hi,

                    For a while I was trying to use contains(point p), mapFromItem(...) or mapToItem(...). But unfortunately, no success! So I got back to the prior method, which was using the X and Y coordinates as follows.

                    Please run it on your system. It works fine for me. The bug is also solved.
                    But there's another bug!

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

                    I also tried to manipulate the MouseArea in the Racket.qml to cope with that, but no change in the result! :(

                    Please check it and express your idea how to solve that issue.

                    QML files Ball, Counter, Light and Winbox are as before.

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

                    main.qml:

                    import QtQuick 2.9
                    import QtQuick.Window 2.2
                    import QtQuick.Controls 2.1
                    
                    Window {
                        id: window
                        visibility: Window.Maximized
                        title: qsTr("The PingPong Game - A QML Game")
                        color: "gray"
                        
                        Rectangle {
                            id: table
                            width: window.width / 1.15; height: window.height / 1.15
                            x: window.x + 100; y: 10;
                            border.width: 10
                            border.color: "white"
                            color: "royalblue"
                            property int count: 1
                            property bool turn: false
                            property bool lightState: false
                            property double step: 3.0
                            property int duration: 4
                            
                            Racket {
                                id: blackRacket
                                anchors.left: table.left
                                anchors.leftMargin: width * 2
                                y: height
                                color: "black"
                            }
                            Racket {
                                id: redRacket
                                anchors.right: table.right
                                anchors.rightMargin: width * 2
                                y: height
                                color: "red"
                            }
                            
                            
                            Ball {
                                id: ball
                                x: table.width/2
                                y: table.height/2
                            }
                            
                            Column {
                                spacing: 3
                                anchors.centerIn: table
                                anchors.top: table.top
                                Repeater {
                                    model: table.height/(blackRacket.height / 2 + 3)
                                    delegate: Rectangle {
                                        width: 5
                                        height: blackRacket.height / 2
                                        color: "white"
                                    }
                                }
                            }
                            
                            Counter {
                                id: leftCounter
                                x: table.width / 2 - height - 100
                                y: 50
                            }
                            Counter {
                                id: rightCounter
                                x: table.width / 2 + 100
                                y: 50
                            }
                            
                            
                            Light {
                                id: leftLight
                                x: table.width/2 - 280
                                y: table.height + 10
                                color: "lime"
                            }
                            Light {
                                id: rightLight
                                x: table.width/2 + 220
                                y: table.height + 10
                                color: "silver"
                            }
                            
                            WinBox {
                                id: rightWin
                                x: table.width/2 + 380
                                y: table.height + 10
                            }
                            WinBox {
                                id: leftWin
                                x: table.x + 40
                                y: table.height + 10
                            }
                            
                            Button {
                                x: table.width/2 - 45
                                y: table.height + 10
                                
                                contentItem: Text {
                                    id: st_tx
                                    horizontalAlignment: Text.AlignHCenter
                                    verticalAlignment: Text.AlignVCenter
                                    text: qsTr("START")
                                    font.bold: true
                                    font.pixelSize: 20
                                    color: "green"
                                }
                                background: Rectangle {
                                    implicitHeight: 60
                                    implicitWidth: 100
                                    color: "lightGrey"
                                    border.width: 8
                                    border.color: "lightBlue"
                                    radius: 20
                                }
                                onClicked: table.startGame()
                            }
                            Button {
                                x: table.width/2 - 150
                                y: table.height + 10
                                
                                contentItem: Text {
                                    id: pu_tx
                                    horizontalAlignment: Text.AlignHCenter
                                    verticalAlignment: Text.AlignVCenter
                                    text: qsTr("PAUSE")
                                    font.bold: true
                                    font.pixelSize: 20
                                    color: "green"
                                }
                                background: Rectangle {
                                    id: pu_rec
                                    implicitHeight: 60
                                    implicitWidth: 100
                                    color: "lightGrey"
                                    border.width: 8
                                    border.color: "lightBlue"
                                    radius: 20
                                }
                                onClicked: table.pauseGame()
                            }
                            Button {
                                x: table.width/2 + 60
                                y: table.height + 10
                                
                                contentItem: Text {
                                    id: sp_tx
                                    horizontalAlignment: Text.AlignHCenter
                                    verticalAlignment: Text.AlignVCenter
                                    text: qsTr("STOP")
                                    font.bold: true
                                    font.pixelSize: 20
                                    color: "green"
                                }
                                background: Rectangle {
                                    implicitHeight: 60
                                    implicitWidth: 100
                                    color: "lightGrey"
                                    border.width: 8
                                    border.color: "lightBlue"
                                    radius: 20
                                    
                                }
                                onClicked: table.stopGame()
                            }
                            
                            Text {
                                x: window.x; y: table.height + 50
                                color: "white"
                                text: "Ver: 1.1"
                                font.family: "Helvetica"
                                font.pointSize: 15
                            }
                            Text {
                                x: table.width - 200; y: table.height + 50
                                color: "white"
                                text: " Programmed By S.R. Abbasi (Tomy)"
                                font.family: "Helvetica"
                                font.pointSize: 10
                            }
                            
                            function startGame() {
                                st_tx.text = qsTr("START")
                                if (leftWin.visible)
                                    leftWin.visible = false
                                if (rightWin.visible)
                                    rightWin.visible = false
                                in_timer.restart()
                            }
                            function pauseGame() {
                                st_tx.text = qsTr("RESUME")
                                in_timer.running = false
                            }
                            function stopGame() {
                                st_tx.text = qsTr("START")
                                in_timer.running = false
                                rightCounter.count = 0
                                leftCounter.count = 0
                                ball.x = table.width/2
                                ball.y = table.height/2
                                table.count = 1
                                table.turn = false
                                rightLight.color = "silver"
                                leftLight.color = "lime"
                                
                                if(ball.xincrement < 0 )
                                    ball.xincrement *= -1
                            }
                            
                            Timer {
                                interval: 40; repeat: true; running: true
                                
                                onTriggered: {
                                    redRacket.yUwards = false
                                    redRacket.yDwards = false
                                    blackRacket.yUwards = false
                                    blackRacket.yDwards = false
                                }
                            }
                            Timer {
                                id: out_timer
                                interval: 1; repeat: false; running: false
                                
                                function lightChange() {
                                    if (table.lightState) {
                                        rightLight.color = "silver"
                                        leftLight.color= "lime"
                                    }
                                    else {
                                        rightLight.color = "lime"
                                        leftLight.color= "silver"
                                    }
                                    table.lightState = !table.lightState
                                }
                                
                                onTriggered: {
                                    ball.xincrement = Math.random() + 0.5
                                    ball.yincrement = Math.random() + 0.5
                                    
                                    if (table.count % 5 == 0) {
                                        table.turn = !table.turn
                                        lightChange()
                                    }
                                    
                                    if (table.turn)
                                        ball.xincrement *= -1
                                    
                                    ball.x = table.width/2
                                    ball.y = table.height/2
                                    
                                    if (ball.yincrement > 1.1)
                                        ball.yincrement *= -1
                                    
                                    in_timer.restart()
                                    table.count++
                                }
                            }
                            Timer {
                                id: right_return_timer
                                interval: 1; repeat: true; running: false
                                onTriggered: {
                                    ball.x = ball.x + (ball.xincrement * table.step)
                                    ball.y = ball.y + (ball.yincrement * table.step)
                                    if(ball.x + ball.width < redRacket.x) {
                                        running = false
                                        in_timer.running = true
                                    }
                                }
                            }
                            Timer {
                                id: left_return_timer
                                interval: 1; repeat: true; running: false
                                onTriggered: {
                                    ball.x = ball.x + (ball.xincrement * table.step)
                                    ball.y = ball.y + (ball.yincrement * table.step)
                                    if(ball.x > blackRacket.x + blackRacket.width) {
                                        running = false
                                        in_timer.running = true
                                    }
                                }
                            }
                            Timer {
                                id: in_timer
                                interval: table.duration; repeat: true; running: false
                                
                                
                                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))
                                        return true
                                    return false
                                }
                                function hitsUpperOrLowerWall(){
                                    if (ball.y <= 0 || ball.y + ball.height >= table.height)
                                        return true
                                    return false
                                }
                                function hitsRightWall() {
                                    if (ball.x + ball.width >= table.width)
                                        return true
                                    else return false
                                }
                                function hitsLeftWall() {
                                    if (ball.x <= 0) return true
                                    else return false
                                }
                                
                                onTriggered: {
                                    if (hitsRightWall()) {
                                        in_timer.stop()
                                        leftCounter.count++
                                        out_timer.interval = 2000
                                        out_timer.running = true
                                    }
                                    else if (hitsLeftWall()) {
                                        in_timer.stop()
                                        rightCounter.count++
                                        out_timer.interval = 2000
                                        out_timer.running = true
                                    }
                                    else if (hitsRightRacket()) {
                                        if (redRacket.yUwards) {
                                            if (ball.yincrement == 0)
                                                ball.yincrement = -ball.ran
                                            else if (ball.yincrement > 0)
                                                ball.yincrement *= -1
                                            interval = (table.duration/4)
                                        }
                                        else if (redRacket.yDwards) {
                                            if (ball.yincrement == 0)
                                                ball.yincrement = ball.ran
                                            else if (ball.yincrement < 0)
                                                ball.yincrement *= -1
                                            interval = (table.duration/4)
                                        }
                                        else {
                                            ball.yincrement = 0
                                            interval = (table.duration/2)
                                        }
                                        ball.xincrement *= -1
                                        running = false
                                        right_return_timer.running = true
                                    }
                                    else if (hitsLeftRacket()) {
                                        if(blackRacket.yUwards) {
                                            if (ball.yincrement == 0)
                                                ball.yincrement = -ball.ran
                                            else if (ball.yincrement > 0)
                                                ball.yincrement *= -1
                                            interval = (table.duration/4)
                                        }
                                        else if (blackRacket.yDwards) {
                                            if (ball.yincrement == 0)
                                                ball.yincrement = ball.ran
                                            else if (ball.yincrement < 0)
                                                ball.yincrement *= -1
                                            interval = (table.duration/4)
                                        }
                                        else {
                                            ball.yincrement = 0
                                            interval = (table.duration/2)
                                        }
                                        ball.xincrement *= -1
                                        running = false
                                        left_return_timer.running = true
                                    }
                                    else if (hitsUpperOrLowerWall())
                                        ball.yincrement *= -1
                                    
                                    // Move Ball
                                    ball.x = ball.x + (ball.xincrement * table.step);
                                    ball.y = ball.y + (ball.yincrement * table.step);
                                    
                                    if(rightCounter.count + leftCounter.count == 21) {
                                        in_timer.stop()
                                        if (rightCounter.count > leftCounter.count)
                                            rightWin.visible = true
                                        else
                                            leftWin.visible = true
                                    }
                                }
                            }
                        }
                    }
                    
                    
                    J.HilkJ 1 Reply Last reply
                    1
                    • tomyT tomy

                      Hi,

                      For a while I was trying to use contains(point p), mapFromItem(...) or mapToItem(...). But unfortunately, no success! So I got back to the prior method, which was using the X and Y coordinates as follows.

                      Please run it on your system. It works fine for me. The bug is also solved.
                      But there's another bug!

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

                      I also tried to manipulate the MouseArea in the Racket.qml to cope with that, but no change in the result! :(

                      Please check it and express your idea how to solve that issue.

                      QML files Ball, Counter, Light and Winbox are as before.

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

                      main.qml:

                      import QtQuick 2.9
                      import QtQuick.Window 2.2
                      import QtQuick.Controls 2.1
                      
                      Window {
                          id: window
                          visibility: Window.Maximized
                          title: qsTr("The PingPong Game - A QML Game")
                          color: "gray"
                          
                          Rectangle {
                              id: table
                              width: window.width / 1.15; height: window.height / 1.15
                              x: window.x + 100; y: 10;
                              border.width: 10
                              border.color: "white"
                              color: "royalblue"
                              property int count: 1
                              property bool turn: false
                              property bool lightState: false
                              property double step: 3.0
                              property int duration: 4
                              
                              Racket {
                                  id: blackRacket
                                  anchors.left: table.left
                                  anchors.leftMargin: width * 2
                                  y: height
                                  color: "black"
                              }
                              Racket {
                                  id: redRacket
                                  anchors.right: table.right
                                  anchors.rightMargin: width * 2
                                  y: height
                                  color: "red"
                              }
                              
                              
                              Ball {
                                  id: ball
                                  x: table.width/2
                                  y: table.height/2
                              }
                              
                              Column {
                                  spacing: 3
                                  anchors.centerIn: table
                                  anchors.top: table.top
                                  Repeater {
                                      model: table.height/(blackRacket.height / 2 + 3)
                                      delegate: Rectangle {
                                          width: 5
                                          height: blackRacket.height / 2
                                          color: "white"
                                      }
                                  }
                              }
                              
                              Counter {
                                  id: leftCounter
                                  x: table.width / 2 - height - 100
                                  y: 50
                              }
                              Counter {
                                  id: rightCounter
                                  x: table.width / 2 + 100
                                  y: 50
                              }
                              
                              
                              Light {
                                  id: leftLight
                                  x: table.width/2 - 280
                                  y: table.height + 10
                                  color: "lime"
                              }
                              Light {
                                  id: rightLight
                                  x: table.width/2 + 220
                                  y: table.height + 10
                                  color: "silver"
                              }
                              
                              WinBox {
                                  id: rightWin
                                  x: table.width/2 + 380
                                  y: table.height + 10
                              }
                              WinBox {
                                  id: leftWin
                                  x: table.x + 40
                                  y: table.height + 10
                              }
                              
                              Button {
                                  x: table.width/2 - 45
                                  y: table.height + 10
                                  
                                  contentItem: Text {
                                      id: st_tx
                                      horizontalAlignment: Text.AlignHCenter
                                      verticalAlignment: Text.AlignVCenter
                                      text: qsTr("START")
                                      font.bold: true
                                      font.pixelSize: 20
                                      color: "green"
                                  }
                                  background: Rectangle {
                                      implicitHeight: 60
                                      implicitWidth: 100
                                      color: "lightGrey"
                                      border.width: 8
                                      border.color: "lightBlue"
                                      radius: 20
                                  }
                                  onClicked: table.startGame()
                              }
                              Button {
                                  x: table.width/2 - 150
                                  y: table.height + 10
                                  
                                  contentItem: Text {
                                      id: pu_tx
                                      horizontalAlignment: Text.AlignHCenter
                                      verticalAlignment: Text.AlignVCenter
                                      text: qsTr("PAUSE")
                                      font.bold: true
                                      font.pixelSize: 20
                                      color: "green"
                                  }
                                  background: Rectangle {
                                      id: pu_rec
                                      implicitHeight: 60
                                      implicitWidth: 100
                                      color: "lightGrey"
                                      border.width: 8
                                      border.color: "lightBlue"
                                      radius: 20
                                  }
                                  onClicked: table.pauseGame()
                              }
                              Button {
                                  x: table.width/2 + 60
                                  y: table.height + 10
                                  
                                  contentItem: Text {
                                      id: sp_tx
                                      horizontalAlignment: Text.AlignHCenter
                                      verticalAlignment: Text.AlignVCenter
                                      text: qsTr("STOP")
                                      font.bold: true
                                      font.pixelSize: 20
                                      color: "green"
                                  }
                                  background: Rectangle {
                                      implicitHeight: 60
                                      implicitWidth: 100
                                      color: "lightGrey"
                                      border.width: 8
                                      border.color: "lightBlue"
                                      radius: 20
                                      
                                  }
                                  onClicked: table.stopGame()
                              }
                              
                              Text {
                                  x: window.x; y: table.height + 50
                                  color: "white"
                                  text: "Ver: 1.1"
                                  font.family: "Helvetica"
                                  font.pointSize: 15
                              }
                              Text {
                                  x: table.width - 200; y: table.height + 50
                                  color: "white"
                                  text: " Programmed By S.R. Abbasi (Tomy)"
                                  font.family: "Helvetica"
                                  font.pointSize: 10
                              }
                              
                              function startGame() {
                                  st_tx.text = qsTr("START")
                                  if (leftWin.visible)
                                      leftWin.visible = false
                                  if (rightWin.visible)
                                      rightWin.visible = false
                                  in_timer.restart()
                              }
                              function pauseGame() {
                                  st_tx.text = qsTr("RESUME")
                                  in_timer.running = false
                              }
                              function stopGame() {
                                  st_tx.text = qsTr("START")
                                  in_timer.running = false
                                  rightCounter.count = 0
                                  leftCounter.count = 0
                                  ball.x = table.width/2
                                  ball.y = table.height/2
                                  table.count = 1
                                  table.turn = false
                                  rightLight.color = "silver"
                                  leftLight.color = "lime"
                                  
                                  if(ball.xincrement < 0 )
                                      ball.xincrement *= -1
                              }
                              
                              Timer {
                                  interval: 40; repeat: true; running: true
                                  
                                  onTriggered: {
                                      redRacket.yUwards = false
                                      redRacket.yDwards = false
                                      blackRacket.yUwards = false
                                      blackRacket.yDwards = false
                                  }
                              }
                              Timer {
                                  id: out_timer
                                  interval: 1; repeat: false; running: false
                                  
                                  function lightChange() {
                                      if (table.lightState) {
                                          rightLight.color = "silver"
                                          leftLight.color= "lime"
                                      }
                                      else {
                                          rightLight.color = "lime"
                                          leftLight.color= "silver"
                                      }
                                      table.lightState = !table.lightState
                                  }
                                  
                                  onTriggered: {
                                      ball.xincrement = Math.random() + 0.5
                                      ball.yincrement = Math.random() + 0.5
                                      
                                      if (table.count % 5 == 0) {
                                          table.turn = !table.turn
                                          lightChange()
                                      }
                                      
                                      if (table.turn)
                                          ball.xincrement *= -1
                                      
                                      ball.x = table.width/2
                                      ball.y = table.height/2
                                      
                                      if (ball.yincrement > 1.1)
                                          ball.yincrement *= -1
                                      
                                      in_timer.restart()
                                      table.count++
                                  }
                              }
                              Timer {
                                  id: right_return_timer
                                  interval: 1; repeat: true; running: false
                                  onTriggered: {
                                      ball.x = ball.x + (ball.xincrement * table.step)
                                      ball.y = ball.y + (ball.yincrement * table.step)
                                      if(ball.x + ball.width < redRacket.x) {
                                          running = false
                                          in_timer.running = true
                                      }
                                  }
                              }
                              Timer {
                                  id: left_return_timer
                                  interval: 1; repeat: true; running: false
                                  onTriggered: {
                                      ball.x = ball.x + (ball.xincrement * table.step)
                                      ball.y = ball.y + (ball.yincrement * table.step)
                                      if(ball.x > blackRacket.x + blackRacket.width) {
                                          running = false
                                          in_timer.running = true
                                      }
                                  }
                              }
                              Timer {
                                  id: in_timer
                                  interval: table.duration; repeat: true; running: false
                                  
                                  
                                  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))
                                          return true
                                      return false
                                  }
                                  function hitsUpperOrLowerWall(){
                                      if (ball.y <= 0 || ball.y + ball.height >= table.height)
                                          return true
                                      return false
                                  }
                                  function hitsRightWall() {
                                      if (ball.x + ball.width >= table.width)
                                          return true
                                      else return false
                                  }
                                  function hitsLeftWall() {
                                      if (ball.x <= 0) return true
                                      else return false
                                  }
                                  
                                  onTriggered: {
                                      if (hitsRightWall()) {
                                          in_timer.stop()
                                          leftCounter.count++
                                          out_timer.interval = 2000
                                          out_timer.running = true
                                      }
                                      else if (hitsLeftWall()) {
                                          in_timer.stop()
                                          rightCounter.count++
                                          out_timer.interval = 2000
                                          out_timer.running = true
                                      }
                                      else if (hitsRightRacket()) {
                                          if (redRacket.yUwards) {
                                              if (ball.yincrement == 0)
                                                  ball.yincrement = -ball.ran
                                              else if (ball.yincrement > 0)
                                                  ball.yincrement *= -1
                                              interval = (table.duration/4)
                                          }
                                          else if (redRacket.yDwards) {
                                              if (ball.yincrement == 0)
                                                  ball.yincrement = ball.ran
                                              else if (ball.yincrement < 0)
                                                  ball.yincrement *= -1
                                              interval = (table.duration/4)
                                          }
                                          else {
                                              ball.yincrement = 0
                                              interval = (table.duration/2)
                                          }
                                          ball.xincrement *= -1
                                          running = false
                                          right_return_timer.running = true
                                      }
                                      else if (hitsLeftRacket()) {
                                          if(blackRacket.yUwards) {
                                              if (ball.yincrement == 0)
                                                  ball.yincrement = -ball.ran
                                              else if (ball.yincrement > 0)
                                                  ball.yincrement *= -1
                                              interval = (table.duration/4)
                                          }
                                          else if (blackRacket.yDwards) {
                                              if (ball.yincrement == 0)
                                                  ball.yincrement = ball.ran
                                              else if (ball.yincrement < 0)
                                                  ball.yincrement *= -1
                                              interval = (table.duration/4)
                                          }
                                          else {
                                              ball.yincrement = 0
                                              interval = (table.duration/2)
                                          }
                                          ball.xincrement *= -1
                                          running = false
                                          left_return_timer.running = true
                                      }
                                      else if (hitsUpperOrLowerWall())
                                          ball.yincrement *= -1
                                      
                                      // Move Ball
                                      ball.x = ball.x + (ball.xincrement * table.step);
                                      ball.y = ball.y + (ball.yincrement * table.step);
                                      
                                      if(rightCounter.count + leftCounter.count == 21) {
                                          in_timer.stop()
                                          if (rightCounter.count > leftCounter.count)
                                              rightWin.visible = true
                                          else
                                              leftWin.visible = true
                                      }
                                  }
                              }
                          }
                      }
                      
                      
                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #29

                      Hi @tomy , sorry for the late response.

                      I had a lengthly break, sickness and holiday - thankfully not overlapping. But I'm back now and will take a look later today. I actually managed not to touch my laptop during that time, that was difficult I'll tell ya.

                      Any progress in the last 23 days ?

                      Greetings.


                      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
                      2
                      • J.HilkJ J.Hilk

                        Hi @tomy , sorry for the late response.

                        I had a lengthly break, sickness and holiday - thankfully not overlapping. But I'm back now and will take a look later today. I actually managed not to touch my laptop during that time, that was difficult I'll tell ya.

                        Any progress in the last 23 days ?

                        Greetings.

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

                        @J.Hilk
                        Hi J.Hilk, welcome back. :)
                        I'm very glad that your sickness and holiday haven't had overlapping. :)
                        I hope you're very well now. And Happy New Year to you. :)

                        I see and it's OK. I'm appreciative for your assistance. :) Thanks.
                        Welcome back once again.

                        Any progress in the last 23 days ?

                        That last version was actually modified many times. :) That is, each time I modified it and edited the code here in that last version making it the most recent one for you when you'll get back.

                        The problem was that and I found no remedy so I thought of using a ParallelAnimation as the tool for moving the ball hoping it resolves the issue with the effect of moving the rackets on the ball's movement.

                        I'm still working on it and today or tomorrow will test this new version and post it here too. Can it be a good solution to the problem in your point of view please?

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

                          Well, to cope with that problem I tried Animations in the code the way below.
                          Other components are as before and here is the code after the stopGame() function in main.qml:

                          ...
                          ParallelAnimation {
                                     id: anim
                                     NumberAnimation {
                                         target: ball
                                         properties: "x"
                                         to: in_timer.xMove
                                     }
                                     NumberAnimation {
                                         target: ball
                                         properties: "y"
                                         to: in_timer.yMove
                                     }
                                 }
                                 
                                 Timer {
                                     interval: 40; repeat: true; running: true
                                     
                                     onTriggered: {
                                         redRacket.yUwards = false
                                         redRacket.yDwards = false
                                         blackRacket.yUwards = false
                                         blackRacket.yDwards = false
                                     }
                                 }
                                 Timer {
                                     id: out_timer
                                     interval: 1; repeat: false; running: false
                                     
                                     function lightChange() {
                                         if (table.lightState) {
                                             rightLight.color = "silver"
                                             leftLight.color= "lime"
                                         }
                                         else {
                                             rightLight.color = "lime"
                                             leftLight.color= "silver"
                                         }
                                         table.lightState = !table.lightState
                                     }
                                     
                                     onTriggered: {
                                         ball.xincrement = Math.random() + 0.5
                                         ball.yincrement = Math.random() + 0.5
                                         
                                         if (table.count % 5 == 0) {
                                             table.turn = !table.turn
                                             lightChange()
                                         }
                                         
                                         if (table.turn)
                                             ball.xincrement *= -1
                                         
                                         ball.x = table.width/2
                                         ball.y = table.height/2
                                         
                                         if (ball.yincrement > 1.1)
                                             ball.yincrement *= -1
                                         
                                         in_timer.restart()
                                         table.count++
                                     }
                                 }
                                 Timer {
                                     id: right_return_timer
                                     interval: 1; repeat: true; running: false
                                     onTriggered: {
                                         in_timer.xMove += ball.xincrement * table.step
                                         in_timer.yMove += ball.yincrement * table.step
                                         anim.restart()
                                         if(ball.x + ball.width < redRacket.x) {
                                             running = false
                                             in_timer.running = true
                                         }
                                     }
                                 }
                                 Timer {
                                     id: left_return_timer
                                     interval: 1; repeat: true; running: false
                                     onTriggered: {
                                         in_timer.xMove += ball.xincrement * table.step
                                         in_timer.yMove += ball.yincrement * table.step
                                         anim.restart()
                                         if(ball.x > blackRacket.x + blackRacket.width) {
                                             running = false
                                             in_timer.running = true
                                         }
                                     }
                                 }
                                 Timer {
                                     id: in_timer
                                     interval: table.duration; repeat: true; running: false
                                     property double xMove: ball.x
                                     property double yMove: ball.y
                                     
                                     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))
                                             return true
                                         return false
                                     }
                                     function hitsUpperOrLowerWall(){
                                         if (ball.y <= 0)
                                             return true
                                         else if (ball.y + ball.height >= table.height)
                                             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
                                         else return false
                                     }
                                     
                                     onTriggered: {
                                         if (hitsRightWall()) {
                                             stop()
                                             leftCounter.count++
                                             out_timer.interval = 2000
                                             out_timer.running = true
                                         }
                                         else if (hitsLeftWall()) {
                                             stop()
                                             rightCounter.count++
                                             out_timer.interval = 2000
                                             out_timer.running = true
                                         }
                                         else if (hitsRightRacket()) {
                                             if (redRacket.yUwards) {
                                                 if (ball.yincrement == 0)
                                                     ball.yincrement = -ball.ran
                                                 else if (ball.yincrement > 0)
                                                     ball.yincrement = ball.yincrement > 0 ?
                                                                 -ball.yincrement: ball.yincrement
                                                 interval = (table.duration/4)
                                             }
                                             else if (redRacket.yDwards) {
                                                 if (ball.yincrement == 0)
                                                     ball.yincrement = ball.ran
                                                 else if (ball.yincrement < 0)
                                                     ball.yincrement = ball.yincrement > 0 ?
                                                                 -ball.yincrement: ball.yincrement
                                                 interval = (table.duration/4)
                                             }
                                             else {
                                                 ball.yincrement = 0
                                                 interval = (table.duration/2)
                                             }
                                             ball.xincrement = ball.xincrement > 0 ?
                                                         -ball.xincrement: ball.xincrement
                                             running = false
                                             right_return_timer.running = true
                                         }
                                         else if (hitsLeftRacket()) {
                                             if(blackRacket.yUwards) {
                                                 if (ball.yincrement == 0)
                                                     ball.yincrement = -ball.ran
                                                 else if (ball.yincrement > 0)
                                                     ball.yincrement = ball.yincrement > 0 ?
                                                                 -ball.yincrement: ball.yincrement
                                                 interval = (table.duration/4)
                                             }
                                             else if (blackRacket.yDwards) {
                                                 if (ball.yincrement == 0)
                                                     ball.yincrement = ball.ran
                                                 else if (ball.yincrement < 0)
                                                     ball.yincrement = ball.yincrement > 0 ?
                                                                 -ball.yincrement: ball.yincrement
                                                 interval = (table.duration/4)
                                             }
                                             else {
                                                 ball.yincrement = 0
                                                 interval = (table.duration/2)
                                             }
                                             ball.xincrement = ball.xincrement > 0 ?
                                                         -ball.xincrement: ball.xincrement
                                             running = false
                                             left_return_timer.running = true
                                         }
                                         else if (hitsUpperOrLowerWall())
                                             ball.yincrement = ball.yincrement > 0 ?
                                                         -ball.yincrement: ball.yincrement
                                         
                                         // Move Ball
                                         xMove += (ball.xincrement * table.step);
                                         yMove += (ball.yincrement * table.step);
                                         anim.restart()
                                         
                                         if(rightCounter.count + leftCounter.count == 21) {
                                             stop()
                                             if (rightCounter.count > leftCounter.count)
                                                 rightWin.visible = true
                                             else
                                                 leftWin.visible = true
                                         }
                                     }
                                 }
                             }
                          }
                          

                          This code also has several problems! One of them is that the ball doesn't stop when it hits the right or left wall. I tired several statements, like:
                          stop()
                          in_timer.stop()
                          running = false
                          anim.stop()
                          but neither works!

                          J.HilkJ 1 Reply Last reply
                          0
                          • tomyT tomy

                            Well, to cope with that problem I tried Animations in the code the way below.
                            Other components are as before and here is the code after the stopGame() function in main.qml:

                            ...
                            ParallelAnimation {
                                       id: anim
                                       NumberAnimation {
                                           target: ball
                                           properties: "x"
                                           to: in_timer.xMove
                                       }
                                       NumberAnimation {
                                           target: ball
                                           properties: "y"
                                           to: in_timer.yMove
                                       }
                                   }
                                   
                                   Timer {
                                       interval: 40; repeat: true; running: true
                                       
                                       onTriggered: {
                                           redRacket.yUwards = false
                                           redRacket.yDwards = false
                                           blackRacket.yUwards = false
                                           blackRacket.yDwards = false
                                       }
                                   }
                                   Timer {
                                       id: out_timer
                                       interval: 1; repeat: false; running: false
                                       
                                       function lightChange() {
                                           if (table.lightState) {
                                               rightLight.color = "silver"
                                               leftLight.color= "lime"
                                           }
                                           else {
                                               rightLight.color = "lime"
                                               leftLight.color= "silver"
                                           }
                                           table.lightState = !table.lightState
                                       }
                                       
                                       onTriggered: {
                                           ball.xincrement = Math.random() + 0.5
                                           ball.yincrement = Math.random() + 0.5
                                           
                                           if (table.count % 5 == 0) {
                                               table.turn = !table.turn
                                               lightChange()
                                           }
                                           
                                           if (table.turn)
                                               ball.xincrement *= -1
                                           
                                           ball.x = table.width/2
                                           ball.y = table.height/2
                                           
                                           if (ball.yincrement > 1.1)
                                               ball.yincrement *= -1
                                           
                                           in_timer.restart()
                                           table.count++
                                       }
                                   }
                                   Timer {
                                       id: right_return_timer
                                       interval: 1; repeat: true; running: false
                                       onTriggered: {
                                           in_timer.xMove += ball.xincrement * table.step
                                           in_timer.yMove += ball.yincrement * table.step
                                           anim.restart()
                                           if(ball.x + ball.width < redRacket.x) {
                                               running = false
                                               in_timer.running = true
                                           }
                                       }
                                   }
                                   Timer {
                                       id: left_return_timer
                                       interval: 1; repeat: true; running: false
                                       onTriggered: {
                                           in_timer.xMove += ball.xincrement * table.step
                                           in_timer.yMove += ball.yincrement * table.step
                                           anim.restart()
                                           if(ball.x > blackRacket.x + blackRacket.width) {
                                               running = false
                                               in_timer.running = true
                                           }
                                       }
                                   }
                                   Timer {
                                       id: in_timer
                                       interval: table.duration; repeat: true; running: false
                                       property double xMove: ball.x
                                       property double yMove: ball.y
                                       
                                       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))
                                               return true
                                           return false
                                       }
                                       function hitsUpperOrLowerWall(){
                                           if (ball.y <= 0)
                                               return true
                                           else if (ball.y + ball.height >= table.height)
                                               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
                                           else return false
                                       }
                                       
                                       onTriggered: {
                                           if (hitsRightWall()) {
                                               stop()
                                               leftCounter.count++
                                               out_timer.interval = 2000
                                               out_timer.running = true
                                           }
                                           else if (hitsLeftWall()) {
                                               stop()
                                               rightCounter.count++
                                               out_timer.interval = 2000
                                               out_timer.running = true
                                           }
                                           else if (hitsRightRacket()) {
                                               if (redRacket.yUwards) {
                                                   if (ball.yincrement == 0)
                                                       ball.yincrement = -ball.ran
                                                   else if (ball.yincrement > 0)
                                                       ball.yincrement = ball.yincrement > 0 ?
                                                                   -ball.yincrement: ball.yincrement
                                                   interval = (table.duration/4)
                                               }
                                               else if (redRacket.yDwards) {
                                                   if (ball.yincrement == 0)
                                                       ball.yincrement = ball.ran
                                                   else if (ball.yincrement < 0)
                                                       ball.yincrement = ball.yincrement > 0 ?
                                                                   -ball.yincrement: ball.yincrement
                                                   interval = (table.duration/4)
                                               }
                                               else {
                                                   ball.yincrement = 0
                                                   interval = (table.duration/2)
                                               }
                                               ball.xincrement = ball.xincrement > 0 ?
                                                           -ball.xincrement: ball.xincrement
                                               running = false
                                               right_return_timer.running = true
                                           }
                                           else if (hitsLeftRacket()) {
                                               if(blackRacket.yUwards) {
                                                   if (ball.yincrement == 0)
                                                       ball.yincrement = -ball.ran
                                                   else if (ball.yincrement > 0)
                                                       ball.yincrement = ball.yincrement > 0 ?
                                                                   -ball.yincrement: ball.yincrement
                                                   interval = (table.duration/4)
                                               }
                                               else if (blackRacket.yDwards) {
                                                   if (ball.yincrement == 0)
                                                       ball.yincrement = ball.ran
                                                   else if (ball.yincrement < 0)
                                                       ball.yincrement = ball.yincrement > 0 ?
                                                                   -ball.yincrement: ball.yincrement
                                                   interval = (table.duration/4)
                                               }
                                               else {
                                                   ball.yincrement = 0
                                                   interval = (table.duration/2)
                                               }
                                               ball.xincrement = ball.xincrement > 0 ?
                                                           -ball.xincrement: ball.xincrement
                                               running = false
                                               left_return_timer.running = true
                                           }
                                           else if (hitsUpperOrLowerWall())
                                               ball.yincrement = ball.yincrement > 0 ?
                                                           -ball.yincrement: ball.yincrement
                                           
                                           // Move Ball
                                           xMove += (ball.xincrement * table.step);
                                           yMove += (ball.yincrement * table.step);
                                           anim.restart()
                                           
                                           if(rightCounter.count + leftCounter.count == 21) {
                                               stop()
                                               if (rightCounter.count > leftCounter.count)
                                                   rightWin.visible = true
                                               else
                                                   leftWin.visible = true
                                           }
                                       }
                                   }
                               }
                            }
                            

                            This code also has several problems! One of them is that the ball doesn't stop when it hits the right or left wall. I tired several statements, like:
                            stop()
                            in_timer.stop()
                            running = false
                            anim.stop()
                            but neither works!

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

                            hey @tomy ,

                            I used the code from your previous post, the one before the last one, and brought it on my iphone.

                            For me it works flawlessly, no slowdown at all.

                            Take a look at this video:
                            Video
                            Edit: video link fixed, thanks to @mrjj

                            In fact, the animation/movement of the ball is too fast in my opinion.

                            Did you compile the release version for your android device? Debug versions are ressource demanding and may result in slow animations on old devices.

                            The racket movment invokes a property binding recalculations, that is executed as soon as the event loop returns, I believe.
                            The Movement of the ball and checks are all depending on timers, during the property binding induced calculations those timers may queue up, that then results in a slow Ball-Animation.


                            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
                            • mrjjM Offline
                              mrjjM Offline
                              mrjj
                              Lifetime Qt Champion
                              wrote on last edited by
                              #33

                              Hi
                              Video link didnt work for me but i could extract
                              https://vimeo.com/251451461

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

                                hey @tomy ,

                                I used the code from your previous post, the one before the last one, and brought it on my iphone.

                                For me it works flawlessly, no slowdown at all.

                                Take a look at this video:
                                Video
                                Edit: video link fixed, thanks to @mrjj

                                In fact, the animation/movement of the ball is too fast in my opinion.

                                Did you compile the release version for your android device? Debug versions are ressource demanding and may result in slow animations on old devices.

                                The racket movment invokes a property binding recalculations, that is executed as soon as the event loop returns, I believe.
                                The Movement of the ball and checks are all depending on timers, during the property binding induced calculations those timers may queue up, that then results in a slow Ball-Animation.

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

                                @J.Hilk

                                For me it works flawlessly, no slowdown at all.
                                Take a look at this video:
                                Video
                                Edit: video link fixed, thanks to @mrjj

                                Hallo, Thank you very much.

                                In fact, the animation/movement of the ball is too fast in my opinion.

                                I think by increasing table.duration it will be solved

                                Did you compile the release version for your android device? Debug versions are ressource demanding and may result in slow animations on old devices.

                                Well, when testing on the Desktop kit on my Windows, the program has no problem. It's fine. When switching to "Android for armeabi-v7a (GCC 4.9, Qt 5.10.0 for Android armv7)" kit in both Debug and Release modes, I get these two issues in the Issues window which are the same apparently. I don't know if it's related to the problem on Android devices or not.

                                :-1: warning: "D:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-gcc" is used by qmake, but "D:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-gcc.exe" is configured in the kit.
                                Please update your kit or choose a mkspec for qmake that matches your target environment better.

                                :-1: warning: "D:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-g++" is used by qmake, but "D:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-g++.exe" is configured in the kit.
                                Please update your kit or choose a mkspec for qmake that matches your target environment better.

                                The racket movment invokes a property binding recalculations, that is executed as soon as the event loop returns, I believe.
                                The Movement of the ball and checks are all depending on timers, during the property binding induced calculations those timers may queue up, that then results in a slow Ball-Animation.

                                I'm not sure I can understand it well. Probably it's a too advanced for me. If it can be a lead, is there any solution for that please?

                                J.HilkJ 1 Reply Last reply
                                0
                                • tomyT tomy

                                  @J.Hilk

                                  For me it works flawlessly, no slowdown at all.
                                  Take a look at this video:
                                  Video
                                  Edit: video link fixed, thanks to @mrjj

                                  Hallo, Thank you very much.

                                  In fact, the animation/movement of the ball is too fast in my opinion.

                                  I think by increasing table.duration it will be solved

                                  Did you compile the release version for your android device? Debug versions are ressource demanding and may result in slow animations on old devices.

                                  Well, when testing on the Desktop kit on my Windows, the program has no problem. It's fine. When switching to "Android for armeabi-v7a (GCC 4.9, Qt 5.10.0 for Android armv7)" kit in both Debug and Release modes, I get these two issues in the Issues window which are the same apparently. I don't know if it's related to the problem on Android devices or not.

                                  :-1: warning: "D:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-gcc" is used by qmake, but "D:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-gcc.exe" is configured in the kit.
                                  Please update your kit or choose a mkspec for qmake that matches your target environment better.

                                  :-1: warning: "D:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-g++" is used by qmake, but "D:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-g++.exe" is configured in the kit.
                                  Please update your kit or choose a mkspec for qmake that matches your target environment better.

                                  The racket movment invokes a property binding recalculations, that is executed as soon as the event loop returns, I believe.
                                  The Movement of the ball and checks are all depending on timers, during the property binding induced calculations those timers may queue up, that then results in a slow Ball-Animation.

                                  I'm not sure I can understand it well. Probably it's a too advanced for me. If it can be a lead, is there any solution for that please?

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

                                  @tomy mmh, my Idea would be to marry your QMl-program with a cpp class, that does the heavy stuff.

                                  Your cpp-class could/should have Q_properties that are bound to ball.x and ball.y and right/leftracket position.

                                  That class could emit signals when the ball hits something and trigger the new ball position etc.

                                  Thats a bit more work than I can justify right now, but I'll look into it a bit more during lunch-break ;-)


                                  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
                                  2
                                  • J.HilkJ J.Hilk

                                    @tomy mmh, my Idea would be to marry your QMl-program with a cpp class, that does the heavy stuff.

                                    Your cpp-class could/should have Q_properties that are bound to ball.x and ball.y and right/leftracket position.

                                    That class could emit signals when the ball hits something and trigger the new ball position etc.

                                    Thats a bit more work than I can justify right now, but I'll look into it a bit more during lunch-break ;-)

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

                                    @J.Hilk
                                    Hi, thank you for your suggestion. I've used C++ for console applications on Visual Studio and also used it on Qt Creator for a few Qt programs. And also have used QML on Qt Creator as in this program. But I've never used C++ in a QML program! So it seems hard for me. But if it's the solution to make the program run correctly on Android devices, OK, I will go for that. But where to start?

                                    J.HilkJ 1 Reply Last reply
                                    0
                                    • tomyT tomy

                                      @J.Hilk
                                      Hi, thank you for your suggestion. I've used C++ for console applications on Visual Studio and also used it on Qt Creator for a few Qt programs. And also have used QML on Qt Creator as in this program. But I've never used C++ in a QML program! So it seems hard for me. But if it's the solution to make the program run correctly on Android devices, OK, I will go for that. But where to start?

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

                                      @tomy

                                      theres a very basic example in the docu, that is really good to get general understanding of a c++ backend for a qml program:

                                      Let me link that for you


                                      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
                                      • J.HilkJ Offline
                                        J.HilkJ Offline
                                        J.Hilk
                                        Moderators
                                        wrote on last edited by
                                        #38

                                        heres an quick example how your Backend could look like:

                                        //PropertyBase.h
                                        #ifndef PROPERTYBASE_H
                                        #define PROPERTYBASE_H
                                        
                                        #include <QObject>
                                        
                                        class PropertyBase : public QObject
                                        {
                                            Q_OBJECT
                                            
                                            Q_PROPERTY(double xBall READ xBall WRITE setXBall NOTIFY xBallChanged)
                                            Q_PROPERTY(double yBall READ yBall WRITE setYBall NOTIFY yBallChanged)
                                            Q_PROPERTY(double wBall READ wBall WRITE setWBall NOTIFY wBallChanged)
                                            Q_PROPERTY(double hBall READ hBall WRITE setHBall NOTIFY hBallChanged)
                                            
                                            Q_PROPERTY(double xRedRacket READ xRedRacket WRITE setXRedRacket NOTIFY xRedRacketChanged)
                                            Q_PROPERTY(double yRedRacket READ yRedRacket WRITE setYRedRacket NOTIFY yRedRacketChanged)
                                            Q_PROPERTY(double wRedRacket READ wRedRacket WRITE setWRedRacket NOTIFY wRedRacketChanged)
                                            Q_PROPERTY(double hRedRacket READ hRedRacket WRITE setHRedRacket NOTIFY hRedRacketChanged)
                                            
                                            Q_PROPERTY(double xBlackRacket READ xBlackRacket WRITE setXBlackRacket NOTIFY xBlackRacketChanged)
                                            Q_PROPERTY(double yBlackRacket READ yBlackRacket WRITE setYBlackRacket NOTIFY yBlackRacketChanged)
                                            Q_PROPERTY(double wBlackRacket READ wBlackRacket WRITE setWBlackRacket NOTIFY wBlackRacketChanged)
                                            Q_PROPERTY(double hBlackRacket READ hBlackRacket WRITE setHBlackRacket NOTIFY hBlackRacketChanged)
                                            
                                            Q_PROPERTY(double wScreen READ wScreen WRITE setWScreen NOTIFY wScreenChanged)
                                            Q_PROPERTY(double hScreen READ hScreen WRITE setHScreen NOTIFY hScreenChanged)
                                            
                                            inline double xBall(){return m_xBall;}
                                            inline double yBall(){return m_yBall;}
                                            inline double wBall(){return m_wBall;}
                                            inline double hBall(){return m_hBall;}
                                            
                                            inline double xRedRacket(){return m_xrRacket;}
                                            inline double yRedRacket(){return m_yrRacket;}
                                            inline double wRedRacket(){return m_wrRacket;}
                                            inline double hRedRacket(){return m_hrRacket;}
                                            
                                            inline double xBlackRacket(){return m_xbRacket;}
                                            inline double yBlackRacket(){return m_ybRacket;}
                                            inline double wBlackRacket(){return m_wbRacket;}
                                            inline double hBlackRacket(){return m_hbRacket;}
                                            
                                            inline double wScreen(){return m_wScreen;}
                                            inline double hScreen(){return m_hScreen;}
                                            
                                            void setXBall(const double &);
                                            void setYBall(const double &);
                                            void setWBall(const double &);
                                            void setHBall(const double &);
                                            
                                            void setXRedRacket(const double &);
                                            void setYRedRacket(const double &);
                                            void setWRedRacket(const double &);
                                            void setHRedRacket(const double &);
                                            
                                            void setXBlackRacket(const double &);
                                            void setYBlackRacket(const double &);
                                            void setWBlackRacket(const double &);
                                            void setHBlackRacket(const double &);
                                            
                                            void setWScreen(const double &);
                                            void setHScreen(const double &);
                                        public:
                                            explicit PropertyBase(QObject *parent = nullptr);
                                        
                                        signals:
                                            void xBallChanged();
                                            void yBallChanged();
                                            void wBallChanged();
                                            void hBallChanged();
                                            
                                            void xRedRacketChanged();
                                            void yRedRacketChanged();
                                            void wRedRacketChanged();
                                            void hRedRacketChanged();
                                            
                                            void xBlackRacketChanged();
                                            void yBlackRacketChanged();
                                            void wBlackRacketChanged();
                                            void hBlackRacketChanged();
                                            
                                            void wScreenChanged();
                                            void hScreenChanged();
                                        protected:
                                            double m_xBall;
                                            double m_yBall;
                                            double m_wBall;
                                            double m_hBall;
                                            
                                            double m_xrRacket;
                                            double m_yrRacket;
                                            double m_wrRacket;
                                            double m_hrRacket;
                                            
                                            double m_xbRacket;
                                            double m_ybRacket;
                                            double m_wbRacket;
                                            double m_hbRacket;
                                            
                                            double m_wScreen;
                                            double m_hScreen;
                                        };
                                        
                                        #endif // PROPERTYBASE_H
                                        

                                        //

                                        //PropertyBase.cpp
                                        #include "propertybase.h"
                                        
                                        
                                        PropertyBase::PropertyBase(QObject *parent) : QObject(parent)
                                        {
                                        
                                        }
                                        
                                        void PropertyBase::setXBall(const double &value)
                                        {
                                            if(value != m_xBall){
                                                m_xBall = value;
                                                emit xBallChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setYBall(const double &value)
                                        {
                                            if(value != m_YBall){
                                                m_yBall = value;
                                                emit yBallChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setWBall(const double &value)
                                        {
                                            if(value != m_wBall){
                                                m_wBall = value;
                                                emit wBallChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setHBall(const double &value)
                                        {
                                            if(value != m_hBall){
                                                m_hBall = value;
                                                emit hBallChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setXRedRacket(const double &value)
                                        {
                                            if(value != m_xrRacket){
                                                m_xrRacket = value;
                                                emit xRedRacketChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setYRedRacket(const double &value)
                                        {
                                            if(value != m_yrRacket){
                                                m_yrRacket = value;
                                                emit yRedRacketChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setWRedRacket(const double &value)
                                        {
                                            if(value != m_wrRacket){
                                                m_wrRacket = value;
                                                emit wRedRacketChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setHRedRacket(const double &value)
                                        {
                                            if(value != m_hrRacket){
                                                m_hrRacket = value;
                                                emit hRedRacketChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setXBlackRacket(const double &value)
                                        {
                                            if(value != m_xbRacket){
                                                m_xbRacket = value;
                                                emit xBlackRacketChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setYBlackRacket(const double &value)
                                        {
                                            if(value != m_ybRacket){
                                                m_ybRacket = value;
                                                emit yBlackRacketChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setWBlackRacket(const double &value)
                                        {
                                            if(value != m_wbRacket){
                                                m_wbRacket = value;
                                                emit wBlackRacketChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setHBlackRacket(const double &value)
                                        {
                                            if(value != m_hbRacket){
                                                m_hbRacket = value;
                                                emit hBlackRacketChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setWScreen(const double &value)
                                        {
                                            if(value != m_wScreen){
                                                m_wScreen = value;
                                                emit wScreenChanged();
                                            }
                                        }
                                        
                                        void PropertyBase::setHScreen(const double &value)
                                        {
                                            if(value != m_hScreen){
                                                m_hScreen = value;
                                                emit hScreenChanged();
                                            }
                                        }
                                        
                                        //Backend.h
                                        #ifndef BACKEND_H
                                        #define BACKEND_H
                                        
                                        #include "propertybase.h"
                                        #include <QTimer>
                                        
                                        class BackEnd : public PropertyBase
                                        {
                                            Q_OBJECT
                                            
                                        public:
                                            explicit BackEnd(PropertyBase *parent = nullptr);
                                        
                                            Q_INVOKABLE void timerStart(){m_BallTimer.start(m_timerInterval);}
                                            Q_INVOKABLE void timerStop(){m_BallTimer.stop();}
                                            
                                            Q_INVOKABLE void setInterval(int & interval){
                                                m_timerInterval = interval;
                                                m_BallTimer.setInterval(interval);
                                            }
                                            
                                        signals:
                                            void rightWallhit();
                                            void leftWallHit();
                                            void rightRacketHit();
                                            void leftRacketHit();
                                            void upperOrLowerWallHit();
                                            
                                            void moveBall();
                                        
                                        public slots:
                                            
                                        private:
                                            bool hitsRightRacket();
                                            bool hitsLeftRacket();
                                            
                                            bool hitsUpperOrLowerWall();
                                            bool hitsRightWall();
                                            bool hitsLeftWall();
                                            
                                        private slots:
                                            void doCalculation();
                                            
                                        protected:
                                            int m_timerInterval = 10;
                                            QTimer m_BallTimer;
                                        };
                                        
                                        #endif // BACKEND_H
                                        
                                        //Backend.cpp
                                        #include "backend.h"
                                        
                                        BackEnd::BackEnd(PropertyBase *parent) : PropertyBase(parent)
                                        {
                                            connect(&m_BallTimer, &QTimer::timeout, this, &BackEnd::doCalculation);
                                        }
                                        
                                        bool BackEnd::hitsRightRacket()
                                        {
                                            if( (xBall() + wBall() >= xRedRacket() && xBall() <= xRedRacket() + wRedRacket() ) &&
                                                (yBall() + hBall() >= yRedRacket() && yBall() <= yRedRacket() + hRedRacket() ))
                                                return true;
                                            
                                            return false;
                                        }
                                        
                                        bool BackEnd::hitsLeftRacket()
                                        {
                                            if( (xBall() + wBall() >= xBlackRacket() && xBall() <= xBlackRacket() + wBlackRacket() ) &&
                                                (yBall() + hBall() >= yBlackRacket() && yBall() <= yBlackRacket() + hBlackRacket() ))
                                                return true;
                                            
                                            return false;
                                        }
                                        
                                        bool BackEnd::hitsUpperOrLowerWall()
                                        {
                                            if(yBall() <= 0 || yBall() +hBall() >= hScreen())
                                                return true;
                                            
                                            return false;
                                        }
                                        
                                        bool BackEnd::hitsRightWall()
                                        {
                                            if(xBall() + wBall() >= wScreen())
                                                return true;
                                            
                                            return false;
                                        }
                                        
                                        bool BackEnd::hitsLeftWall()
                                        {
                                            if(xBall() <= 0)
                                                return true;
                                            
                                            return false;
                                        }
                                        
                                        void BackEnd::doCalculation()
                                        {
                                            if(hitsRightWall()){
                                                timerStop();
                                                emit rightWallhit();
                                            }
                                            
                                            if(hitsLeftWall()){
                                                timerStop();
                                                emit leftWallHit();
                                            }
                                            
                                            if(hitsRightRacket())
                                                emit rightRacketHit();
                                            
                                            if(hitsLeftRacket())
                                                emit leftRacketHit();
                                            
                                            if(hitsUpperOrLowerWall())
                                                emit upperOrLowerWallHit();
                                            
                                            emit moveBall();
                                        }
                                        
                                        
                                        //main.cpp
                                        #include <QGuiApplication>
                                        #include <QQmlApplicationEngine>
                                        
                                        #include "backend.h"
                                        
                                        int main(int argc, char *argv[])
                                        {
                                            QGuiApplication app(argc, argv);
                                            
                                            qmlRegisterType<BackEnd>("myBackend",1,0,"BackEnd");
                                        
                                            QQmlApplicationEngine engine;
                                            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                                            if (engine.rootObjects().isEmpty())
                                                return -1;
                                        
                                            return app.exec();
                                        }
                                        
                                        
                                        //main.qml
                                        Window {
                                            id: window
                                            visibility: Window.Maximized
                                            title: qsTr("The PingPong Game - A QML Game")
                                            color: "gray"
                                            
                                            
                                            BackEnd{
                                                id:myBackend
                                                
                                                xBall: ball.x
                                                yBall: ball.y
                                                wBall: ball.width
                                                hBall: ball.height
                                                
                                                xRedRacket: redRacket.x
                                                yRedRacket: redRacket.y
                                                //....
                                                
                                                onRightWallhit: {
                                                    leftCounter.count++
                                                    out_timer.interval = 2000
                                                    out_timer.running = true
                                                }
                                                onLeftWallHit: {
                                                    rightCounter.count++
                                                    out_timer.interval = 2000
                                                    out_timer.running = true
                                                }
                                                onRightRacketHit: {
                                                    if (redRacket.yUwards) {
                                                        if (ball.yincrement == 0)
                                                            ball.yincrement = -ball.ran
                                                        else if (ball.yincrement > 0)
                                                            ball.yincrement *= -1
                                                        
                                                    }
                                                    else if (redRacket.yDwards) {
                                                        if (ball.yincrement == 0)
                                                            ball.yincrement = ball.ran
                                                        else if (ball.yincrement < 0)
                                                            ball.yincrement *= -1
                                                        setInterval(table.duration/4)
                                                    }
                                                }
                                                 ....
                                            }
                                        .....
                                        }
                                        

                                        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
                                        2
                                        • J.HilkJ J.Hilk

                                          heres an quick example how your Backend could look like:

                                          //PropertyBase.h
                                          #ifndef PROPERTYBASE_H
                                          #define PROPERTYBASE_H
                                          
                                          #include <QObject>
                                          
                                          class PropertyBase : public QObject
                                          {
                                              Q_OBJECT
                                              
                                              Q_PROPERTY(double xBall READ xBall WRITE setXBall NOTIFY xBallChanged)
                                              Q_PROPERTY(double yBall READ yBall WRITE setYBall NOTIFY yBallChanged)
                                              Q_PROPERTY(double wBall READ wBall WRITE setWBall NOTIFY wBallChanged)
                                              Q_PROPERTY(double hBall READ hBall WRITE setHBall NOTIFY hBallChanged)
                                              
                                              Q_PROPERTY(double xRedRacket READ xRedRacket WRITE setXRedRacket NOTIFY xRedRacketChanged)
                                              Q_PROPERTY(double yRedRacket READ yRedRacket WRITE setYRedRacket NOTIFY yRedRacketChanged)
                                              Q_PROPERTY(double wRedRacket READ wRedRacket WRITE setWRedRacket NOTIFY wRedRacketChanged)
                                              Q_PROPERTY(double hRedRacket READ hRedRacket WRITE setHRedRacket NOTIFY hRedRacketChanged)
                                              
                                              Q_PROPERTY(double xBlackRacket READ xBlackRacket WRITE setXBlackRacket NOTIFY xBlackRacketChanged)
                                              Q_PROPERTY(double yBlackRacket READ yBlackRacket WRITE setYBlackRacket NOTIFY yBlackRacketChanged)
                                              Q_PROPERTY(double wBlackRacket READ wBlackRacket WRITE setWBlackRacket NOTIFY wBlackRacketChanged)
                                              Q_PROPERTY(double hBlackRacket READ hBlackRacket WRITE setHBlackRacket NOTIFY hBlackRacketChanged)
                                              
                                              Q_PROPERTY(double wScreen READ wScreen WRITE setWScreen NOTIFY wScreenChanged)
                                              Q_PROPERTY(double hScreen READ hScreen WRITE setHScreen NOTIFY hScreenChanged)
                                              
                                              inline double xBall(){return m_xBall;}
                                              inline double yBall(){return m_yBall;}
                                              inline double wBall(){return m_wBall;}
                                              inline double hBall(){return m_hBall;}
                                              
                                              inline double xRedRacket(){return m_xrRacket;}
                                              inline double yRedRacket(){return m_yrRacket;}
                                              inline double wRedRacket(){return m_wrRacket;}
                                              inline double hRedRacket(){return m_hrRacket;}
                                              
                                              inline double xBlackRacket(){return m_xbRacket;}
                                              inline double yBlackRacket(){return m_ybRacket;}
                                              inline double wBlackRacket(){return m_wbRacket;}
                                              inline double hBlackRacket(){return m_hbRacket;}
                                              
                                              inline double wScreen(){return m_wScreen;}
                                              inline double hScreen(){return m_hScreen;}
                                              
                                              void setXBall(const double &);
                                              void setYBall(const double &);
                                              void setWBall(const double &);
                                              void setHBall(const double &);
                                              
                                              void setXRedRacket(const double &);
                                              void setYRedRacket(const double &);
                                              void setWRedRacket(const double &);
                                              void setHRedRacket(const double &);
                                              
                                              void setXBlackRacket(const double &);
                                              void setYBlackRacket(const double &);
                                              void setWBlackRacket(const double &);
                                              void setHBlackRacket(const double &);
                                              
                                              void setWScreen(const double &);
                                              void setHScreen(const double &);
                                          public:
                                              explicit PropertyBase(QObject *parent = nullptr);
                                          
                                          signals:
                                              void xBallChanged();
                                              void yBallChanged();
                                              void wBallChanged();
                                              void hBallChanged();
                                              
                                              void xRedRacketChanged();
                                              void yRedRacketChanged();
                                              void wRedRacketChanged();
                                              void hRedRacketChanged();
                                              
                                              void xBlackRacketChanged();
                                              void yBlackRacketChanged();
                                              void wBlackRacketChanged();
                                              void hBlackRacketChanged();
                                              
                                              void wScreenChanged();
                                              void hScreenChanged();
                                          protected:
                                              double m_xBall;
                                              double m_yBall;
                                              double m_wBall;
                                              double m_hBall;
                                              
                                              double m_xrRacket;
                                              double m_yrRacket;
                                              double m_wrRacket;
                                              double m_hrRacket;
                                              
                                              double m_xbRacket;
                                              double m_ybRacket;
                                              double m_wbRacket;
                                              double m_hbRacket;
                                              
                                              double m_wScreen;
                                              double m_hScreen;
                                          };
                                          
                                          #endif // PROPERTYBASE_H
                                          

                                          //

                                          //PropertyBase.cpp
                                          #include "propertybase.h"
                                          
                                          
                                          PropertyBase::PropertyBase(QObject *parent) : QObject(parent)
                                          {
                                          
                                          }
                                          
                                          void PropertyBase::setXBall(const double &value)
                                          {
                                              if(value != m_xBall){
                                                  m_xBall = value;
                                                  emit xBallChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setYBall(const double &value)
                                          {
                                              if(value != m_YBall){
                                                  m_yBall = value;
                                                  emit yBallChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setWBall(const double &value)
                                          {
                                              if(value != m_wBall){
                                                  m_wBall = value;
                                                  emit wBallChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setHBall(const double &value)
                                          {
                                              if(value != m_hBall){
                                                  m_hBall = value;
                                                  emit hBallChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setXRedRacket(const double &value)
                                          {
                                              if(value != m_xrRacket){
                                                  m_xrRacket = value;
                                                  emit xRedRacketChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setYRedRacket(const double &value)
                                          {
                                              if(value != m_yrRacket){
                                                  m_yrRacket = value;
                                                  emit yRedRacketChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setWRedRacket(const double &value)
                                          {
                                              if(value != m_wrRacket){
                                                  m_wrRacket = value;
                                                  emit wRedRacketChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setHRedRacket(const double &value)
                                          {
                                              if(value != m_hrRacket){
                                                  m_hrRacket = value;
                                                  emit hRedRacketChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setXBlackRacket(const double &value)
                                          {
                                              if(value != m_xbRacket){
                                                  m_xbRacket = value;
                                                  emit xBlackRacketChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setYBlackRacket(const double &value)
                                          {
                                              if(value != m_ybRacket){
                                                  m_ybRacket = value;
                                                  emit yBlackRacketChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setWBlackRacket(const double &value)
                                          {
                                              if(value != m_wbRacket){
                                                  m_wbRacket = value;
                                                  emit wBlackRacketChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setHBlackRacket(const double &value)
                                          {
                                              if(value != m_hbRacket){
                                                  m_hbRacket = value;
                                                  emit hBlackRacketChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setWScreen(const double &value)
                                          {
                                              if(value != m_wScreen){
                                                  m_wScreen = value;
                                                  emit wScreenChanged();
                                              }
                                          }
                                          
                                          void PropertyBase::setHScreen(const double &value)
                                          {
                                              if(value != m_hScreen){
                                                  m_hScreen = value;
                                                  emit hScreenChanged();
                                              }
                                          }
                                          
                                          //Backend.h
                                          #ifndef BACKEND_H
                                          #define BACKEND_H
                                          
                                          #include "propertybase.h"
                                          #include <QTimer>
                                          
                                          class BackEnd : public PropertyBase
                                          {
                                              Q_OBJECT
                                              
                                          public:
                                              explicit BackEnd(PropertyBase *parent = nullptr);
                                          
                                              Q_INVOKABLE void timerStart(){m_BallTimer.start(m_timerInterval);}
                                              Q_INVOKABLE void timerStop(){m_BallTimer.stop();}
                                              
                                              Q_INVOKABLE void setInterval(int & interval){
                                                  m_timerInterval = interval;
                                                  m_BallTimer.setInterval(interval);
                                              }
                                              
                                          signals:
                                              void rightWallhit();
                                              void leftWallHit();
                                              void rightRacketHit();
                                              void leftRacketHit();
                                              void upperOrLowerWallHit();
                                              
                                              void moveBall();
                                          
                                          public slots:
                                              
                                          private:
                                              bool hitsRightRacket();
                                              bool hitsLeftRacket();
                                              
                                              bool hitsUpperOrLowerWall();
                                              bool hitsRightWall();
                                              bool hitsLeftWall();
                                              
                                          private slots:
                                              void doCalculation();
                                              
                                          protected:
                                              int m_timerInterval = 10;
                                              QTimer m_BallTimer;
                                          };
                                          
                                          #endif // BACKEND_H
                                          
                                          //Backend.cpp
                                          #include "backend.h"
                                          
                                          BackEnd::BackEnd(PropertyBase *parent) : PropertyBase(parent)
                                          {
                                              connect(&m_BallTimer, &QTimer::timeout, this, &BackEnd::doCalculation);
                                          }
                                          
                                          bool BackEnd::hitsRightRacket()
                                          {
                                              if( (xBall() + wBall() >= xRedRacket() && xBall() <= xRedRacket() + wRedRacket() ) &&
                                                  (yBall() + hBall() >= yRedRacket() && yBall() <= yRedRacket() + hRedRacket() ))
                                                  return true;
                                              
                                              return false;
                                          }
                                          
                                          bool BackEnd::hitsLeftRacket()
                                          {
                                              if( (xBall() + wBall() >= xBlackRacket() && xBall() <= xBlackRacket() + wBlackRacket() ) &&
                                                  (yBall() + hBall() >= yBlackRacket() && yBall() <= yBlackRacket() + hBlackRacket() ))
                                                  return true;
                                              
                                              return false;
                                          }
                                          
                                          bool BackEnd::hitsUpperOrLowerWall()
                                          {
                                              if(yBall() <= 0 || yBall() +hBall() >= hScreen())
                                                  return true;
                                              
                                              return false;
                                          }
                                          
                                          bool BackEnd::hitsRightWall()
                                          {
                                              if(xBall() + wBall() >= wScreen())
                                                  return true;
                                              
                                              return false;
                                          }
                                          
                                          bool BackEnd::hitsLeftWall()
                                          {
                                              if(xBall() <= 0)
                                                  return true;
                                              
                                              return false;
                                          }
                                          
                                          void BackEnd::doCalculation()
                                          {
                                              if(hitsRightWall()){
                                                  timerStop();
                                                  emit rightWallhit();
                                              }
                                              
                                              if(hitsLeftWall()){
                                                  timerStop();
                                                  emit leftWallHit();
                                              }
                                              
                                              if(hitsRightRacket())
                                                  emit rightRacketHit();
                                              
                                              if(hitsLeftRacket())
                                                  emit leftRacketHit();
                                              
                                              if(hitsUpperOrLowerWall())
                                                  emit upperOrLowerWallHit();
                                              
                                              emit moveBall();
                                          }
                                          
                                          
                                          //main.cpp
                                          #include <QGuiApplication>
                                          #include <QQmlApplicationEngine>
                                          
                                          #include "backend.h"
                                          
                                          int main(int argc, char *argv[])
                                          {
                                              QGuiApplication app(argc, argv);
                                              
                                              qmlRegisterType<BackEnd>("myBackend",1,0,"BackEnd");
                                          
                                              QQmlApplicationEngine engine;
                                              engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                                              if (engine.rootObjects().isEmpty())
                                                  return -1;
                                          
                                              return app.exec();
                                          }
                                          
                                          
                                          //main.qml
                                          Window {
                                              id: window
                                              visibility: Window.Maximized
                                              title: qsTr("The PingPong Game - A QML Game")
                                              color: "gray"
                                              
                                              
                                              BackEnd{
                                                  id:myBackend
                                                  
                                                  xBall: ball.x
                                                  yBall: ball.y
                                                  wBall: ball.width
                                                  hBall: ball.height
                                                  
                                                  xRedRacket: redRacket.x
                                                  yRedRacket: redRacket.y
                                                  //....
                                                  
                                                  onRightWallhit: {
                                                      leftCounter.count++
                                                      out_timer.interval = 2000
                                                      out_timer.running = true
                                                  }
                                                  onLeftWallHit: {
                                                      rightCounter.count++
                                                      out_timer.interval = 2000
                                                      out_timer.running = true
                                                  }
                                                  onRightRacketHit: {
                                                      if (redRacket.yUwards) {
                                                          if (ball.yincrement == 0)
                                                              ball.yincrement = -ball.ran
                                                          else if (ball.yincrement > 0)
                                                              ball.yincrement *= -1
                                                          
                                                      }
                                                      else if (redRacket.yDwards) {
                                                          if (ball.yincrement == 0)
                                                              ball.yincrement = ball.ran
                                                          else if (ball.yincrement < 0)
                                                              ball.yincrement *= -1
                                                          setInterval(table.duration/4)
                                                      }
                                                  }
                                                   ....
                                              }
                                          .....
                                          }
                                          
                                          tomyT Offline
                                          tomyT Offline
                                          tomy
                                          wrote on last edited by
                                          #39

                                          @J.Hilk
                                          Thank you many times. :-)
                                          I must analyse the code for both being familiar with the code and also the way C++ and QML have been mixed. :-)

                                          J.HilkJ 1 Reply Last reply
                                          1

                                          • Login

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