mirror of
https://github.com/bevyengine/bevy
synced 2024-11-23 05:03:47 +00:00
73605f43b6
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation. This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct. Signed-off-by: Lena Milizé <me@lvmn.org> # Objective Fixes #2926. ## Solution Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`. --- ## Changelog ### Added - `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating` ### Changed - Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode` - Change `repeating: bool` field of `Timer` with `mode: TimerMode` ## Migration Guide - Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`. - Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`. - Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`. - Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`. - Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
54 lines
1.7 KiB
Rust
54 lines
1.7 KiB
Rust
//! Renders an animated sprite by loading all animation frames from a single image (a sprite sheet)
|
|
//! into a texture atlas, and changing the displayed image periodically.
|
|
|
|
use bevy::prelude::*;
|
|
|
|
fn main() {
|
|
App::new()
|
|
.insert_resource(ImageSettings::default_nearest()) // prevents blurry sprites
|
|
.add_plugins(DefaultPlugins)
|
|
.add_startup_system(setup)
|
|
.add_system(animate_sprite)
|
|
.run();
|
|
}
|
|
|
|
#[derive(Component, Deref, DerefMut)]
|
|
struct AnimationTimer(Timer);
|
|
|
|
fn animate_sprite(
|
|
time: Res<Time>,
|
|
texture_atlases: Res<Assets<TextureAtlas>>,
|
|
mut query: Query<(
|
|
&mut AnimationTimer,
|
|
&mut TextureAtlasSprite,
|
|
&Handle<TextureAtlas>,
|
|
)>,
|
|
) {
|
|
for (mut timer, mut sprite, texture_atlas_handle) in &mut query {
|
|
timer.tick(time.delta());
|
|
if timer.just_finished() {
|
|
let texture_atlas = texture_atlases.get(texture_atlas_handle).unwrap();
|
|
sprite.index = (sprite.index + 1) % texture_atlas.textures.len();
|
|
}
|
|
}
|
|
}
|
|
|
|
fn setup(
|
|
mut commands: Commands,
|
|
asset_server: Res<AssetServer>,
|
|
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
|
|
) {
|
|
let texture_handle = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png");
|
|
let texture_atlas =
|
|
TextureAtlas::from_grid(texture_handle, Vec2::new(24.0, 24.0), 7, 1, None, None);
|
|
let texture_atlas_handle = texture_atlases.add(texture_atlas);
|
|
commands.spawn(Camera2dBundle::default());
|
|
commands.spawn((
|
|
SpriteSheetBundle {
|
|
texture_atlas: texture_atlas_handle,
|
|
transform: Transform::from_scale(Vec3::splat(6.0)),
|
|
..default()
|
|
},
|
|
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
|
|
));
|
|
}
|