微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何检测 PyQt5 中的碰撞

如何解决如何检测 PyQt5 中的碰撞

我正在使用 PyQt 制作一个简单的游戏,但我不知道如何检测敌人和子弹之间的碰撞,有一个 C++ 实现,但我不知道如何在 PyQt 中做到这一点。它应该在 Bullet.py 文件中完成。 这些是文件

窗口.py

from PyQt6.QtWidgets import QGraphicsScene,QApplication,QGraphicsView,QGraphicsItem
from PyQt6.QtCore import Qt,QTimer
import sys
from Player import Player
from Enemy import Enemy


class Window(QGraphicsView):
    def __init__(self):
        super().__init__()

    self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBaralwaysOff)
    self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBaralwaysOff)

    self.setFixedSize(800,600)
    self.create_scene()

    self.show()




def create_scene(self):
    self.scene = QGraphicsScene()

    #create an item to put in the scene
    player = Player()

    #make rect focusable
    player.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsFocusable)
    player.setFocus()


    #by default QGraphicsRectItem has 0 length and width
    player.setRect(0,100,100)

    #add item to the scene
    self.scene.addItem(player)

    #set size of the scene
    self.scene.setSceneRect(0,800,600)

    #set the player at the botoom
    player.setPos(self.width() / 2,self.height() - player.rect().height())
     
     # create our score
    score = score()
    self.scene.addItem(score)

    self.setScene(self.scene)

    self.timer = QTimer()
    self.timer.timeout.connect(self.spawn)
    self.timer.start(2000)


def spawn(self):
    enemy = Enemy()
    self.scene.addItem(enemy)


App = QApplication(sys.argv)
window = Window() 
sys.exit(App.exec())

播放器.py

from PyQt6.QtWidgets import QGraphicsRectItem
from PyQt6.QtGui import QKeyEvent
from PyQt6.QtCore import Qt
from Bullet import MyBullet




class Player(QGraphicsRectItem):
    def __init__(self):
       super().__init__()



def keyPressEvent(self,event: QKeyEvent):
    if (event.key() == Qt.Key.Key_Left):

        if self.pos().x() > 0:
            self.setPos(self.x() - 10,self.y())

    elif (event.key() == Qt.Key.Key_Right):
        if (self.pos().x() + 100 < 800):
            self.setPos(self.x() + 10,self.y())


    elif (event.key() == Qt.Key.Key_Space):
        mybullet = MyBullet()
        mybullet.setPos(self.x(),self.y())
        self.scene().addItem(mybullet)

敌人.py

from PyQt6.QtWidgets import QGraphicsRectItem
from random import randint
from PyQt6.QtCore import QTimer


class Enemy(QGraphicsRectItem):
    def __init__(self):
        super().__init__()

    random_number = randint(10,1000) % 700
    self.setPos(random_number,0)


    self.setRect(0,100)

    self.timer = QTimer()
    self.timer.timeout.connect(self.move)
    self.timer.start(50)




def move(self):
    #move enemy to down
    self.setPos(self.x(),self.y()+5)

    if self.pos().y() + self.rect().height() < 0:
        self.scene().removeItem(self)
        print("Bullet deleted")

Bullet.py

from PyQt6.QtWidgets import QGraphicsRectItem,QGraphicsItem
from PyQt6.QtCore import QTimer
from Enemy import Enemy




class MyBullet(QGraphicsRectItem):
    def __init__(self):
        super().__init__()
    score = score() 

    self.setRect(0,10,50)

    self.timer = QTimer()
    self.timer.timeout.connect(self.move)
    self.timer.start(50)


def move(self):
    
    #This is the place for the collision 
    colliding = self.collidingItems()
    for item in colliding:
        if isinstance(item,Enemy):
            #increase the score
            score.increase()
            self.scene().removeItem(item)
            self.scene().removeItem(self)


    self.setPos(self.x(),self.y() - 10)

    if self.pos().y() + self.rect().height() < 0:
        self.scene().removeItem(self)
        print("Bullet deleted")
       

分数.py 从 PyQt6.QtWidgets 导入 qgraphicstextitem 从 PyQt6.QtCore 导入 Qt

from PyQt6.QtGui import QFont

class score(qgraphicstextitem):

    def __init__(self):
       super().__init__()

    self.score = 0

    #draw the text
    self.setPlainText("score : " + str(self.score))
    self.setDefaultTextColor(Qt.GlobalColor.red)
    self.setFont(QFont("Sanserif",18))



def increase(self):
    self.score += 1
    self.setPlainText(str(self.score))
    print(self.score)

这是 C++ 代码,我想要类似的 Python 代码

QList<QGraphicsItem *> colliding_items = collidingItems();
for (int i = 0,n = colliding_items.size(); i < n; ++i) {
    if (typeid(*(colliding_items[i])) == typeid(Enemy)) {
        scene->removeItem(colliding_items[i]);
        scene->removeItem(this);

    }
}

解决方法

QGraphicsItemcollidingItems 方法,使用 QGraphicsItem.boundingRect() 来检测碰撞。它是为 QGraphicsRectItem 实现的。所以你只需要调用它并迭代项目。

class MyBullet(QGraphicsRectItem):
    
    def move(self):
        colliding = self.collidingItems()
        for item in colliding:
            if isinstance(item,Enemy):
                self.scene().removeItem(item)
                self.scene().removeItem(self)
                return

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。