Events

Events are the primary way objects in ppb communicate. This module contains the events defined by various systems in ppb.

To respond to an event your event handler should be snake_cased on_event_name and accept an event instance and a signal function as parameters. Example:

class MySprite(Sprite):
    def on_update(self, event: Update, signal):
        . . .

The signal() function accepts one parameter: an instance of an event class. You are not limited to predefined event types, but can provide arbitrary instances.

Events as defined here are dataclasses.dataclass(), but ppb does not expect dataclasses; they are just a simple way to quickly define new events. The name of the handler will always be based on the name of the class, with the TitleCase name of the class converted to on_event_name function. The instance passed to signal() will be passed to all the event handlers as the event parameter.

Basic Events

These events are the basic events you’ll want to build your games. You can make a variety of games using just them.

class ppb.events.Update(time_delta: float, scene: Optional[ppb.scenes.Scene] = None)[source]

A simulation tick.

Respond via on_update to advance the simulation of your game objects. Movement and other things that happen “over time” are best implemented in your on_update methods.

scene: ppb.scenes.Scene = None

The currently running scene.

time_delta: float

Seconds since last Update

class ppb.events.PreRender(time_delta: float, scene: Optional[ppb.scenes.Scene] = None)[source]

The Renderer is preparing to render.

PreRender is called before every frame is rendered. Things that are strictly for display purposes (like the text of a score board or the position of the camera) should happen on_pre_render.

scene: ppb.scenes.Scene = None

The currently running scene.

time_delta: float

Seconds since last PreRender.

class ppb.events.ButtonPressed(button: ppb.buttons.MouseButton, position: ppb_vector.Vector, scene: Optional[ppb.scenes.Scene] = None)[source]

A mouse button was pressed.

The button is a MouseButton instance.

This represents the button in the active state. For acting when a button is released see ButtonReleased.

class ppb.events.ButtonReleased(button: ppb.buttons.MouseButton, position: ppb_vector.Vector, scene: Optional[ppb.scenes.Scene] = None)[source]

A mouse button was released.

The button is a MouseButton instance.

This represents the button in the inactive state. For acting when a button is clicked see ButtonPressed.

button: ppb.buttons.MouseButton

A mouse button: Primary, Secondary, or Tertiary

position: ppb_vector.Vector

The game-world position of the event.

scene: ppb.scenes.Scene = None

The currently running scene.

class ppb.events.KeyPressed(key: ppb.keycodes.KeyCode, mods: Set[ppb.keycodes.KeyCode], scene: Optional[ppb.scenes.Scene] = None)[source]

A keyboard key was pressed.

The buttons are defined in ppb.keycodes.

This represents the key entering an active state, to respond to when a key is released see KeyReleased.

key: ppb.keycodes.KeyCode

A KeyCode flag.

mods: Set[ppb.keycodes.KeyCode]

A set of KeyCodes

scene: ppb.scenes.Scene = None

The currently running scene

class ppb.events.KeyReleased(key: ppb.keycodes.KeyCode, mods: Set[ppb.keycodes.KeyCode], scene: Optional[ppb.scenes.Scene] = None)[source]

A keyboard key was released.

The buttons are defined in ppb.keycodes.

This represents the key entering an inactive state, to respond to when a key is pressed see KeyPressed.

key: ppb.keycodes.KeyCode

A KeyCode flag.

mods: Set[ppb.keycodes.KeyCode]

A set of KeyCodes

scene: ppb.scenes.Scene = None

The currently running scene

class ppb.events.MouseMotion(position: ppb_vector.Vector, delta: ppb_vector.Vector, buttons: Collection[ppb.buttons.MouseButton], scene: Optional[ppb.scenes.Scene] = None)[source]

The mouse moved.

If something should be tracking the mouse, this is the event to listen to.

buttons: Collection[ppb.buttons.MouseButton]

The state of the mouse buttons.

delta: ppb_vector.Vector

The change in position since the last MouseMotion event.

position: ppb_vector.Vector

The game-world location of the mouse cursor.

scene: ppb.scenes.Scene = None

The currently running scene.

Command Events

These events are used in your code to achieve certain effects.

class ppb.events.Quit(scene: Optional[ppb.scenes.Scene] = None)[source]

A request to quit the program.

Fired in response to a close request from the OS, but can be signaled from inside one of your handlers to end the program.

For example:

def on_update(self, event, signal):
    signal(Quit())

This will stop the engine.

Respond with on_quit to perform any shut down tasks (like saving data.)

scene: ppb.scenes.Scene = None

The currently running scene.

class ppb.events.StartScene(new_scene: Union[ppb.scenes.Scene, Type[ppb.scenes.Scene]], kwargs: Optional[Dict[str, Any]] = None, scene: Optional[ppb.scenes.Scene] = None)[source]

An object requested a new scene to be started.

new_scene can be an instance or a class. If a class, must include kwargs. If new_scene is an instance kwargs should be empty or None.

Before the previous scene pauses, a ScenePaused event will be fired. Any events signaled in response will be delivered to the new scene.

After the ScenePaused event and any follow up events have been delivered, a SceneStarted event will be sent.

