当前位置: 首页 > 知识库问答 >
问题:

PyGame鼠标点击检测

刘兴修
2023-03-14

我想知道如何编写代码来检测鼠标点击精灵。例如:

if #Function that checks for mouse clicked on Sprite:
    print ("You have opened a chest!")

共有3个答案

荣晨朗
2023-03-14

鼠标事件的pygame文档在这里。

您可以使用pygame。老鼠与pygame协作,按下方法。老鼠获取位置(如果需要)。

记住通过主事件循环使用鼠标单击事件。事件循环之所以更好,是因为“短点击”。您可能不会在普通机器上注意到这些,但在轨迹板上使用点击的计算机的点击周期过小。使用鼠标事件将防止出现这种情况。

编辑:要执行像素完美碰撞,请使用pygame。(传说中的)精灵collide_rect()在他们的精灵文档中找到。

督德明
2023-03-14
匿名用户

当单击鼠标按钮时,MOUSEBUTTONDOWN事件发生一次,当释放鼠标按钮时,MOUSEBUTTONUP事件发生一次。pygame.event.事件()对象有两个属性,提供有关鼠标事件的信息。pos是存储单击位置的元组。按钮存储单击的按钮。每个鼠标按钮都关联一个值。例如,属性的值1, 2, 3, 4, 5分别为鼠标左键、鼠标中键、鼠标右键、鼠标滚轮向上、鼠标滚轮向下。当按下多个键时,会发生多个鼠标按钮事件。进一步的解释可以在模块pygame.event的留档中找到。

使用rect属性的pygame.sprite.Sprite对象和碰撞点方法来查看是否单击了Sprite。将事件列表传递给更新pygame.sprite.方法,以便您可以处理Sprite类中的事件:

class SpriteObject(pygame.sprite.Sprite):
    # [...]

    def update(self, event_list):

        for event in event_list:
            if event.type == pygame.MOUSEBUTTONDOWN:
                if self.rect.collidepoint(event.pos):
                    # [...]

my_sprite = SpriteObject()
group = pygame.sprite.Group(my_sprite)

# [...]

run = True
while run:
    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.QUIT:
            run = False 

    group.update(event_list)

    # [...]

import pygame

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, color):
        super().__init__() 
        self.original_image = pygame.Surface((50, 50), pygame.SRCALPHA)
        pygame.draw.circle(self.original_image, color, (25, 25), 25)
        self.click_image = pygame.Surface((50, 50), pygame.SRCALPHA)
        pygame.draw.circle(self.click_image, color, (25, 25), 25)
        pygame.draw.circle(self.click_image, (255, 255, 255), (25, 25), 25, 4)
        self.image = self.original_image 
        self.rect = self.image.get_rect(center = (x, y))
        self.clicked = False

    def update(self, event_list):
        for event in event_list:
            if event.type == pygame.MOUSEBUTTONDOWN:
                if self.rect.collidepoint(event.pos):
                    self.clicked = not self.clicked

        self.image = self.click_image if self.clicked else self.original_image

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

