Iam making a simple game using PyQt, but i don’t know how i can detect the collisions between enemy and bullets, there is a C++ implementation, but i dont know how i can do that in PyQt. and it should be done in Bullet.py file. these are the files.
Window.py
JavaScript
x
65
65
1
from PyQt6.QtWidgets import QGraphicsScene,QApplication, QGraphicsView, QGraphicsItem
2
from PyQt6.QtCore import Qt, QTimer
3
import sys
4
from Player import Player
5
from Enemy import Enemy
6
7
8
class Window(QGraphicsView):
9
def __init__(self):
10
super().__init__()
11
12
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
13
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
14
15
self.setFixedSize(800, 600)
16
self.create_scene()
17
18
self.show()
19
20
21
22
23
def create_scene(self):
24
self.scene = QGraphicsScene()
25
26
#create an item to put in the scene
27
player = Player()
28
29
#make rect focusable
30
player.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsFocusable)
31
player.setFocus()
32
33
34
#by default QGraphicsRectItem has 0 length and width
35
player.setRect(0,0, 100,100)
36
37
#add item to the scene
38
self.scene.addItem(player)
39
40
#set size of the scene
41
self.scene.setSceneRect(0, 0, 800, 600)
42
43
#set the player at the botoom
44
player.setPos(self.width() / 2, self.height() - player.rect().height())
45
46
# create our score
47
score = Score()
48
self.scene.addItem(score)
49
50
self.setScene(self.scene)
51
52
self.timer = QTimer()
53
self.timer.timeout.connect(self.spawn)
54
self.timer.start(2000)
55
56
57
def spawn(self):
58
enemy = Enemy()
59
self.scene.addItem(enemy)
60
61
62
App = QApplication(sys.argv)
63
window = Window()
64
sys.exit(App.exec())
65
Player.py
JavaScript
1
30
30
1
from PyQt6.QtWidgets import QGraphicsRectItem
2
from PyQt6.QtGui import QKeyEvent
3
from PyQt6.QtCore import Qt
4
from Bullet import MyBullet
5
6
7
8
9
class Player(QGraphicsRectItem):
10
def __init__(self):
11
super().__init__()
12
13
14
15
def keyPressEvent(self, event: QKeyEvent):
16
if (event.key() == Qt.Key.Key_Left):
17
18
if self.pos().x() > 0:
19
self.setPos(self.x() - 10, self.y())
20
21
elif (event.key() == Qt.Key.Key_Right):
22
if (self.pos().x() + 100 < 800):
23
self.setPos(self.x() + 10, self.y())
24
25
26
elif (event.key() == Qt.Key.Key_Space):
27
mybullet = MyBullet()
28
mybullet.setPos(self.x(), self.y())
29
self.scene().addItem(mybullet)
30
Enemy.py
JavaScript
1
30
30
1
from PyQt6.QtWidgets import QGraphicsRectItem
2
from random import randint
3
from PyQt6.QtCore import QTimer
4
5
6
class Enemy(QGraphicsRectItem):
7
def __init__(self):
8
super().__init__()
9
10
random_number = randint(10,1000) % 700
11
self.setPos(random_number , 0)
12
13
14
self.setRect(0,0,100,100)
15
16
self.timer = QTimer()
17
self.timer.timeout.connect(self.move)
18
self.timer.start(50)
19
20
21
22
23
def move(self):
24
#move enemy to down
25
self.setPos(self.x(), self.y()+5)
26
27
if self.pos().y() + self.rect().height() < 0:
28
self.scene().removeItem(self)
29
print("Bullet deleted")
30
Bullet.py
JavaScript
1
38
38
1
from PyQt6.QtWidgets import QGraphicsRectItem, QGraphicsItem
2
from PyQt6.QtCore import QTimer
3
from Enemy import Enemy
4
5
6
7
8
class MyBullet(QGraphicsRectItem):
9
def __init__(self):
10
super().__init__()
11
score = Score()
12
13
self.setRect(0,0,10,50)
14
15
self.timer = QTimer()
16
self.timer.timeout.connect(self.move)
17
self.timer.start(50)
18
19
20
def move(self):
21
22
#This is the place for the collision
23
colliding = self.collidingItems()
24
for item in colliding:
25
if isinstance(item, Enemy):
26
#increase the score
27
score.increase()
28
self.scene().removeItem(item)
29
self.scene().removeItem(self)
30
31
32
self.setPos(self.x(), self.y() - 10)
33
34
if self.pos().y() + self.rect().height() < 0:
35
self.scene().removeItem(self)
36
print("Bullet deleted")
37
38
Score.py from PyQt6.QtWidgets import QGraphicsTextItem from PyQt6.QtCore import Qt
JavaScript
1
21
21
1
from PyQt6.QtGui import QFont
2
3
class Score(QGraphicsTextItem):
4
5
def __init__(self):
6
super().__init__()
7
8
self.score = 0
9
10
#draw the text
11
self.setPlainText("Score : " + str(self.score))
12
self.setDefaultTextColor(Qt.GlobalColor.red)
13
self.setFont(QFont("Sanserif", 18))
14
15
16
17
def increase(self):
18
self.score += 1
19
self.setPlainText(str(self.score))
20
print(self.score)
21
This is the C++ code, i want similiar of that for Python.
JavaScript
1
9
1
QList<QGraphicsItem *> colliding_items = collidingItems();
2
for (int i = 0, n = colliding_items.size(); i < n; ++i) {
3
if (typeid(*(colliding_items[i])) == typeid(Enemy)) {
4
scene->removeItem(colliding_items[i]);
5
scene->removeItem(this);
6
7
}
8
}
9
Advertisement
Answer
QGraphicsItem
has collidingItems
method that use QGraphicsItem.boundingRect()
to detect collisions. It is implemented for QGraphicsRectItem
. So you only need to call it and iterate over items.
JavaScript
1
10
10
1
class MyBullet(QGraphicsRectItem):
2
3
def move(self):
4
colliding = self.collidingItems()
5
for item in colliding:
6
if isinstance(item, Enemy):
7
self.scene().removeItem(item)
8
self.scene().removeItem(self)
9
return
10