views:

1472

answers:

2

What is the canonical way of making your sprites respond to mouse clicks in PyGame ?

Here's something simple, in my event loop:

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        exit_game()
    [...]
    elif (  event.type == pygame.MOUSEBUTTONDOWN and
            pygame.mouse.get_pressed()[0]):
        for sprite in sprites:
            sprite.mouse_click(pygame.mouse.get_pos())

Some questions about it:

  1. Is this the best way of responding to mouse clicks ?
  2. What if the mouse stays pressed on the sprite for some time ? How do I make a single event out of it ?
  3. Is this a reasonable way to notify all my sprites of the click ?

Thanks in advance

A: 

2: pygame.MOUSEBUTTONUP

thereisnospork
But then how do I know which button was it ?
Eli Bendersky
+3  A: 

I usually give my clickable objects a click function, like in your example. I put all of those objects in a list, for easy iteration when the click functions are to be called.

when checking for which mousebutton you press, use the button property of the event.

import pygame
from pygame.locals import * #This lets you use pygame's constants directly.

for event in pygame.event.get():
    if event.type == MOUSEBUTTONDOWN:  #Better to seperate to a new if statement aswell, since there's more buttons that can be clicked and makes for cleaner code.
        if event.button == 1:
            for object in clickableObjectsList:
                object.clickCheck(event.pos)

I would say this is the recommended way of doing it. The click only registers once, so it wont tell your sprite if the user is "dragging" with a button. That can easily be done with a boolean that is set to true with the MOUSEBUTTONDOWN event, and false with the MOUSEBUTTONUP. The have "draggable" objects iterated for activating their functions... and so on.

However, if you don't want to use an event handler, you can let an update function check for input with:

pygame.mouse.get_pos() 
pygame.mouse.get_pressed().

This is a bad idea for larger projects, since it can create hard to find bugs. Better just keeping events in one place. Smaller games, like simple arcade games might make more sense using the probing style though.

Sir Oddfellow
Thanks. About the `event.button == 1` part, is there no constant instead of that explicit 1 in PyGame ?
Eli Bendersky
I don't think there's a need for it. 1 is always the left button, 2 the middle, and 3 is the right. 3 is the right even on mouses with only two buttons.
Sir Oddfellow