首页 > 解决方案 > 处理pygame中重叠对象的点击

问题描述

我正在构建一个非常简单的等距游戏原型,使用pygame.

由于我对pygame游戏开发非常陌生,因此我不确定如何处理单击具有重叠rects 的多个对象。游戏将泥土块“堆叠”起来,使其看起来像一块土地。玩家应该能够独立单击每个图块。

你能告诉我怎么做吗?

在此处输入图像描述

标签: pythonpygameoverlap

解决方案


这个概念很简单:

您将所有可拖动对象存储在列表中。每当在对象上检测到点击时:

  1. 查找该对象的列表索引。

  2. 检查是否选择了列表中索引大于当前对象(这意味着它们被绘制在当前对象上方)的任何其他对象。如果是,请不要调用该drag函数,如果不是,请调用它。

  3. 在我们调用函数之前,确保重新定位当前对象的列表索引;因为我们只是点击了它,它应该在所有其他对象之上,所以remove从列表中的对象,append到最后。

这是该概念的实现:

import pygame

pygame.init()
screen = pygame.display.set_mode((500, 500))

objs = []

class Obj:
    def __init__(self, x, y, w, h, color):
        self.rect = pygame.rect.Rect(x, y, w, h)
        self.dragging = False
        self.color = color
        objs.append(self)

    def clicked(self, m_pos):
        return self.rect.collidepoint(m_pos)

    def set_offset(self, m_pos):
        self.dragging = True
        m_x, m_y = m_pos
        self.offset_x = self.rect.x - m_x
        self.offset_y = self.rect.y - m_y

    def drag(self, m_pos):
        m_x, m_y = m_pos
        self.rect.x = m_x + self.offset_x
        self.rect.y = m_y + self.offset_y

    def draw(self):
        pygame.draw.rect(screen, self.color, self.rect)

square1 = Obj(200, 170, 100, 100, (255, 0, 0))
square2 = Obj(150, 300, 100, 100, (0, 255, 0))
square3 = Obj(220, 30, 100, 100, (0, 0, 255))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                for square in objs:
                    if square.clicked(event.pos):
                        o = objs[objs.index(square)+1:]
                        if not any(s.clicked(event.pos) for s in o):
                            objs.remove(square)
                            objs.append(square)
                            square.set_offset(event.pos)
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                for square in objs:
                    square.dragging = False
        elif event.type == pygame.MOUSEMOTION:
            for square in objs:
                if square.dragging:
                    square.drag(event.pos)
    screen.fill((255, 255, 255))
    for square in objs:
        square.draw()
    pygame.display.update()

输出:

在此处输入图像描述


推荐阅读