亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

PyQt5 像素級碰撞檢測

PyQt5 像素級碰撞檢測

慕田峪7331174 2022-10-06 18:44:16
我正在學習 Python,并想用 PyQ5t 制作一個簡單的平臺游戲。目前,當我想在游戲中的形狀之間進行像素級碰撞檢測時,我遇到了麻煩。我已將 QPixMap 設置為透明,并嘗試使用 QGraphicsPixmapItem.HeuristicMaskShape 形狀模式,但碰撞檢測不起作用。如果我將形狀(在這種情況下為鼠標)背景設為灰色并刪除形狀模式,則會發生矩形碰撞檢測。我在這里缺少什么?我花了幾個小時在互聯網上挖掘,但還沒有解決方案......這是我顯示問題的代碼,請使用箭頭鍵移動紅色的“鼠標”:) 我希望在紅色圓圈中的第一個像素接觸棕色平臺時看到碰撞檢測文本。import sysfrom PyQt5.QtGui import QPen, QBrushfrom PyQt5 import QtCore, QtGuifrom PyQt5.QtCore import Qt, QPointfrom PyQt5.QtWidgets import QApplication, QWidget, QGraphicsView, QGraphicsScene, QLabel, QGraphicsPixmapItem, QFrameclass Mouse(QGraphicsPixmapItem):    def __init__(self, parent):        super().__init__()        self.canvas = QtGui.QPixmap(40,40)        self.canvas.fill(Qt.transparent)        self.setPixmap(self.canvas)        self.x = 100        self.y = 100        self.setPos(self.x, self.y)        self.setFlag(QGraphicsPixmapItem.ItemIsMovable)        self.setFlag(QGraphicsPixmapItem.ItemIsFocusable)        self.setShapeMode(QGraphicsPixmapItem.HeuristicMaskShape)        self.setFocus()        parent.addItem(self)    def paint(self, painter, option, widget=None):        super().paint(painter, option, widget)        pen = QPen(Qt.black, 4, Qt.SolidLine)        brush = QBrush(Qt.red, Qt.SolidPattern)        painter.save()        painter.setPen(pen)        painter.setBrush(brush)        painter.drawEllipse(QPoint(20,20),16,16)        painter.restore()    def keyPressEvent(self, e):        if e.key() == Qt.Key_Right:            self.x += 5        if e.key() == Qt.Key_Left:            self.x -= 5        if e.key() == Qt.Key_Up:            self.y -= 5        if e.key() == Qt.Key_Down:            self.y += 5        self.setPos(self.x, self.y)        collides_with_items = self.collidingItems(mode=Qt.IntersectsItemShape)        if collides_with_items:            print("Collision detected!")            for item in collides_with_items:                print(item)
查看完整描述

1 回答

?
白板的微信

TA貢獻1883條經驗 獲得超3個贊

您提供的是一個空的像素圖 ( self.canvas),因此無論您選擇哪種形狀模式,它都將始終為形狀,除非您使用BoundingRectShape,它使用像素圖邊界矩形。

您手動繪制圓圈的事實并不重要,因為不考慮繪制碰撞檢測(也不應該)。

您可以覆蓋該shape()方法以提供您自己的形狀(使用 QPainterPath):

def shape(self):
    path = QtGui.QPainterPath()
    path.addEllipse(12, 12, 16, 16) 
       return path

但是,由于您只繪制一個橢圓,因此只需使用QGraphicsEllipseItem代替。


一些未經請求的建議:

  • 如果您打算使用場景(QGraphicsItem 的父項只能是另一個 QGraphicsItem),我會避免使用名稱“父項”,并且項通常不應該“添加自身”到場景中;

  • 不要覆蓋self.xand self.y,因為它們是 QGraphicsItem現有 屬性

  • 如果您在一個場景中有多個項目并且只想使用鍵盤控制一個項目,通常最好覆蓋場景或視圖的鍵事件方法(特別是如果您使用箭頭鍵:即使滾動條被隱藏,他們仍然可以攔截這些動作);

  • 如果您仍然想在項目上使用鍵盤事件,請確保項目保持鍵盤焦點:使用setFocus是不夠的,因為一旦用戶點擊其他地方它就會失去焦點;一種可能的解決方案是使用QGraphicsItem.grabKeyboard()(僅在將項目添加到場景后才有效);

  • 如果您在 QFrame 上設置樣式表,它很可能至少會部分忽略任何框架選項集(形狀、陰影等),因為它們取決于樣式/平臺;通常最好不要將樣式表與與可視化相關的 Qt 小部件的設置混合在一起,因此在您的情況下,您可能只需要添加一個帶有正確樣式表參數集的簡單 QFrame ;

  • 雖然從技術上講這不是問題,但通常最好與導入“樣式”保持一致,特別是在使用像 Qt 這樣的復雜模塊時:你要么導入單個類 ( from PyQt5.QtWidgets import QApplication, ...) 要么導入子模塊 ( from PyQt5 import QtCore, ...),否則它將使代碼只是令人困惑;


查看完整回答
反對 回復 2022-10-06
  • 1 回答
  • 0 關注
  • 86 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號