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.2k 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.
  • T tomy
    4 Dec 2017, 08:54

    @J.Hilk
    Pong is much cooler but how to play such a two-player game on a smartphone? We need joysticks. So I go for the one-player version of the game.

    J Offline
    J Offline
    J.Hilk
    Moderators
    wrote on 4 Dec 2017, 09:07 last edited by
    #11

    @tomy ok,
    but fyi, Most, if not all, smartphones have a multi touch screen, So it should be possible to play with 2 players.

    alternatively, this could also be a good option for you to get into networking, to play on 2 phones via bluetooth or wlan. ;-)


    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.

    T 2 Replies Last reply 4 Dec 2017, 10:49
    1
    • J J.Hilk
      4 Dec 2017, 09:07

      @tomy ok,
      but fyi, Most, if not all, smartphones have a multi touch screen, So it should be possible to play with 2 players.

      alternatively, this could also be a good option for you to get into networking, to play on 2 phones via bluetooth or wlan. ;-)

      T Offline
      T Offline
      tomy
      wrote on 4 Dec 2017, 10:49 last edited by tomy 12 Apr 2017, 10:58
      #12

      @J.Hilk

      alternatively, this could also be a good option for you to get into networking, to play on 2 phones via bluetooth or wlan. ;-)

      I guess we have two parts, the first is designing the stuff and the last part is networking (via wlan).
      I think it's too advanced for me, but I like it and go for that.

      1 Reply Last reply
      0
      • J J.Hilk
        4 Dec 2017, 09:07

        @tomy ok,
        but fyi, Most, if not all, smartphones have a multi touch screen, So it should be possible to play with 2 players.

        alternatively, this could also be a good option for you to get into networking, to play on 2 phones via bluetooth or wlan. ;-)

        T Offline
        T Offline
        tomy
        wrote on 5 Dec 2017, 08:59 last edited by tomy 12 May 2017, 08:59
        #13

        @J.Hilk

        I started by a project named PingPong! I've reached that point up to now:

        main.qml:

        import QtQuick 2.8
        import QtQuick.Window 2.2
        
        Window {
            visible: true
            width: 800
            height: 600
            title: qsTr("The Ping Pong game")
        
            Rectangle {
                id: root
                width: 700; height: 500
                border.width: 10
                border.color: "black"
                color: "royalblue"
                property int duration: 1000
        
           Racket {
               x: 630; y: 100
               color: "red"
           }
        
           Racket {
               x: 50; y: 100
               color: "black"
           }
        
           Ball {
               id: ball
               x: root.width/2 - 50
               y: root.height/2
           }
        
           Rectangle {
               x: root.width/2
               y: 10
               width: 10
               height: root.height - 20
               color: "white"
            }
               
          }
        
        }
        

        Ball.qml:

        import QtQuick 2.8
        
        Rectangle {
            width: 20; height: 20
            x: 250; y: 250
            color: "white"
            radius: width/2
        }
        

        Racket.qml:

        import QtQuick 2.8
        
        Rectangle {
            id: root
            width: 15; height: 50
            x: 400; y: 100
            color: "red"
        
            MouseArea {
                anchors.fill: parent
                drag.target: root
                drag.axis: Drag.YAxis
                drag.minimumY: 10
                drag.maximumY: 440
            }
        }
        

        I have this up to now:
        0_1512464003457_Capture.PNG

        The rackets work good with the mouse button but will they work as well with touching on smartphones?

        Now what I need is animating the ball using Easing.Linear. The ball also should start animating when the program starts and recognizes the rackets and the top and down part of the table to reflect.
        what should I read for these please?

        J 1 Reply Last reply 5 Dec 2017, 09:13
        2
        • T tomy
          5 Dec 2017, 08:59

          @J.Hilk

          I started by a project named PingPong! I've reached that point up to now:

          main.qml:

          import QtQuick 2.8
          import QtQuick.Window 2.2
          
          Window {
              visible: true
              width: 800
              height: 600
              title: qsTr("The Ping Pong game")
          
              Rectangle {
                  id: root
                  width: 700; height: 500
                  border.width: 10
                  border.color: "black"
                  color: "royalblue"
                  property int duration: 1000
          
             Racket {
                 x: 630; y: 100
                 color: "red"
             }
          
             Racket {
                 x: 50; y: 100
                 color: "black"
             }
          
             Ball {
                 id: ball
                 x: root.width/2 - 50
                 y: root.height/2
             }
          
             Rectangle {
                 x: root.width/2
                 y: 10
                 width: 10
                 height: root.height - 20
                 color: "white"
              }
                 
            }
          
          }
          

          Ball.qml:

          import QtQuick 2.8
          
          Rectangle {
              width: 20; height: 20
              x: 250; y: 250
              color: "white"
              radius: width/2
          }
          

          Racket.qml:

          import QtQuick 2.8
          
          Rectangle {
              id: root
              width: 15; height: 50
              x: 400; y: 100
              color: "red"
          
              MouseArea {
                  anchors.fill: parent
                  drag.target: root
                  drag.axis: Drag.YAxis
                  drag.minimumY: 10
                  drag.maximumY: 440
              }
          }
          

          I have this up to now:
          0_1512464003457_Capture.PNG

          The rackets work good with the mouse button but will they work as well with touching on smartphones?

          Now what I need is animating the ball using Easing.Linear. The ball also should start animating when the program starts and recognizes the rackets and the top and down part of the table to reflect.
          what should I read for these please?

          J Offline
          J Offline
          J.Hilk
          Moderators
          wrote on 5 Dec 2017, 09:13 last edited by
          #14

          @tomy
          Hiho,

          Internaly Qt does not differ between mouse clicks and touch events, so if it works fine with the mouse, than it should work fine on the phone display.

          I don't think there is much to read upon for you, you should be able to do that "collision" with what you know.

          E.g
          You monitor the x-position of your ball. If it hits the x-position of one of the rackets, check if the y-positions of ball and racket overlap.
          If yes : Stop old animation of ball and start new one if not, let animation finish and change score counter.


          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.

          T 1 Reply Last reply 7 Dec 2017, 08:35
          1
          • J J.Hilk
            5 Dec 2017, 09:13

            @tomy
            Hiho,

            Internaly Qt does not differ between mouse clicks and touch events, so if it works fine with the mouse, than it should work fine on the phone display.

            I don't think there is much to read upon for you, you should be able to do that "collision" with what you know.

            E.g
            You monitor the x-position of your ball. If it hits the x-position of one of the rackets, check if the y-positions of ball and racket overlap.
            If yes : Stop old animation of ball and start new one if not, let animation finish and change score counter.

            T Offline
            T Offline
            tomy
            wrote on 7 Dec 2017, 08:35 last edited by tomy 12 Jul 2017, 08:37
            #15

            @J.Hilk

            For this point I changed the main.qml to 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: root
                    width: 700; height: 500
                    border.width: 10
                    border.color: "black"
                    color: "royalblue"
                    property int duration: 1000
                    property real xPos: root.width
                    property real yPos: Math.random()
            
               Racket {
                   id: redRacket
                   x: 630; y: 100
                   color: "red"
               }
            
               Racket {
                   id: blackRacket
                   x: 50; y: 100
                   color: "black"
               }
            
               Ball {
                   id: ball
                   x: root.width/2 - 50
                   y: root.height/2
               }
            
               Column {
                   spacing: 3
                   x: root.width/2
                   y: 10
            
                     Repeater {
                       model: 21
                         delegate:  Rectangle {
                                  width: 5
                                  height: 20
                                  color: "white"
                            }
                         }
                 }
            
               ParallelAnimation {
                        id: anim1
                           NumberAnimation
                           {
                               target: ball
                               properties: "x"
                               to: root.xPos
                               duration: root.duration
                               easing.type: Easing.Linear
                           }
                           NumberAnimation
                           {
                               target: ball
                               properties: "y"
                               to: root.yPos
                               duration: root.duration
                               easing.type: Easing.Linear
                           }
                      }
               function nextPos()
               {
                 if(ball.x == redRacket.x && ball.y == redRacket.y)
                 {
                     ParallelAnimation {
                        id: anim2
                           NumberAnimation
                           {
                               target: ball
                               properties: "x"
                               to: -root.xPos
                               duration: root.duration
                               easing.type: Easing.Linear
                           }
                           NumberAnimation
                           {
                               target: ball
                               properties: "y"
                               to: root.yPos
                               duration: root.duration
                               easing.type: Easing.Linear
                           }
                      }
                  }
               }
               
                MouseArea {
                    anchors.fill: ball
                    onClicked:
                    { anim1.restart(); anim2.restart() }
                }
              }
            }
            

            The net is better and also I tried to make the ball animate on two opposite directions. But I get these errors:

            qrc:/main.qml:76 Expected token ,'
            qrc:/main.qml:78 Expected token `}'

            By the way, the Math.random() function seems not to work!

            J 1 Reply Last reply 7 Dec 2017, 09:39
            2
            • T tomy
              7 Dec 2017, 08:35

              @J.Hilk

              For this point I changed the main.qml to 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: root
                      width: 700; height: 500
                      border.width: 10
                      border.color: "black"
                      color: "royalblue"
                      property int duration: 1000
                      property real xPos: root.width
                      property real yPos: Math.random()
              
                 Racket {
                     id: redRacket
                     x: 630; y: 100
                     color: "red"
                 }
              
                 Racket {
                     id: blackRacket
                     x: 50; y: 100
                     color: "black"
                 }
              
                 Ball {
                     id: ball
                     x: root.width/2 - 50
                     y: root.height/2
                 }
              
                 Column {
                     spacing: 3
                     x: root.width/2
                     y: 10
              
                       Repeater {
                         model: 21
                           delegate:  Rectangle {
                                    width: 5
                                    height: 20
                                    color: "white"
                              }
                           }
                   }
              
                 ParallelAnimation {
                          id: anim1
                             NumberAnimation
                             {
                                 target: ball
                                 properties: "x"
                                 to: root.xPos
                                 duration: root.duration
                                 easing.type: Easing.Linear
                             }
                             NumberAnimation
                             {
                                 target: ball
                                 properties: "y"
                                 to: root.yPos
                                 duration: root.duration
                                 easing.type: Easing.Linear
                             }
                        }
                 function nextPos()
                 {
                   if(ball.x == redRacket.x && ball.y == redRacket.y)
                   {
                       ParallelAnimation {
                          id: anim2
                             NumberAnimation
                             {
                                 target: ball
                                 properties: "x"
                                 to: -root.xPos
                                 duration: root.duration
                                 easing.type: Easing.Linear
                             }
                             NumberAnimation
                             {
                                 target: ball
                                 properties: "y"
                                 to: root.yPos
                                 duration: root.duration
                                 easing.type: Easing.Linear
                             }
                        }
                    }
                 }
                 
                  MouseArea {
                      anchors.fill: ball
                      onClicked:
                      { anim1.restart(); anim2.restart() }
                  }
                }
              }
              

              The net is better and also I tried to make the ball animate on two opposite directions. But I get these errors:

              qrc:/main.qml:76 Expected token ,'
              qrc:/main.qml:78 Expected token `}'

              By the way, the Math.random() function seems not to work!

              J Offline
              J Offline
              J.Hilk
              Moderators
              wrote on 7 Dec 2017, 09:39 last edited by
              #16

              @tomy
              first of let me tell you, as a person with slight ocd-issues, the fact that your indenting is off, is driving me nuts x)

              Anyway:

              you define a function nextPos() and insinde the function-body you try to define a ParallelAnimation item and NumberAnimation items. That can't work.

              only calculate assign values&properties in functions! Not new items.
              In C++ you would, kind of, get way with it, but defenitly not in QML :-)


              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.

              T 1 Reply Last reply 9 Dec 2017, 08:31
              2
              • J J.Hilk
                7 Dec 2017, 09:39

                @tomy
                first of let me tell you, as a person with slight ocd-issues, the fact that your indenting is off, is driving me nuts x)

                Anyway:

                you define a function nextPos() and insinde the function-body you try to define a ParallelAnimation item and NumberAnimation items. That can't work.

                only calculate assign values&properties in functions! Not new items.
                In C++ you would, kind of, get way with it, but defenitly not in QML :-)

                T Offline
                T Offline
                tomy
                wrote on 9 Dec 2017, 08:31 last edited by
                #17

                @J.Hilk
                Sorry, I don't know if there is an option that offer automatic indenting on Qt Creator. Do you mean the code looks ugly? :-)

                Anyway,
                The functions Math.random() and nextPos() and if-condition are fixed:

                import QtQuick 2.8
                import QtQuick.Window 2.2
                
                Window {
                    visible: true
                    width: 800
                    height: 600
                    title: qsTr("The Ping Pong game")
                
                    Rectangle {
                        id: root
                        width: 700; height: 500
                        border.width: 10
                        border.color: "black"
                        color: "royalblue"
                        property int duration: 1000
                        property real xPos: root.width
                        property real yPos: Math.random() * root.height
                
                   Racket {
                       id: redRacket
                       x: 630; y: 100
                       color: "red"
                   }
                
                   Racket {
                       id: blackRacket
                       x: 50; y: 100
                       color: "black"
                   }
                
                   Ball {
                       id: ball
                       x: root.width/2 - 50
                       y: root.height/2
                   }
                
                   Column {
                       spacing: 3
                       x: root.width/2
                       y: 10
                          Repeater {
                            model: 21
                             delegate: Rectangle {
                                      width: 5
                                      height: 20
                                      color: "white"
                                   }
                             }
                       }
                
                   ParallelAnimation {
                      id: anim1
                          NumberAnimation {
                                   target: ball
                                   properties: "x"
                                   to: root.xPos
                                   duration: root.duration
                                   easing.type: Easing.Linear
                               }
                          NumberAnimation {
                                   target: ball
                                   properties: "y"
                                   to: root.yPos
                                   duration: root.duration
                                   easing.type: Easing.Linear
                               }
                          }
                
                   ParallelAnimation {
                      id: anim2
                         NumberAnimation {
                             target: ball
                             properties: "x"
                             to: -root.xPos
                             duration: root.duration
                             easing.type: Easing.Linear
                         }
                         NumberAnimation {
                             target: ball
                             properties: "y"
                             to: root.yPos
                             duration: root.duration
                             easing.type: Easing.Linear
                         }
                    }
                
                   function nextPos() {
                
                     if(ball.x >= redRacket.x && ball.x <= redRacket.x + redRacket.height)
                     {
                       anim1.stop();
                       anim2.start();
                     }
                   }
                
                    MouseArea {
                        anchors.fill: ball
                        onClicked: { anim1.start(); root.nextPos(); }
                    }
                  }
                }
                

                The x position of the ball is for when it hasn't been animated yet so it won't work in the condition. I need something like:

                if (hit(ball,redRacket))
                

                The second is that in:

                anim1.stop();
                anim2.start();
                

                anim2.start() doesn't let anim1.start() work!

                J 1 Reply Last reply 11 Dec 2017, 07:01
                0
                • T tomy
                  9 Dec 2017, 08:31

                  @J.Hilk
                  Sorry, I don't know if there is an option that offer automatic indenting on Qt Creator. Do you mean the code looks ugly? :-)

                  Anyway,
                  The functions Math.random() and nextPos() and if-condition are fixed:

                  import QtQuick 2.8
                  import QtQuick.Window 2.2
                  
                  Window {
                      visible: true
                      width: 800
                      height: 600
                      title: qsTr("The Ping Pong game")
                  
                      Rectangle {
                          id: root
                          width: 700; height: 500
                          border.width: 10
                          border.color: "black"
                          color: "royalblue"
                          property int duration: 1000
                          property real xPos: root.width
                          property real yPos: Math.random() * root.height
                  
                     Racket {
                         id: redRacket
                         x: 630; y: 100
                         color: "red"
                     }
                  
                     Racket {
                         id: blackRacket
                         x: 50; y: 100
                         color: "black"
                     }
                  
                     Ball {
                         id: ball
                         x: root.width/2 - 50
                         y: root.height/2
                     }
                  
                     Column {
                         spacing: 3
                         x: root.width/2
                         y: 10
                            Repeater {
                              model: 21
                               delegate: Rectangle {
                                        width: 5
                                        height: 20
                                        color: "white"
                                     }
                               }
                         }
                  
                     ParallelAnimation {
                        id: anim1
                            NumberAnimation {
                                     target: ball
                                     properties: "x"
                                     to: root.xPos
                                     duration: root.duration
                                     easing.type: Easing.Linear
                                 }
                            NumberAnimation {
                                     target: ball
                                     properties: "y"
                                     to: root.yPos
                                     duration: root.duration
                                     easing.type: Easing.Linear
                                 }
                            }
                  
                     ParallelAnimation {
                        id: anim2
                           NumberAnimation {
                               target: ball
                               properties: "x"
                               to: -root.xPos
                               duration: root.duration
                               easing.type: Easing.Linear
                           }
                           NumberAnimation {
                               target: ball
                               properties: "y"
                               to: root.yPos
                               duration: root.duration
                               easing.type: Easing.Linear
                           }
                      }
                  
                     function nextPos() {
                  
                       if(ball.x >= redRacket.x && ball.x <= redRacket.x + redRacket.height)
                       {
                         anim1.stop();
                         anim2.start();
                       }
                     }
                  
                      MouseArea {
                          anchors.fill: ball
                          onClicked: { anim1.start(); root.nextPos(); }
                      }
                    }
                  }
                  

                  The x position of the ball is for when it hasn't been animated yet so it won't work in the condition. I need something like:

                  if (hit(ball,redRacket))
                  

                  The second is that in:

                  anim1.stop();
                  anim2.start();
                  

                  anim2.start() doesn't let anim1.start() work!

                  J Offline
                  J Offline
                  J.Hilk
                  Moderators
                  wrote on 11 Dec 2017, 07:01 last edited by J.Hilk 12 Nov 2017, 07:13
                  #18

                  @tomy Hiho

                  So, I took a look at your code. I'm not quite sure why it's not working like you want it to.
                  My guess would be, its quite difficult to click upon the ball when its in the window when its in the Racket.

                  So I simpliefied the situation a bit

                  I added 2 Properties and a timer to help:
                  The timer was needed in my testing, otherwise it would change animation an

                  property bool toTheRight: true
                  property bool delay: false
                  
                  Timer{
                          id: delayTimer
                          interval: 500; running:  false; repeat: false
                          onTriggered: delay = false
                  }
                  onToTheRightChanged: {
                          delay = true
                          delayTimer.start()
                  }
                  

                  nextPos() was slighly changed, it currently only checks if the ball is past a line:

                  function nextPos() {
                          if(!delay){
                              if(ball.x + ball.width >= redRacket.x || ball.x <= blackRacket.x + blackRacket.width){
                                  toRight = !toRight
                                  console.log("Ball hits a racket")
                                  if(anim1.running)
                                      anim1.stop()
                                  else
                                      anim1.start()
                  
                                  if(anim2.running)
                                      anim2.stop()
                                  else
                                      anim2.start()
                              }
                         }
                  }
                  

                  The Ball item calls nextPos():

                  Ball {
                         id: ball
                         x: root.width/2 - 50
                         y: root.height/2
                         onXChanged: nextPos()
                  }
                  ...
                  MouseArea {
                          anchors.fill: ball
                          onClicked: { anim1.start(); /*root.nextPos();*/}
                      }
                  

                  This works fine for me, its results in the ball pinging from one wall to the other.
                  Next step would be to add the player input conditions.

                  hope this helps.


                  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.

                  T 1 Reply Last reply 12 Dec 2017, 11:12
                  2
                  • J J.Hilk
                    11 Dec 2017, 07:01

                    @tomy Hiho

                    So, I took a look at your code. I'm not quite sure why it's not working like you want it to.
                    My guess would be, its quite difficult to click upon the ball when its in the window when its in the Racket.

                    So I simpliefied the situation a bit

                    I added 2 Properties and a timer to help:
                    The timer was needed in my testing, otherwise it would change animation an

                    property bool toTheRight: true
                    property bool delay: false
                    
                    Timer{
                            id: delayTimer
                            interval: 500; running:  false; repeat: false
                            onTriggered: delay = false
                    }
                    onToTheRightChanged: {
                            delay = true
                            delayTimer.start()
                    }
                    

                    nextPos() was slighly changed, it currently only checks if the ball is past a line:

                    function nextPos() {
                            if(!delay){
                                if(ball.x + ball.width >= redRacket.x || ball.x <= blackRacket.x + blackRacket.width){
                                    toRight = !toRight
                                    console.log("Ball hits a racket")
                                    if(anim1.running)
                                        anim1.stop()
                                    else
                                        anim1.start()
                    
                                    if(anim2.running)
                                        anim2.stop()
                                    else
                                        anim2.start()
                                }
                           }
                    }
                    

                    The Ball item calls nextPos():

                    Ball {
                           id: ball
                           x: root.width/2 - 50
                           y: root.height/2
                           onXChanged: nextPos()
                    }
                    ...
                    MouseArea {
                            anchors.fill: ball
                            onClicked: { anim1.start(); /*root.nextPos();*/}
                        }
                    

                    This works fine for me, its results in the ball pinging from one wall to the other.
                    Next step would be to add the player input conditions.

                    hope this helps.

                    T Offline
                    T Offline
                    tomy
                    wrote on 12 Dec 2017, 11:12 last edited by tomy 12 Dec 2017, 11:14
                    #19

                    @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 1 Reply Last reply 12 Dec 2017, 11:51
                    0
                    • T tomy
                      12 Dec 2017, 11:12

                      @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 Offline
                      J Offline
                      J.Hilk
                      Moderators
                      wrote on 12 Dec 2017, 11:51 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.

                      T 1 Reply Last reply 13 Dec 2017, 10:17
                      1
                      • J J.Hilk
                        12 Dec 2017, 11:51

                        @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
                            }
                        }
                        
                        T Offline
                        T Offline
                        tomy
                        wrote on 13 Dec 2017, 10:17 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 1 Reply Last reply 13 Dec 2017, 10:47
                        0
                        • T tomy
                          13 Dec 2017, 10:17

                          @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 Offline
                          J Offline
                          J.Hilk
                          Moderators
                          wrote on 13 Dec 2017, 10:47 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.

                          T 1 Reply Last reply 13 Dec 2017, 12:50
                          1
                          • J J.Hilk
                            13 Dec 2017, 10:47

                            @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 ;-)

                            T Offline
                            T Offline
                            tomy
                            wrote on 13 Dec 2017, 12:50 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 1 Reply Last reply 13 Dec 2017, 13:37
                            0
                            • T tomy
                              13 Dec 2017, 12:50

                              @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 Offline
                              J Offline
                              J.Hilk
                              Moderators
                              wrote on 13 Dec 2017, 13:37 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.

                              T 1 Reply Last reply 16 Dec 2017, 15:33
                              1
                              • J J.Hilk
                                13 Dec 2017, 13:37

                                @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,

                                T Offline
                                T Offline
                                tomy
                                wrote on 16 Dec 2017, 15:33 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 Offline
                                  J Offline
                                  J.Hilk
                                  Moderators
                                  wrote on 20 Dec 2017, 06:19 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.

                                  T 1 Reply Last reply 20 Dec 2017, 13:02
                                  0
                                  • J J.Hilk
                                    20 Dec 2017, 06:19

                                    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

                                    T Offline
                                    T Offline
                                    tomy
                                    wrote on 20 Dec 2017, 13:02 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
                                    • T Offline
                                      T Offline
                                      tomy
                                      wrote on 24 Dec 2017, 21:40 last edited by tomy 1 Jun 2018, 09:24
                                      #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 1 Reply Last reply 15 Jan 2018, 06:47
                                      1
                                      • T tomy
                                        24 Dec 2017, 21:40

                                        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 Offline
                                        J Offline
                                        J.Hilk
                                        Moderators
                                        wrote on 15 Jan 2018, 06:47 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.

                                        T 1 Reply Last reply 16 Jan 2018, 09:03
                                        2
                                        • J J.Hilk
                                          15 Jan 2018, 06:47

                                          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.

                                          T Offline
                                          T Offline
                                          tomy
                                          wrote on 16 Jan 2018, 09:03 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

                                          • Login

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