sprites and mouse events

594 views
Skip to first unread message

omcginnis

unread,
Feb 22, 2009, 6:16:44 AM2/22/09
to pyglet-users
Hello,

i'm a week into teaching myself pyglet (and python for that matter),
and i'm a bit stumped on something... is it possible to listen for
mouse events on specific sprites? I understand how to capture mouse
events via the default window handlers (i.e. on_mouse_press,
on_mouse_release, etc), but not on specific objects. I'm coming from
an AS3 background where you can attach mouse event listeners to
objects like this: someObj.addEventListener(MouseEvent.MOUSE_DOWN,
eventHandler). Is there a python/pyglet equivalent to this kind of
event handling? Basically, I want to create a sprite and have a
specific handler for when the user clicks on that sprite. Any
suggestions?

Thanks very much.

Ø

Tristam MacDonald

unread,
Feb 22, 2009, 8:22:39 AM2/22/09
to pyglet...@googlegroups.com
You can subclass sprite to add an event handler:

class Subclass(Sprite):
def __init__(self, *args):
Sprite.__init__(self, *args)
window.push_handlers(self.on_mouse_press)
def on_mouse_press(self, x, y, button, modifiers):
print 'mouse pressed on sprite', self

Or you can dynamically attach an event handler to an existing sprite:

sprite = Sprite(/*whatever*/)

def on_mouse_press(self, x, y, button, modifiers):
print 'mouse pressed on sprite', self

import types

sprite.on_mouse_press = types.MethodType(on_mouse_press, sprite, sprite.__class__) 
window.push_handlers(sprite.on_mouse_press)

omcginnis

unread,
Feb 22, 2009, 2:01:56 PM2/22/09
to pyglet-users
Tis a beautiful thing... thanks very much!

Alex Holkner

unread,
Feb 23, 2009, 5:12:09 PM2/23/09
to pyglet...@googlegroups.com
On Mon, Feb 23, 2009 at 12:22 AM, Tristam MacDonald
<swift...@gmail.com> wrote:
> You can subclass sprite to add an event handler:

Note that you'll also have to test that the mouse x,y coordinates are
actually over the sprite (for example, by checking bounds).

Alex.

omcginnis

unread,
Feb 24, 2009, 3:48:59 AM2/24/09
to pyglet-users
<alex.holk...@gmail.com> wrote:
> Note that you'll also have to test that the mouse x,y coordinates are
> actually over the sprite (for example, by checking bounds).

Yeah, I noticed that... in fact I added approximately 40 sprites to
the stage, each with their own mouse_down handler, and I quickly
noticed that everyone of the handlers executed no matter which one was
clicked :)

So, it boils down to bounds checking, huh? I thought perhaps you could
simply isolate the the event target as the sprite. But, it seems that
the event target is always the window... is this correct?

Thanks for the heads up!

Ø

On Feb 23, 2:12 pm, Alex Holkner <alex.holk...@gmail.com> wrote:
> On Mon, Feb 23, 2009 at 12:22 AM, Tristam MacDonald
>
> <swiftco...@gmail.com> wrote:
> > You can subclass sprite to add an event handler:
>
> Note that you'll also have to test that the mouse x,y coordinates are
> actually over the sprite (for example, by checking bounds).
>
> Alex.
>

Alex Holkner

unread,
Feb 24, 2009, 3:55:01 AM2/24/09
to pyglet...@googlegroups.com
On Tue, Feb 24, 2009 at 7:48 PM, omcginnis <oliv...@gmail.com> wrote:
>
> <alex.holk...@gmail.com> wrote:
>> Note that you'll also have to test that the mouse x,y coordinates are
>> actually over the sprite (for example, by checking bounds).
>
> Yeah, I noticed that... in fact I added approximately 40 sprites to
> the stage, each with their own mouse_down handler, and I quickly
> noticed that everyone of the handlers executed no matter which one was
> clicked :)
>
> So, it boils down to bounds checking, huh? I thought perhaps you could
> simply isolate the the event target as the sprite. But, it seems that
> the event target is always the window... is this correct?

That's right -- pyglet provides a lower-level interface than Flash/AS,
so you'll need to do a lot of these types of things yourself, or find
a helper library to use in conjuction with pyglet (cocos2d springs to
mind, there are others as well).

Alex.

griliard

unread,
Feb 26, 2009, 5:30:25 PM2/26/09
to pyglet-users
I use a python dictionary with a coordinate string as a key to create
a mouse hash in my code. The upside is it's a constant time lookup,
the downside is it takes more memory. You would also have to update
it to track moving sprites since I use it mostly for interface stuff
like buttons and icons.

class Screen:
def __init__(self):
self.mouse_hash={}

def hashify(self, x, y):
return "%04d%04d" % (x, y)

def add_rectangle_to_mouse_hash(self, x, y, width, height, id,
align=None):
if align=='center':
x=x-width*0.5
y=y-height*0.5
for i in range(int(x), int(x+width)):
for j in range(int(y), int(y+height)):
self.mouse_hash[self.hashify(i,j)]=id

def on_mouse_press(self, x, y, button, modifiers):
id=self.mouse_hash.get(self.hashify(x,y))
if id:
#Do whatever you want with the id

-Ryan

Martin O'Leary

unread,
Feb 26, 2009, 6:34:23 PM2/26/09
to pyglet...@googlegroups.com
You do realise that tuples are valid dictionary keys? You can replace
your self.mouse_hash[self.hashify(x, y)] with the quite satisfying
self.mouse_hash[x, y]

2009/2/26 griliard <gril...@gmail.com>:

griliard

unread,
Feb 26, 2009, 9:25:02 PM2/26/09
to pyglet-users
Nope, didn't know that. Thanks.

On Feb 26, 3:34 pm, "Martin O'Leary" <m.e.w.ole...@gmail.com> wrote:
> You do realise that tuples are valid dictionary keys? You can replace
> your self.mouse_hash[self.hashify(x, y)] with the quite satisfying
> self.mouse_hash[x, y]
>
> 2009/2/26 griliard <grili...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages