Обнаружение щелчка мыши Pygame

Мне было интересно, как написать код, который будет определять щелчок мышью на спрайте. Например:

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

Ответ 1

Я предполагаю, что ваша игра имеет основной цикл, и все ваши спрайты находятся в списке под названием sprites.

В своем основном цикле получите все события и проверьте событие MOUSEBUTTONDOWN или MOUSEBUTTONUP.

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...

Итак, в основном вы должны проверить на клик на спрайт на каждой итерации mainloop. Вы захотите использовать mouse.get_pos() и rect.collidepoint().

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 и добавить метод под названием is_clicked следующим образом:

class MySprite(Sprite):
  ...

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

Итак, лучше использовать первый подход IMHO.

Ответ 2

Документация pygame для событий мыши находится здесь. Вы можете использовать метод pygame.mouse.get_pressed в сотрудничестве с pygame.mouse.get_pos (при необходимости). Но, пожалуйста, используйте событие щелчка мыши через цикл основного события. Причина, по которой цикл событий лучше, вызвана "короткими щелчками". Вы можете не заметить их на обычных машинах, но компьютеры, использующие щелчки на трекпадах, имеют чрезмерно небольшие периоды щелчка. Использование событий мыши предотвратит это.

EDIT: Для выполнения идеальных столкновений с пикселями используйте pygame.sprite.collide_rect(), найденные в свои документы для спрайтов.

Ответ 3

Я искал тот же ответ на этот вопрос, и после большой царапины головы это был ответ, который я придумал:

#Python 3.4.3 with Pygame
import pygame

pygame.init()
pygame.display.set_caption('Crash!')
window = pygame.display.set_mode((300, 300))
running = True

# Draw Once
Rectplace = pygame.draw.rect(window, (255, 0, 0),(100, 100, 100, 100))
pygame.display.update()
# Main Loop
while running:
    # Mouse position and button clicking.
    pos = pygame.mouse.get_pos()
    pressed1, pressed2, pressed3 = pygame.mouse.get_pressed()
    # Check if the rect collided with the mouse pos
    # and if the left mouse button was pressed.
    if Rectplace.collidepoint(pos) and pressed1:
        print("You have opened a chest!")
    # Quit pygame.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False