Richard Jones' Log: Another pyglet update

Sat, 13 Jan 2007

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