⚠️ Beta State

PyBevy is in an early and experimental stage. The API is incomplete, subject to breaking changes without notice, and you should expect bugs. Many features are still under development.

Player Input

Move a sprite using the keyboard.

Introduction

Games need to respond to player input. pybevy provides a simple way to read the state of the keyboard, mouse, and gamepads through Resources.

In this example, we'll read the keyboard to move a sprite around the screen.

from pybevy.prelude import *

The Player

We'll create a Player marker component to easily identify our player's sprite. The setup system spawns the camera and the player sprite.

@component
class Player(Component):
    pass
 
def setup(commands: Commands, asset_server: AssetServer):
    commands.spawn(Camera2d())
    commands.spawn(
        Sprite(image=asset_server.load_image("branding/icon.png")),
        Player(),
    )

The Movement System

This system runs every frame and checks the state of the arrow keys.

  • Res<ButtonInput<KeyCode>>: This is a Resource that holds the state of every key on the keyboard.
  • .pressed(KeyCode.ArrowLeft): This method returns True if the key is currently held down.
  • time.delta_seconds(): This gives us the time elapsed since the last frame. Multiplying our movement by this value makes the movement speed independent of the frame rate.
def player_movement_system(
    time: Res[Time],
    keyboard_input: Res[ButtonInput],
    query: Query[Mut[Transform], With[Player]],
):
    player_speed = 200.0
    for transform in query:
        direction = Vec3.ZERO
        if keyboard_input.pressed(KeyCode.ArrowLeft):
            direction.x -= 1.0
        if keyboard_input.pressed(KeyCode.ArrowRight):
            direction.x += 1.0
        if keyboard_input.pressed(KeyCode.ArrowUp):
            direction.y += 1.0
        if keyboard_input.pressed(KeyCode.ArrowDown):
            direction.y -= 1.0
 
        if direction.length() > 0.0:
            transform.translation += direction.normalize() * player_speed * time.delta_secs()

Running the App

Now, we add our systems to the app. When you run it, you'll be able to move the PyBevy logo with your arrow keys!

@entrypoint
def main(app: App) -> App:
    return (
        app
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, player_movement_system)
    )
 
if __name__ == "__main__":
    main().run()