from dataclasses import dataclass
from pybevy.prelude import *
@component
@dataclass
class AnimationIndices(Component):
first: int
last: int
@component(storage="python")
@dataclass
class AnimationTimer(Component):
timer: Timer
def animate_sprite(
time: Res[Time],
query: Query[tuple[AnimationIndices, Mut[AnimationTimer], Mut[Sprite]]],
) -> None:
for indices, timer_component, sprite in query:
timer_component.timer.tick(time.delta_secs())
if timer_component.timer.just_finished():
atlas = sprite.texture_atlas
if atlas is not None:
if atlas.index == indices.last:
atlas.index = indices.first
else:
atlas.index += 1
def setup(
commands: Commands,
asset_server: Res[AssetServer],
texture_atlas_layouts: ResMut[Assets[TextureAtlasLayout]],
) -> None:
texture = asset_server.load_image("bevy/textures/rpg/chars/gabe/gabe-idle-run.png")
layout = TextureAtlasLayout.from_grid(
tile_size=UVec2.splat(24),
columns=7,
rows=1,
padding=None,
offset=None,
)
texture_atlas_layout = texture_atlas_layouts.add(layout)
animation_indices = AnimationIndices(first=1, last=6)
commands.spawn(Camera2d())
commands.spawn(
Sprite.from_atlas_image(
texture,
TextureAtlas(
layout=texture_atlas_layout,
index=animation_indices.first,
),
),
Transform.from_scale(Vec3.splat(6.0)),
animation_indices,
AnimationTimer(timer=Timer(0.1, TimerMode.REPEATING)),
)
@entrypoint
def main(app: App) -> App:
return (
app.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, animate_sprite)
)
if __name__ == "__main__":
main().run()