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
}
}
For simple checks, whether a point is within a
Item
or not, you can usecontains(point p)
.This function needs a point in local coordinates, (relative to the
Item
s origin), so you should usemapFromItem(...)
ormapToItem(...)
to get the right position.