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.
Mouse Input
Handle mouse clicks, motion, and scroll wheel input.
Introduction
The keyboard tutorial covered ButtonInput for key presses. Mouse input works
similarly but adds motion and scroll events.
Key types:
Res[ButtonInput]withMouseButton: Check click state (aliased asMouseInput).MessageReader[MouseMotion]: Read mouse movement deltas.MessageReader[MouseWheel]: Read scroll wheel events.AccumulatedMouseMotion: Resource with total mouse delta for the frame.
from pybevy.prelude import *
from pybevy.input import MouseButton, MouseInput, MouseMotion, MouseWheel, AccumulatedMouseMotionTracking Mouse Clicks
MouseInput (aliased from Res[ButtonInput]) works just like keyboard input:
.pressed(), .just_pressed(), .just_released().
@component
class Clickable(Component):
pass
def mouse_click_system(
mouse: Res[MouseInput],
):
if mouse.just_pressed(MouseButton.Left()):
print("Left click!")
if mouse.just_pressed(MouseButton.Right()):
print("Right click!")
if mouse.just_pressed(MouseButton.Middle()):
print("Middle click!")Reading Mouse Motion
Mouse motion events give you the raw pixel delta each frame. This is useful for camera look, dragging, and drawing.
@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(),
)
def drag_with_mouse(
mouse: Res[MouseInput],
motion: Res[AccumulatedMouseMotion],
query: Query[Mut[Transform], With[Player]],
):
# Drag sprite while left mouse button is held
if mouse.pressed(MouseButton.Left()):
for transform in query:
transform.translation.x += motion.delta.x
# Y is inverted: screen Y goes down, world Y goes up
transform.translation.y -= motion.delta.yScroll Wheel for Zooming
Mouse wheel events have x and y components. The y value is the
vertical scroll — positive for scroll up, negative for scroll down.
def zoom_camera(
wheel: MessageReader[MouseWheel],
query: Query[Mut[Transform], With[Camera2d]],
):
for event in wheel:
for transform in query:
# Scale the camera: scroll up = zoom in, scroll down = zoom out
zoom_factor = 1.0 - event.y * 0.1
transform.scale = transform.scale * zoom_factorRunning the App
When you run this, drag the sprite with left click and zoom with the scroll wheel.
@entrypoint
def main(app: App) -> App:
return (
app
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, (mouse_click_system, drag_with_mouse, zoom_camera))
)
if __name__ == "__main__":
main().run()