QML components collision test method

1.6k Views Asked by At

Well, there may be many QML programs in which if two components collide with each other the programmer defines an action based on that. In such programs as the one below, we want to concentrate on that collision and try to know how to define a function that tells us whether such a collision is done or not.

The code below is part of a bigger program. I tried to use a function called collision for that, in the code. The issue up to now is that it's not working well. I wanted to know if there is a built-in function in QML "or" if there is a good code you've used for that purpose.

The racket has three faces that may collide with the ball: a long one at the front, an upper and a lower one. The issue specifically is that the ball goes inside the racket when it collides with it from the upper or lower face!
The problem that I want to solve is that. I want that when the ball hits the racket from any faces, it reflects.

main.qml:

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 720
    height: 620
    title: qsTr("Collision Test")

    Rectangle {
        id: table
        anchors.fill: parent
        color: "gray"

        Rectangle {
            id: ball
            property double xincrement: Math.random() + 0.5
            property double yincrement: Math.random() + 0.5
            width: 15
            height: width
            radius: width / 2
            color: "white"
            x: 300; y: 300
        }

        Racket {
            id: myRacket
            x: table.width - 50
            y: table.height/3
            color: "blue"
        }

        Timer {
            interval: 5; repeat: true; running: true

            function collision() {
                if((ball.x + ball.width >= myRacket.x  &&
                    ball.x < myRacket.x + myRacket.width) &&
                   (ball.y + ball.height >= myRacket.y &&
                    ball.y <= myRacket.y + myRacket.height))
                    return true
                return false
            }

            onTriggered: {
                if(ball.x + ball.width >= table.width)
                    running = false

                else if(ball.x <= 0)
                    ball.xincrement *= -1

                else if (collision())
                    ball.xincrement *= -1

                ball.x = ball.x + (ball.xincrement * 1.5);
                ball.y = ball.y + (ball.yincrement * 1.5);

                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: 50

    MouseArea {
        anchors.fill: parent
        drag.target: root
        drag.axis: Drag.YAxis
        drag.minimumY: table.y
        drag.maximumY: table.y + table.height - 50
    }
}
1

There are 1 best solutions below

7
On

For simple checks, whether a point is within a Item or not, you can use contains(point p).

This function needs a point in local coordinates, (relative to the Items origin), so you should use mapFromItem(...) or mapToItem(...) to get the right position.