web-dev-qa-db-fra.com

Détection de clic de souris Pygame

Je me demandais comment écrire du code qui détecterait le clic de la souris sur un Sprite. Par exemple:

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

Je suppose que votre jeu a une boucle principale, et tous vos sprites sont dans une liste appelée sprites.

Dans votre boucle principale, récupérez tous les événements et recherchez l'événement MOUSEBUTTONDOWN ou 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...

Donc, fondamentalement, vous devez vérifier vous-même un clic sur un Sprite à chaque itération de la boucle principale. Vous voudrez utiliser mouse.get_pos () et rect.collidepoint () .

Pygame n'offre pas de programmation événementielle, comme par ex. cocos2d le fait.

Une autre façon serait de vérifier la position du curseur de la souris et l'état des boutons enfoncés, mais cette approche a quelques problèmes.

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

Vous devrez introduire une sorte de drapeau si vous avez traité ce cas, car sinon ce code affichera "Vous avez ouvert un coffre!" à chaque itération de la boucle principale.

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]

Bien sûr, vous pouvez sous-classer Sprite et ajouter une méthode appelée is_clicked comme ça:

class MySprite(Sprite):
  ...

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

Il est donc préférable d'utiliser la première approche à mon humble avis.

28
sloth

La documentation pygame pour les événements de souris est ici . Vous pouvez soit utiliser la méthode pygame.mouse.get_pressed En collaboration avec le pygame.mouse.get_pos (Si nécessaire). Mais veuillez utiliser l'événement de clic de souris via une boucle d'événement principale. La raison pour laquelle la boucle d'événement est meilleure est due aux "clics courts". Vous ne les remarquerez peut-être pas sur les machines normales, mais les ordinateurs qui utilisent les tap-click sur les trackpads ont des périodes de clic excessivement petites. L'utilisation des événements de la souris empêchera cela.

EDIT: Pour effectuer des collisions parfaites de pixels, utilisez pygame.Sprite.collide_rect() trouvé sur leurs documents pour les sprites .

6
jakebird451

Je cherchais la même réponse à cette question et après avoir beaucoup gratté la tête, voici la réponse que j'ai trouvée:

#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
4
James Abela