pyglet's tile/sprite bits got event handling in the last couple of days. I reckon it's pretty cool and should greatly simplify development of sprite/tile based games (that use the mouse). It looks like (given a view):
# attach the following event handler to the view
@event(view)
# only highlight cells
@for_cells()
def on_mouse_enter(cells, x, y):
' The mouse is hovering over the indicated cells. '
@event(view)
@for_cells()
def on_mouse_leave(cells):
' The mouse has stopped hovering over these cells. '
@event(view)
# just for the car sprite
@for_sprites([car])
def on_mouse_press(sprites, button, x, y, modifiers):
' Car has been clicked '
# also:
def on_mouse_release(sprites_or_cells, button, x, y, modifiers):
pass
def on_mouse_drag(sprites_or_cells, x, y, dx, dy, buttons, modifiers):
pass
def on_view_enter(sprites_or_cells, x, y):
''' sprite or cell has entered the View (even if potentially
obscured by another cell / sprite) '''
def on_view_leave(sprites_or_cells, x, y):
' sprite or cell has left the View '
@event says what event dispatcher to hook the handler on to. The @for_cells() call tells the dispatcher to generate events for all map cells for all maps in the view. We could have passed a list of maps to interrogate as @for_cells([m1, m2, m3]). We also could have said @for_cells(is_base=True) to have it only generate events for cells that have properties['is_base'] == True. If we didn't say @for_cells then we'd get events for sprites too. For example:
@for_cells() # for any map cell
@for_cells([map, map]) # may have multiple maps
# event could be generated for every cell in the map(s)
@for_cells([map], name=value, name=value)
# looks up property by name on Cell, then Tile, then TileSet
@for_cells([map], id='exit_door')
# could be defined on Cell or Tile -- "id" special-cased as an attribute
@for_cells([map], red_base=True)
@for_cells([map], type='grass')
# would be defined on Tiles by convention - but there's nothing
# stopping an exceptional Cell having a "type" property
@for_cells([map], group='grass')
# would be defined on TileSets by convention
@for_sprites() # all sprites are active
@for_sprites([list of sprites]) # limited list of sprites active
# filters may be chained:
@event(view)
@for_cells([map1], ...)
@for_cells([map2], ...)
def on_mouse_press(cell, ...):
...
There's a practical demonstration of this and another new feature -- adding drawing effects to Cells, Tiles, etc (any "Drawable") -- in tests/scene2d/RECT_FLAT_MOUSE.py