Examples:
  • signal(new_scene=StartScene(MyScene(player=player))

  • signal(new_scene=StartScene, kwargs={“player”: player}

Warning

In general, you should not respond to StartScene, if you want to respond to a new scene, see SceneStarted.

kwargs: Dict[str, Any] = None

Keyword arguments to be passed to a scene type.

new_scene: Union[ppb.scenes.Scene, Type[ppb.scenes.Scene]]

A Scene class or instance

scene: ppb.scenes.Scene = None

The currently running scene.

class ppb.events.ReplaceScene(new_scene: Union[ppb.scenes.Scene, Type[ppb.scenes.Scene]], kwargs: Optional[Dict[str, Any]] = None, scene: Optional[ppb.scenes.Scene] = None)[source]

An object requested a new scene to replace it.

new_scene can be an instance or a class. If a class, must include kwargs. If new_scene is an instance kwargs should be empty or None.

Before the previous scene stops, a SceneStopped event will be fired. Any events signaled in response will be delivered to the new scene.

After the SceneStopped event and any follow up events have been delivered, a SceneStarted event will be sent.

Examples:
  • signal(ReplaceScene(MyScene(player=player))

  • signal(ReplaceScene(new_scene=ReplacementScene, kwargs={“player”: player}))

Warning

In general, you should not respond to ReplaceScene, if you want to respond to a new scene, see SceneStarted.

kwargs: Dict[str, Any] = None

Keyword arguments to be passed to a scene type.

new_scene: Union[ppb.scenes.Scene, Type[ppb.scenes.Scene]]

A Scene class or instance

scene: ppb.scenes.Scene = None

The currently running scene.

class ppb.events.StopScene(scene: Optional[ppb.scenes.Scene] = None)[source]

An object has requested the current scene be stopped.

Before the scene stops, a SceneStopped event will be fired. Any events signaled in response will be delivered to the previous scene if it exists.

If there is a paused scene on the stack, a SceneContinued event will be fired after the responses to the SceneStopped event.

Warning

In general, you should not respond to StopScene, if you want to respond to a scene ending, see SceneStopped.

scene: ppb.scenes.Scene = None

The scene that is stopping.

class ppb.events.PlaySound(sound: ppb.assetlib.Asset)[source]

An object requested a sound be played.

Signal in an event handler to have a sound played.

Example:

signal(PlaySound(my_sound))
sound: ppb.assetlib.Asset

A Sound asset.

Scene Transition Events

These are events triggered during the lifetime of a scene: it starting, stopping, etc.

The scene property on these events always refers to the scene these are about—ScenePaused.scene is the scene that is being paused.

class ppb.events.SceneStarted(scene: Optional[ppb.scenes.Scene] = None)[source]

A new scene has started running.

This is delivered to a Scene shortly after it starts.

Responding to SceneStarted is a good choice for ppb.systems that change behavior based on the running scene, or if you have start up work that requires the initial state to be set before it happens.

The scene lifetime events happen in the following order:

  1. Always: SceneStarted

  2. Optionally, Repeatable: ScenePaused

  3. Optionally, Repeatable: SceneContinued

  4. Optionally: SceneStopped

scene: ppb.scenes.Scene = None

The scene that is starting.

class ppb.events.ScenePaused(scene: Optional[ppb.scenes.Scene] = None)[source]

A scene that is running is being paused to allow a new scene to run.

This is delivered to a scene about to be paused when a StartScene event is sent to the engine. When this scene resumes it will receive a SceneContinued event.

A middle event in the scene lifetime, started with SceneStarted.

scene: ppb.scenes.Scene = None

The scene that has paused.

class ppb.events.SceneContinued(scene: Optional[ppb.scenes.Scene] = None)[source]

A scene that had been paused has continued.

This is delivered to a scene as it resumes operation after being paused via a ScenePaused event.

From the middle of the event lifetime that begins with SceneStarted.

scene: ppb.scenes.Scene = None

The scene that is resuming.

class ppb.events.SceneStopped(scene: Optional[ppb.scenes.Scene] = None)[source]

A scene is being stopped and will no longer be available.

This is delivered to a scene and it’s objects when a StopScene or ReplaceScene event is sent to the engine.

This is technically an optional event, as not all scenes in the stack will receive a SceneStopped event if a Quit event was sent.

This is the end of the scene lifetime, see SceneStarted.

scene: ppb.scenes.Scene = None

The scene that is stopping.

Engine Events

These are additional events from the engine mostly for advanced purposes.

class ppb.events.Idle(time_delta: float, scene: Optional[ppb.scenes.Scene] = None)[source]

A complete loop of the GameEngine main loop has finished.

This is an engine plumbing event to pump timing information to subsystems.

scene: ppb.scenes.Scene = None

The currently running scene.

time_delta: float

Seconds since last Idle.

class ppb.events.Render(scene: Optional[ppb.scenes.Scene] = None)[source]

The Renderer is rendering.

Warning

In general, responses to Render will not be reflected until the next render pass. If you want changes to effect this frame, see PreRender

scene: ppb.scenes.Scene = None

The currently running scene.

class ppb.events.AssetLoaded(asset: ppb.assetlib.Asset, total_loaded: int, total_queued: int)[source]

An asset has finished loading.

asset: ppb.assetlib.Asset

A Asset

total_loaded: int

The total count of loaded assets.

total_queued: int

The number of requested assets still waiting.