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. Inconsistences when testing a QML application on Android devices
Forum Updated to NodeBB v4.3 + New Features

Inconsistences when testing a QML application on Android devices

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

    Hi guys,

    After a couple of days working on the following program on Windows, using Qt Creator (qt 5.10) in a Qt Qucik Application - Empty project, by help from @J.HILK, it's now working fine on my Desktop. My intention on using QML is actually building appications for smartphoes, so I Built the program (ctrl + B) and moved the .apk file onto two Android devices, versions: 4.3 and 4.4.2 for testing. But there is a problem!

    Here is the output of the screen on both devices:

    0_1514412814843_photo_2017-12-28_01-25-29.jpg

    Inconsistences in the position of the black racket, the upper side of the table and also the net. When I drag the rackets on those devices by my finger, the ball is also affected! Why those many inconsistences while I'm using QML which is built to program for smartphones, please? Don't those problems belong to the versions of Android on those devices that are not high? What about my SDK?

    Please if you use QML for creating applications for mobile phones tell me how you program and how you solve these issues.

    Ball.qml:

    import QtQuick 2.9
    
    Rectangle {
        width: 18; height: 18
        x: border.width/2; y: border.height/2
        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: 65; height: 60
        color: "lightskyblue"
        property int count: 0
    
        Text {
            id: text
            anchors.centerIn: parent
            text: count.toString()
            color: "gray"
            font.bold: true
            font.pixelSize: 50
        }
    }
    

    Light.qml:

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

    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
            drag.target: root
            drag.axis: Drag.YAxis
            drag.minimumY: table.y - 20
            drag.maximumY: table.height - 65
        }
    }
    

    WinBox.aml:

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

    main.qml:

    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtQuick.Controls 2.1
    
    Window {
        id: window
        visible: true
        visibility: Window.FullScreen
        title: qsTr("The PingPong Game - A QML Game")
        color: "gray"
    
        Rectangle {
            id: border
            x: window.x + window.width/14; y: window.y - 10
            width: window.width -300; height: window.height - 120
            color: "white"
        }
    
        Rectangle {
            id: table
            x: border.x + 10; y: border.y + 10
            width: border.width - 20; height: border.height - 20
            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: redRacket
                x: table.width - 40; y: 100
                color: "red"
            }
            Racket {
                id: blackRacket
                x: table.x - 120; y: 100
                color: "black"
            }
    
            Ball {
                id: ball
                x: table.width/2
                y: table.height/2
            }
    
            Column {
                spacing: 3
                x: border.width/2
                Repeater {
                    model: 37
                    delegate: Rectangle {
                        width: 5
                        height: 21
                        color: "white"
                    }
                }
            }
    
            Counter {
                id: rightCounter
                x: table.width / 2 + 140
                y: 50
            }
            Counter {
                id: leftCounter
                x: table.width / 3 + 70
                y: 50
            }
    
            Light {
                id: leftLight
                x: border.width/2 - 280
                y: border.height + 10
                color: "lime"
            }
            Light {
                id: rightLight
                x: border.width/2 + 220
                y: border.height + 10
                color: "silver"
            }
    
            WinBox {
                id: rightWin
                x: border.width/2 + 380
                y: border.height + 10
            }
            WinBox {
                id: leftWin
                x: border.x + 40
                y: border.height + 10
            }
    
            Button {
                x: border.width/2 - 45
                y: border.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: border.width/2 - 150
                y: border.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: border.width/2 + 60
                y: border.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 {
                id: ver
                x: border.x - 130; y: table.height + 70
                color: "white"
                text: "Ver: 1.1"
                font.family: "Helvetica"
                font.pointSize: 15
            }
            Text {
                id: prog
                x: border.width - 100; y: ver.y + 15
                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
                    }
                }
            }
        }
    }
    
    1 Reply Last reply
    0
    • sierdzioS Online
      sierdzioS Online
      sierdzio
      Moderators
      wrote on last edited by
      #2

      You are not anchoring your elements but using X / Y positions instead. On every device, there are different pixel density, resolution etc. and while you can hand-tweak the x, y positions to look good for one screen, it will fail on others. Try using more anchors or layouts instead. Or make sure that your x, y bindings are properly abstract - that they will work well on all screen sizes and DPI settings.

      The reason why your black racket is in wrong position, just to pick one error, is that you tie it's position to table width - 40 pixels. However, the table position depends on width of the border element, which has X set to one 14th of window width. Now that dimension will be different on different screens.

      To see problems with positioning more clearly, try running your app on desktop in windowed mode and resize it to a few different sizes - you will see which elements go out of their proper places and should be fixed.

      (Z(:^

      tomyT 1 Reply Last reply
      1
      • sierdzioS sierdzio

        You are not anchoring your elements but using X / Y positions instead. On every device, there are different pixel density, resolution etc. and while you can hand-tweak the x, y positions to look good for one screen, it will fail on others. Try using more anchors or layouts instead. Or make sure that your x, y bindings are properly abstract - that they will work well on all screen sizes and DPI settings.

        The reason why your black racket is in wrong position, just to pick one error, is that you tie it's position to table width - 40 pixels. However, the table position depends on width of the border element, which has X set to one 14th of window width. Now that dimension will be different on different screens.

        To see problems with positioning more clearly, try running your app on desktop in windowed mode and resize it to a few different sizes - you will see which elements go out of their proper places and should be fixed.

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

        @sierdzio
        Thank you very much.

        I removed the border rectangle and replaced its id with table then used anchors here:

        main.qml:

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

        Racket.qml:

        ...
        drag.maximumY: table.height - height - 10
        ...
        

        The output on the android device is fine:

        0_1514461640193_photo_2017-12-28_15-15-19.jpg

        The problem that bothers the players is that, moving the rackets affects the speed of the ball, by the way, dragging the racket is not easy. It's hard.

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

          I don't know why whoever replies to my questions will be offline for days! :( :(

          K 1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi,

            1. Weekend
            2. End of year holidays
            3. Preparing new year's eve celebrations
            4. Recovering from Christmas celebrations
            5. Others (too much sweets, kid's toys to construct, not enough presents, death, etc.)

            Don't forget that this is a community driven forum. People come here on their own time providing help for free.

            They have no obligation of answering at any specific rate.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • tomyT tomy

              I don't know why whoever replies to my questions will be offline for days! :( :(

              K Offline
              K Offline
              kenchan
              wrote on last edited by
              #6

              @tomy be careful what you say or people may not care to answer you!

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

                Hey guys, especially kenchan: you're misunderstanding. I said nothing aggressively. And I know how to act.

                Thanks SGaist, yeah, you're right. the most important case is that it's being a new year so people are mostly very buys.

                1 Reply Last reply
                0
                • sierdzioS Online
                  sierdzioS Online
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #8

                  @tomy said in Inconsistences when testing a QML application on Android devices:

                  The problem that bothers the players is that, moving the rackets affects the speed of the ball, by the way, dragging the racket is not easy. It's hard.

                  Make the area of the rackets bigger, then, for example by padding them with an invisible Item. Pseudo code:

                  Item {
                    width: 200
                    height: 200
                    MouseArea {
                      anchors.fill: parent
                    }
                  
                  Racket {} // (better integrate that Item padding into Racket component itself, of course)
                  }
                  

                  (Z(:^

                  tomyT 1 Reply Last reply
                  1
                  • sierdzioS sierdzio

                    @tomy said in Inconsistences when testing a QML application on Android devices:

                    The problem that bothers the players is that, moving the rackets affects the speed of the ball, by the way, dragging the racket is not easy. It's hard.

                    Make the area of the rackets bigger, then, for example by padding them with an invisible Item. Pseudo code:

                    Item {
                      width: 200
                      height: 200
                      MouseArea {
                        anchors.fill: parent
                      }
                    
                    Racket {} // (better integrate that Item padding into Racket component itself, of course)
                    }
                    
                    tomyT Offline
                    tomyT Offline
                    tomy
                    wrote on last edited by
                    #9

                    @sierdzio
                    Hi,

                    I used this code for Racket.qml. It logically should work but in practice, no!
                    What's its issue please?

                    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
                        }
                        
                        Item {
                            x: root.x - 50
                            y: root.y - 50
                            width: 100
                            height: 200
                            
                            MouseArea {
                                anchors.fill: parent
                                drag.target: parent
                                focus: true
                                hoverEnabled: true
                                pressAndHoldInterval: 0
                                drag.axis: Drag.YAxis
                                drag.minimumY: table.y
                                drag.maximumY: table.height - height - 10
                            }
                        }
                    }
                    
                    sierdzioS 1 Reply Last reply
                    0
                    • sierdzioS Online
                      sierdzioS Online
                      sierdzio
                      Moderators
                      wrote on last edited by
                      #10

                      @tomy said in Inconsistences when testing a QML application on Android devices:

                      drag.target: parent

                      You are dragging an invisible item instead of your racket.

                      (Z(:^

                      tomyT 1 Reply Last reply
                      0
                      • sierdzioS sierdzio

                        @tomy said in Inconsistences when testing a QML application on Android devices:

                        drag.target: parent

                        You are dragging an invisible item instead of your racket.

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

                        @sierdzio
                        I also changed the target to: drag.target: root but no expected result again!

                        1 Reply Last reply
                        0
                        • tomyT tomy

                          @sierdzio
                          Hi,

                          I used this code for Racket.qml. It logically should work but in practice, no!
                          What's its issue please?

                          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
                              }
                              
                              Item {
                                  x: root.x - 50
                                  y: root.y - 50
                                  width: 100
                                  height: 200
                                  
                                  MouseArea {
                                      anchors.fill: parent
                                      drag.target: parent
                                      focus: true
                                      hoverEnabled: true
                                      pressAndHoldInterval: 0
                                      drag.axis: Drag.YAxis
                                      drag.minimumY: table.y
                                      drag.maximumY: table.height - height - 10
                                  }
                              }
                          }
                          
                          sierdzioS Online
                          sierdzioS Online
                          sierdzio
                          Moderators
                          wrote on last edited by
                          #12

                          @tomy said in Inconsistences when testing a QML application on Android devices:

                                  drag.minimumY: table.y
                                  drag.maximumY: table.height - height - 10
                          

                          Is "table" defined and visible by your Racket? No errors or warnings?

                          (Z(:^

                          tomyT 1 Reply Last reply
                          0
                          • sierdzioS sierdzio

                            @tomy said in Inconsistences when testing a QML application on Android devices:

                                    drag.minimumY: table.y
                                    drag.maximumY: table.height - height - 10
                            

                            Is "table" defined and visible by your Racket? No errors or warnings?

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

                            @sierdzio

                            Is "table" defined and visible by your Racket? No errors or warnings?

                            table is the first Rectangle in the 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"
                                    ...
                            

                            Before widening the MouseArea the code used that and therefore recognized it.
                            As well as, I changed it, say, to:

                            drag.minimumY: 0
                            drag.maximumY: 300
                            

                            just for test. But no change again!

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

                              Well, the code this way was helpful:

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

                              Now there is only one problem with the program which is:

                              • Moving the rackets 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 rackets affects the speed of ball's movement.
                                If you run the code on an Android device it will be obvious.
                              1 Reply Last reply
                              0
                              • johngodJ Offline
                                johngodJ Offline
                                johngod
                                wrote on last edited by
                                #15

                                I admit I havent check your code with much attention but here are a few ideias for you:
                                In rectangle id: table you have property int duration: 4, and in some timers you use
                                interval = (table.duration/4) wich mean you are setting a 1 ms timer trigger, wich means you're trying to get 1000fps (a little bit hight :) ).
                                Perhaps you could use int duration: 16, that will give you 60 fps that should be more than enought.

                                You seem to have one rectangle for table and another for the table border ? Cant you make it simple and use just one rectangle and make use of border.width and border.color properties ?
                                In the rectangle border you have something like
                                Rectangle {
                                id: border
                                x: window.x + window.width/14; y: window.y - 10
                                width: window.width -300; height: window.height - 120
                                since you would want your game to fit in phones and tablet and all have very different resolutions, screen sizes should really use anchorings, something like

                                Rectangle {
                                id: border
                                width: window.width * 0.8//just an example using 80% of the screen
                                height: window.height * 0.7//again just an example using 70% of the screen size
                                anchors.horizontalCenter: window.horizontalCenter
                                anchors.top: window top
                                anchors.topMargin: ...//use some margins if need, you get the point

                                Whenever I use qml, I tend to use dimensions in milimeters, not in pixel size, because things will get messy different sizes, in phones or tablet with diferente resolution.
                                For example in Ball. qml you have
                                Rectangle {
                                width: 18; height: 18
                                If you specify the size in milimeters instead of pixels you will get the same aprox. size in all type of screens and that is probably what you want. So how do you specify in size in milimeters ? Read on:

                                Rectangle {
                                property real calibrationFactor: 1
                                // you can also use diferent values if want to use diferente sizes for different plataforms
                                // calibrationFactor: Qt.platform.os === "android" ? 0.4 : 0.6
                                property real mm: Screen.pixelDensity * calibrationFactor
                                width: 5 * mm; height: 5 * mm

                                I usually tend to declare mm in main.qml and make general use of mm in setting width and height properties of all items (Button, Balls, ...) and usually have very good results.

                                In Ball.qml you have:
                                property double ran: Math.random() + 0.5
                                property double xincrement: ran
                                property double yincrement: ran
                                it seems the velocity will depend on the random ran value ? It doesnt look very acurate to me, make the velocity depend on some random factor.
                                I would do something like:

                                property real angle: 45//initially angle 
                                property double ran: 3 * mm //fixed value
                                	
                                //call move from the timer
                                function move() {
                                    x += ran*Math.cos(angle)
                                    y += ran*Math.sin(angle)
                                	
                                	/*
                                	for example, within the timer, you can check the limits of the ball, and change the angle, to make it bounce back in the walls or rackets
                                	or you can set properties here in Ball, with the limits of the field and the position of the backets, and check here for collisions
                                	*/
                                }
                                

                                Happy conding.

                                tomyT 1 Reply Last reply
                                1
                                • johngodJ johngod

                                  I admit I havent check your code with much attention but here are a few ideias for you:
                                  In rectangle id: table you have property int duration: 4, and in some timers you use
                                  interval = (table.duration/4) wich mean you are setting a 1 ms timer trigger, wich means you're trying to get 1000fps (a little bit hight :) ).
                                  Perhaps you could use int duration: 16, that will give you 60 fps that should be more than enought.

                                  You seem to have one rectangle for table and another for the table border ? Cant you make it simple and use just one rectangle and make use of border.width and border.color properties ?
                                  In the rectangle border you have something like
                                  Rectangle {
                                  id: border
                                  x: window.x + window.width/14; y: window.y - 10
                                  width: window.width -300; height: window.height - 120
                                  since you would want your game to fit in phones and tablet and all have very different resolutions, screen sizes should really use anchorings, something like

                                  Rectangle {
                                  id: border
                                  width: window.width * 0.8//just an example using 80% of the screen
                                  height: window.height * 0.7//again just an example using 70% of the screen size
                                  anchors.horizontalCenter: window.horizontalCenter
                                  anchors.top: window top
                                  anchors.topMargin: ...//use some margins if need, you get the point

                                  Whenever I use qml, I tend to use dimensions in milimeters, not in pixel size, because things will get messy different sizes, in phones or tablet with diferente resolution.
                                  For example in Ball. qml you have
                                  Rectangle {
                                  width: 18; height: 18
                                  If you specify the size in milimeters instead of pixels you will get the same aprox. size in all type of screens and that is probably what you want. So how do you specify in size in milimeters ? Read on:

                                  Rectangle {
                                  property real calibrationFactor: 1
                                  // you can also use diferent values if want to use diferente sizes for different plataforms
                                  // calibrationFactor: Qt.platform.os === "android" ? 0.4 : 0.6
                                  property real mm: Screen.pixelDensity * calibrationFactor
                                  width: 5 * mm; height: 5 * mm

                                  I usually tend to declare mm in main.qml and make general use of mm in setting width and height properties of all items (Button, Balls, ...) and usually have very good results.

                                  In Ball.qml you have:
                                  property double ran: Math.random() + 0.5
                                  property double xincrement: ran
                                  property double yincrement: ran
                                  it seems the velocity will depend on the random ran value ? It doesnt look very acurate to me, make the velocity depend on some random factor.
                                  I would do something like:

                                  property real angle: 45//initially angle 
                                  property double ran: 3 * mm //fixed value
                                  	
                                  //call move from the timer
                                  function move() {
                                      x += ran*Math.cos(angle)
                                      y += ran*Math.sin(angle)
                                  	
                                  	/*
                                  	for example, within the timer, you can check the limits of the ball, and change the angle, to make it bounce back in the walls or rackets
                                  	or you can set properties here in Ball, with the limits of the field and the position of the backets, and check here for collisions
                                  	*/
                                  }
                                  

                                  Happy conding.

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

                                  @johngod
                                  Thank you very much for your suggestions especially the one for moving.
                                  Please take a look at this code. It's a very simplified version of a program disclosing the problem. I also tried your method in it:

                                  main.qml:

                                  import QtQuick 2.9
                                  import QtQuick.Window 2.2
                                  
                                  Window {
                                      visible: true
                                      width: 720
                                      height: 620
                                  
                                      Rectangle {
                                          id: table
                                          anchors.fill: parent
                                          color: "gray"
                                  
                                          Rectangle {
                                              id: ball
                                              property real angle: 45
                                              property real calibrationFactor: 1
                                              property real mm: Screen.pixelDensity * calibrationFactor
                                              property double ran: 3 * mm 
                                              property double xincrement: ran*Math.cos(angle)
                                              property double yincrement: ran*Math.sin(angle)
                                  
                                              width: 15
                                              height: width
                                              radius: width / 2
                                              color: "white"
                                              x: 300; y: 300
                                          }
                                  
                                          Racket {
                                              id: myRacket
                                              x: table.width - 50
                                              y: table.height/3
                                              color: "blue"
                                          }
                                  
                                          Timer {
                                              interval: 15; repeat: true; running: true
                                  
                                              function move() {
                                                  ball.x += ball.xincrement
                                                  ball.y += ball.yincrement
                                              }
                                  
                                              onTriggered: {
                                                  if(ball.x + ball.width >= table.width || ball.x <= 0)
                                                      ball.xincrement *= -1
                                  
                                                  move()
                                  
                                                  if(ball.y <= 0 || ball.y + ball.height >= table.height)
                                                      ball.yincrement *= -1
                                              }
                                          }
                                      }
                                  }
                                  

                                  Racket.qml:

                                  import QtQuick 2.9
                                  
                                  Rectangle {
                                      id: root
                                      width: 15; height: 65
                                  
                                      MouseArea {
                                          anchors.fill: root
                                          anchors.margins: -root.height
                                          drag.target: root
                                          drag.axis: Drag.YAxis
                                          drag.minimumY: 0
                                          drag.maximumY: 600
                                      }
                                  }
                                  

                                  But when I test it on my Android device, the problem still exists! :-(

                                  1 Reply Last reply
                                  0

                                  • Login

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