sprite_object = SpriteObject(*window.get_rect().center, (128, 128, 0))
group = pygame.sprite.Group([
    SpriteObject(window.get_width() // 3, window.get_height() // 3, (128, 0, 0)),
    SpriteObject(window.get_width() * 2 // 3, window.get_height() // 3, (0, 128, 0)),
    SpriteObject(window.get_width() // 3, window.get_height() * 2 // 3, (0, 0, 128)),
    SpriteObject(window.get_width() * 2// 3, window.get_height() * 2 // 3, (128, 128, 0)),
])

run = True
while run:
    clock.tick(60)
    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.QUIT:
            run = False 

    group.update(event_list)

    window.fill(0)
    group.draw(window)
    pygame.display.flip()

pygame.quit()
exit()

请参阅在Pygame中从同一精灵类创建具有不同update()的多个精灵

鼠标的当前位置可以通过pygame确定。老鼠获取位置()。返回值是一个元组,表示鼠标光标的x和y坐标<代码>pygame。老鼠get_pressed()返回布尔值列表​​表示所有鼠标按钮的状态(TrueFalse)。只要按下按钮,按钮的状态就是True。当按下多个按钮时,列表中的多个项目为True。列表中的第一、第二和第三个元素表示鼠标左键、中键和右键。

pygame的Update方法中检测并评估鼠标状态。(传说中的)精灵精灵对象:

class SpriteObject(pygame.sprite.Sprite):
    # [...]

    def update(self, event_list):

        mouse_pos = pygame.mouse.get_pos()
        mouse_buttons = pygame.mouse.get_pressed()

        if  self.rect.collidepoint(mouse_pos) and any(mouse_buttons):
            # [...]

my_sprite = SpriteObject()
group = pygame.sprite.Group(my_sprite)

# [...]

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    group.update(event_list)

    # [...]

import pygame

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, color):
        super().__init__() 
        self.original_image = pygame.Surface((50, 50), pygame.SRCALPHA)
        pygame.draw.circle(self.original_image, color, (25, 25), 25)
        self.hover_image = pygame.Surface((50, 50), pygame.SRCALPHA)
        pygame.draw.circle(self.hover_image, color, (25, 25), 25)
        pygame.draw.circle(self.hover_image, (255, 255, 255), (25, 25), 25, 4)
        self.image = self.original_image 
        self.rect = self.image.get_rect(center = (x, y))
        self.hover = False

    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        mouse_buttons = pygame.mouse.get_pressed()

        #self.hover = self.rect.collidepoint(mouse_pos)
        self.hover = self.rect.collidepoint(mouse_pos) and any(mouse_buttons)

        self.image = self.hover_image if self.hover else self.original_image

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

sprite_object = SpriteObject(*window.get_rect().center, (128, 128, 0))
group = pygame.sprite.Group([
    SpriteObject(window.get_width() // 3, window.get_height() // 3, (128, 0, 0)),
    SpriteObject(window.get_width() * 2 // 3, window.get_height() // 3, (0, 128, 0)),
    SpriteObject(window.get_width() // 3, window.get_height() * 2 // 3, (0, 0, 128)),
    SpriteObject(window.get_width() * 2// 3, window.get_height() * 2 // 3, (128, 128, 0)),
])

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 

    group.update()

    window.fill(0)
    group.draw(window)
    pygame.display.flip()

pygame.quit()
exit()

尹辰沛
2023-03-14

我假设你的游戏有一个主循环,你所有的精灵都在一个名为精灵的列表中。

在主循环中,获取所有事件,并检查MOUSEBUTTONDOWNMOUSEBUTTONUP事件。

while ... # your main loop
  # get all events
  ev = pygame.event.get()

  # proceed events
  for event in ev:

    # handle MOUSEBUTTONUP
    if event.type == pygame.MOUSEBUTTONUP:
      pos = pygame.mouse.get_pos()

      # get a list of all sprites that are under the mouse cursor
      clicked_sprites = [s for s in sprites if s.rect.collidepoint(pos)]
      # do something with the clicked sprites...

所以基本上你必须在主循环的每一次迭代中自己检查是否点击了精灵。你会想用鼠标。get_pos()和rect。碰撞点()。

PyGame不提供事件驱动编程,例如cocos2d。

另一种方法是检查鼠标光标的位置和按下按钮的状态,但是这种方法有一些问题。

if pygame.mouse.get_pressed()[0] and mysprite.rect.collidepoint(pygame.mouse.get_pos()):
  print ("You have opened a chest!")

如果你处理了这个案子,你将不得不引入某种标志,因为否则这个代码将打印“你已经打开了一个箱子!”主循环的每次迭代。

handled = False

while ... // your loop

  if pygame.mouse.get_pressed()[0] and mysprite.rect.collidepoint(pygame.mouse.get_pos()) and not handled:
    print ("You have opened a chest!")
    handled = pygame.mouse.get_pressed()[0]

当然,您可以子类化Sprite,并添加一个名为的方法,单击后如下所示:

class MySprite(Sprite):
  ...

  def is_clicked(self):
    return pygame.mouse.get_pressed()[0] and self.rect.collidepoint(pygame.mouse.get_pos())

因此,最好使用第一种方法IMHO。

 类似资料:
  • 问题内容: 我正在学习Pygame制作带有Python的游戏。但是,我遇到了一个问题。我正在尝试检测播放器当前何时单击屏幕,但是我的代码无法正常工作。我的代码实际上是搞砸了,还是我正在使用的在线Pygame编译器? 当我运行此代码时,输​​出控制台在每秒几千次内向文本“您正在单击”发送垃圾邮件。即使我没有单击屏幕,它仍然会显示此信息。即使我的鼠标是不是 在 屏幕上。相同的文字。一遍又一遍。Pyga

  • 从pygame的api来看,它有: 但是没有办法区分右点击和左点击?

  • 我正在用python和pygame制作一个选择题问答游戏。我有圆,你想要的是当你点击圆时,它会改变宽度,使圆充满。但我不知道有哪种python函数可以做到这一点 以下是我目前的代码: 我想有这样的东西,如果鼠标悬停在圆圈和鼠标按钮向下和event.button==1然后改变宽度为0(填写) 提前谢谢! P. S.这不是我所有的代码

  • 我有一个JTable,其中第3列和第4列使用JComboBox作为单元格编辑器。第3列指定类型,第4列指定子类型。第4列中可用的子类型列表取决于用户为类型选择的值。此外,用户可以编辑类型和子类型列表(这里的详细信息并不重要,只是类型和子类型列表在运行时都可以更改)。 因为子类型组合框的内容是动态的,所以我的目的是检测用户何时单击子类型单元格,并根据该行中类型的内容设置列表模型(设置可用的子类型项列

  • 我在pygame中运行一个游戏,发现了一个漏洞。按照我的编码方式,如果鼠标出了窗口,游戏开始循环。当你得到,它将返回上次在窗口中检测到鼠标的值,但从其他方面看,没有鼠标离开窗口的指示。那么,有没有办法检查鼠标是否已经停止在pygame窗口上悬停,并离开了它?

  • 但是,鼠标中键不是由Vaadin注册的。我怎么才能让这个起作用?