### Quick Start Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/README.md This example demonstrates how to set up Bevy with the AsepriteUltraPlugin and spawn an animated sprite and a static slice. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(AsepriteUltraPlugin) .add_systems(Startup, setup) .run(); } fn setup(mut cmd: Commands, server: Res) { // Animated sprite cmd.spawn(( AseAnimation { animation: Animation::tag("walk"), aseprite: server.load("player.aseprite"), }, Sprite::default(), )); // Static slice cmd.spawn(( AseSlice { name: "sword".into(), aseprite: server.load("items.aseprite"), }, Sprite::default(), )); } ``` -------------------------------- ### Installation Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/plugin.md How to add AsepriteUltraPlugin to a Bevy app and spawn an entity with an AseAnimation component. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(AsepriteUltraPlugin) // Add here .add_systems(Startup, setup) .run(); } fn setup(mut cmd: Commands, server: Res) { cmd.spawn(( AseAnimation { animation: Animation::tag("idle"), aseprite: server.load("player.aseprite"), }, Sprite::default(), )); } ``` -------------------------------- ### Running Examples Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/README.md Instructions on how to run the provided examples. ```bash cargo run --example ``` -------------------------------- ### Example Commands Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/README.md Commands to run the various examples provided by the crate. ```bash cargo run --example slices cargo run --example animations cargo run --example ui cargo run --example asset_processing --features asset_processing cargo run --example 3d --features 3d ``` -------------------------------- ### Setup for Manual Frame Control Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/animation-state.md Example setup function to spawn an entity with AseAnimation and ManualTick, disabling automatic frame advancement. ```rust use bevy_aseprite_ultra::prelude::*; fn setup(mut cmd: Commands, server: Res) { cmd.spawn(( AseAnimation { animation: Animation::tag("walk"), aseprite: server.load("player.aseprite"), }, Sprite::default(), ManualTick, // Disable automatic frame advancement )); } ``` -------------------------------- ### Playing an Animation Instantly with `play` Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/animation.md Example of how to instantly start a new animation, clearing any previously queued animations, within a Bevy system. ```rust fn on_input( mut animations: Query<&mut AseAnimation>, input: Res>, ) { if input.just_pressed(KeyCode::KeyW) { if let Ok(mut anim) = animations.get_single_mut() { anim.animation.play("walk-up", AnimationRepeat::Loop); } } } ``` -------------------------------- ### System Ordering Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/plugin.md An example of how to order custom systems relative to the plugin's animation rendering systems, using `PostUpdate` and `after`. ```rust app.add_systems( PostUpdate, my_system.after(render_animation::), ) ``` -------------------------------- ### Setup with ManualTick Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/advanced-components.md Example of setting up an entity with `AseAnimation`, `Sprite`, and `ManualTick` to disable automatic ticking. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn setup(mut cmd: Commands, server: Res) { cmd.spawn(( AseAnimation { animation: Animation::tag("walk"), aseprite: server.load("player.aseprite"), }, Sprite::default(), ManualTick, // Disable automatic ticking )); } ``` -------------------------------- ### Complete Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/plugin.md A full example demonstrating how to set up the Bevy Aseprite Ultra plugin, including camera, sprite animation, UI animation, and static slice usage. ```rust use bevy::prelude::* use bevy_aseprite_ultra::prelude::* fn main() { App::new() // Set up image plugin for pixel-perfect rendering .add_plugins(DefaultPlugins.set(ImagePlugin { default_sampler: bevy::render::texture::ImageSamplerDescriptor::nearest(), })) // Add the plugin .add_plugins(AsepriteUltraPlugin) // Your systems .add_systems(Startup, setup) .add_systems(Update, player_input) .add_systems(Update, handle_events) .run(); } fn setup(mut cmd: Commands, server: Res) { cmd.spawn(Camera2d::default()); // Sprite animation cmd.spawn(( AseAnimation { animation: Animation::tag("idle"), aseprite: server.load("player.aseprite"), }, Sprite::default(), Transform::default(), Player, )); // UI animation cmd.spawn(( ImageNode::default(), AseAnimation { animation: Animation::tag("spinning"), aseprite: server.load("ui.aseprite"), }, Node { width: Val::Px(64.0), height: Val::Px(64.0), ..default() }, )); // Static slice cmd.spawn(( Sprite::default(), AseSlice { name: "sword".into(), aseprite: server.load("items.aseprite"), }, Transform::from_translation(Vec3::new(100.0, 0.0, 0.0)), )); } #[derive(Component)] struct Player; fn player_input( mut animations: Query<&mut AseAnimation, With>, input: Res>, ) { if let Ok(mut anim) = animations.get_single_mut() { if input.pressed(KeyCode::KeyW) { anim.animation.play("walk-up", AnimationRepeat::Loop); } else if input.pressed(KeyCode::KeyS) { anim.animation.play("walk-down", AnimationRepeat::Loop); } else { anim.animation.play("idle", AnimationRepeat::Loop); } } } fn handle_events( mut events: MessageReader, ) { for event in events.read() { match event { AnimationEvents::Finished(entity) => { println!("Animation finished on entity: {:?}", entity); } AnimationEvents::LoopCycleFinished(_) => {} } } } ``` -------------------------------- ### Complete Example: Click-to-Advance Animation Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/advanced-components.md A full Bevy application example demonstrating how to set up an animation with `ManualTick` and advance its frames on mouse clicks. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn setup(mut cmd: Commands, server: Res) { cmd.spawn(( AseAnimation { animation: Animation::tag("attack"), aseprite: server.load("player.aseprite"), }, Sprite::default(), ManualTick, )); cmd.spawn(Text::new("Click to advance frame".to_string())); } fn click_to_advance( animation_entity: Single>, input: Res>, mut cmd: Commands, ) { if input.just_pressed(MouseButton::Left) { cmd.trigger(NextFrameEvent(*animation_entity)); } } fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(AsepriteUltraPlugin) .add_systems(Startup, setup) .add_systems(Update, click_to_advance) .run(); } ``` -------------------------------- ### AnimationEvents Listener Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/types.md Example of how to listen for and handle `AnimationEvents`. ```rust fn handle_animation_events( mut events: MessageReader, mut cmd: Commands ) { for event in events.read() { match event { AnimationEvents::Finished(entity) => { cmd.entity(*entity).despawn(); } AnimationEvents::LoopCycleFinished(_) => { // Handle loop cycle } } } } ``` -------------------------------- ### Asset Loading Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/README.md Example of loading an aseprite file using the AssetServer, relative to the assets/ directory. ```rust // Relative to assets/ directory let handle: Handle = server.load("sprites/player.aseprite"); ``` -------------------------------- ### Example: Custom Sampler Configuration Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/configuration.md Per-asset loader settings (if needed for specific assets). ```rust // Per-asset loader settings (if needed for specific assets): use bevy_aseprite_ultra::prelude::AsepriteLoaderSettings; use bevy::render::texture::ImageSampler; let settings = AsepriteLoaderSettings { sampler: ImageSampler::nearest(), }; // This is typically handled automatically by Bevy's asset system ``` -------------------------------- ### Manual Animation Control Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/types.md Example of how to manually advance an animation using NextFrameEvent. ```rust let animation_entity = Entity::PLACEHOLDER; commands.trigger(NextFrameEvent(animation_entity)); ``` -------------------------------- ### Basic Animation Setup Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/animation.md Sets up a basic Aseprite animation component with an 'idle' tag. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn setup(mut cmd: Commands, server: Res) { cmd.spawn(( AseAnimation { animation: Animation::tag("idle"), aseprite: server.load("player.aseprite"), }, Sprite::default(), )); } ``` -------------------------------- ### Removal Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/plugin.md Illustrates how to 'remove' the plugin by simply not adding it to the Bevy application. ```rust // Don't add it App::new() .add_plugins(DefaultPlugins) // No AsepriteUltraPlugin here ``` -------------------------------- ### get_atlas_index Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/aseprite-asset.md An example demonstrating how to use the get_atlas_index method to find the texture atlas index for a specific frame. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn get_frame_texture( aseprites: Res>, handle: Handle, ) { if let Some(aseprite) = aseprites.get(&handle) { let atlas_index = aseprite.get_atlas_index(5); // Frame 5 println!("Frame 5 is at atlas index: {}", atlas_index); } } ``` -------------------------------- ### Query Animation State Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-animation.md Example of querying for AseAnimation and AnimationState components to get animation details. ```rust fn check_animation_state( animations: Query<(&AseAnimation, &AnimationState)>, ) { for (anim, state) in animations.iter() { println!("Current frame: {}", state.current_frame); println!("Relative frame: {}", state.relative_frame); println!("Time in frame: {:?}", state.elapsed); println!("Playing: {}", anim.animation.playing); } } ``` -------------------------------- ### Recommended setup for games Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/plugin.md Configures the Bevy application with default plugins and the AsepriteUltraPlugin, specifically setting the ImagePlugin for pixel-perfect rendering. ```rust use bevy::image::ImageSamplerDescriptor; App::new() .add_plugins(DefaultPlugins.set(ImagePlugin { default_sampler: ImageSamplerDescriptor::nearest(), // Pixel-perfect })) .add_plugins(AsepriteUltraPlugin) // ... rest of your setup ``` -------------------------------- ### Get Tag Frame Range Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/aseprite-asset.md Demonstrates how to retrieve and print the frame range of a specific animation tag from an Aseprite asset. ```rust fn get_tag_frames( aseprites: Res>, handle: Handle, tag_name: &str, ) { if let Some(aseprite) = aseprites.get(&handle) { if let Some(tag) = aseprite.tags.get(tag_name) { println!("Tag '{}' frames: {:?}", tag_name, tag.range); let frame_count = tag.range.end() - tag.range.start() + 1; println!("Frame count: {}", frame_count); } } } ``` -------------------------------- ### Feature Flags: 3d Usage Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/configuration.md Usage example for the 3d feature. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn setup( mut cmd: Commands, server: Res, mut materials: ResMut>, ) { cmd.spawn(( AseAnimation { animation: Animation::tag("walk"), aseprite: server.load("player.aseprite"), }, MeshMaterial3d(materials.add(MyMaterial::default())), )); } ``` -------------------------------- ### Finished Event Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/advanced-components.md An example of how to listen for the `Finished` animation event and despawn the entity when an animation completes. ```rust fn on_animation_finished( mut events: MessageReader, mut cmd: Commands, ) { for event in events.read() { if let AnimationEvents::Finished(entity) = event { println!("Animation on {:?} finished", entity); cmd.entity(*entity).despawn(); } } } ``` -------------------------------- ### Spawning a Demo Animation Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/README.md Example of how to load and configure an animation from an aseprite file using the `AseAnimation` component. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; ... // Load an animation from an aseprite file fn spawn_demo_animation(mut cmd : Commands, server : Res){ cmd.spawn(( AseAnimation { aseprite: server.load("player.aseprite"), animation: Animation::tag("walk-right") .with_repeat(AnimationRepeat::Count(1)) .with_speed(2.) // Aseprite provides a repeat config per tag, which is beeing ignored on purpose. .with_repeat(AnimationRepeat::Count(42)) // The direction is provided by the asperite config for the tag, but can be overwritten. .with_direction(AnimationDirection::PingPong) // you can also chain finite animations, loop animations will never finish .with_then("walk-left", AnimationRepeat::Count(4)) .with_then("walk-up", AnimationRepeat::Loop), }, // The Render target. There are default impls for Sprite, Ui and 3D. // You may also define your own. Checkout the examples. Sprite { flip_x: true, ..default() }, )); } ``` -------------------------------- ### Preload Assets Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/aseprite-asset.md Example of preloading multiple aseprite assets using the AssetServer. ```rust fn preload(server: Res) { let _handle = server.load("sprites/player.aseprite"); let _handle = server.load("sprites/enemies.aseprite"); let _handle = server.load("ui/icons.aseprite"); } ``` -------------------------------- ### RenderAnimation Implementation Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/render-traits.md Example of implementing RenderAnimation for a custom component type. ```rust use bevy_aseprite_ultra::prelude::*; impl RenderAnimation for MyComponent { type Extra<'e> = (); // Add parameters if needed fn render_animation( &mut self, aseprite: &Aseprite, state: &AnimationState, _extra: &mut Self::Extra<'_>, ) { // Update self with frame data let atlas_index = aseprite.get_atlas_index(usize::from(state.current_frame)); self.current_frame = atlas_index; } } ``` -------------------------------- ### Custom Material and RenderAnimation Implementation Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/render-traits.md A complete example demonstrating how to define a custom material and implement the RenderAnimation trait for it, along with its usage in Bevy. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; // Custom material #[derive(Asset, TypePath, AsBindGroup, Clone)] pub struct MyAnimatedMaterial { #[texture(0)] #[sampler(1)] pub texture: Handle, #[uniform(2)] pub time: f32, } impl Material2d for MyAnimatedMaterial {} // Implement RenderAnimation impl RenderAnimation for MyAnimatedMaterial { type Extra<'e> = Res<'e, Time>; fn render_animation( &mut self, aseprite: &Aseprite, state: &AnimationState, time: &mut Self::Extra<'_>, ) { self.texture = aseprite.atlas_image.clone(); self.time = time.elapsed_secs(); } } // Use in Bevy fn setup( mut cmd: Commands, server: Res, mut materials: ResMut>, ) { let material = MyAnimatedMaterial { texture: Handle::default(), time: 0.0, }; cmd.spawn(( AseAnimation { animation: Animation::tag("walk"), aseprite: server.load("player.aseprite"), }, MeshMaterial2d(materials.add(material)), Mesh2d(/* mesh here */), )); } ``` -------------------------------- ### Get All Slices Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-slice.md Query pattern to get all slices. ```rust fn update_all_slices(mut slices: Query<&mut AseSlice>) { for mut slice in slices.iter_mut() { // Update all slices } } ``` -------------------------------- ### Custom RenderSlice Implementation Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/render-traits.md Example of implementing RenderSlice for a custom material type, including its usage. ```rust use bevy_aseprite_ultra::prelude::*; impl RenderSlice for MyMaterial { type Extra<'e> = Res<'e, Time>; fn render_slice( &mut self, aseprite: &Aseprite, slice_meta: &SliceMeta, time: &mut Self::Extra<'_>, ) { self.texture = aseprite.atlas_image.clone(); self.rect = slice_meta.rect; self.timestamp = time.elapsed_secs(); } } // Use it fn setup( mut cmd: Commands, server: Res, mut materials: ResMut>, ) { cmd.spawn(( AseSlice { name: "icon_sword".into(), aseprite: server.load("items.aseprite"), }, MeshMaterial2d(materials.add(MyMaterial::default())), )); } ``` -------------------------------- ### LoopCycleFinished Event Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/advanced-components.md An example of how to listen for the `LoopCycleFinished` animation event and increment a counter for each completed loop cycle. ```rust #[derive(Component)] struct LoopCounter { cycles: u32, } fn count_loops( mut events: MessageReader, mut counters: Query<&mut LoopCounter>, entities: Query<&LoopCounter>, ) { for event in events.read() { if let AnimationEvents::LoopCycleFinished(entity) = event { if let Ok(mut counter) = counters.get_mut(*entity) { counter.cycles += 1; println!("Loop cycle {}", counter.cycles); } } } } ``` -------------------------------- ### Loading Aseprite Assets Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/configuration.md Example of how to load an Aseprite file as a Bevy asset and spawn it with an AseAnimation component. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn setup(mut cmd: Commands, server: Res) { // Asset path is relative to assets/ directory let handle: Handle = server.load("sprites/player.aseprite"); cmd.spawn(( AseAnimation { animation: Animation::tag("idle"), aseprite: handle, }, Sprite::default(), )); } ``` -------------------------------- ### Feature Flags: asset_processing Usage Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/configuration.md Usage example for the asset_processing feature. ```rust use bevy::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins.set(AssetPlugin { mode: AssetMode::Processed, ..Default::default() })) .add_plugins(AsepriteUltraPlugin) .run(); } ``` -------------------------------- ### Pause/Resume Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-animation.md Example of pausing and resuming an animation. ```rust fn toggle_pause( mut animations: Query<&mut AseAnimation>, input: Res>, ) { if input.just_pressed(KeyCode::Space) { if let Ok(mut anim) = animations.get_single_mut() { if anim.animation.playing { anim.animation.pause(); } else { anim.animation.start(); } } } } ``` -------------------------------- ### Example Split of Aseprite Files Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/configuration.md Demonstrates how to load multiple Aseprite files if a single file exceeds texture atlas limits. ```rust // Instead of one large file, use multiple: let player_top = server.load("player_top.aseprite"); let player_bottom = server.load("player_bottom.aseprite"); ``` -------------------------------- ### Advanced: Multiple Extra Parameters Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/render-traits.md An example showing how to implement RenderAnimation with multiple associated extra parameters. ```rust impl RenderAnimation for ComplexMaterial { type Extra<'e> = ( Res<'e, Time>, Res<'e, GameState>, ResMut<'e, Assets>, ); fn render_animation( &mut self, aseprite: &Aseprite, state: &AnimationState, extra: &mut Self::Extra<'_>, ) { let (time, state, materials) = extra; // Use all three parameters } } ``` -------------------------------- ### Handling Animation Events Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/README.md Example of how to listen for and react to animation events, such as when an animation finishes. ```rust // animation events // this is useful for one shot animations like explosions fn despawn_on_finish(mut events: EventReader, mut cmd : Commands){ for event in events.read() { match event { AnimationEvents::Finished(entity) => cmd.entity(*entity).despawn_recursive(), // you can also listen for loop cycle repeats AnimationEvents::LoopCycleFinished(_entity) => (), }; } } ``` -------------------------------- ### Asset Processing Feature Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/plugin.md Enabling the 'asset_processing' feature for optimized asset loading. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins.set(AssetPlugin { mode: AssetMode::Processed, ..Default::default() })) .add_plugins(AsepriteUltraPlugin) // Automatically uses processor .run(); } ``` -------------------------------- ### Playing an Animation in a Loop with `play_loop` Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/animation.md Shows how to start an animation that will loop indefinitely, clearing the animation queue. ```rust anim.animation.play_loop("idle"); ``` -------------------------------- ### Animation Events Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-animation.md Example of listening for animation completion events. ```rust fn on_animation_finish( mut events: MessageReader, mut cmd: Commands, ) { for event in events.read() { match event { AnimationEvents::Finished(entity) => { println!("Animation finished, despawning entity"); cmd.entity(*entity).despawn(); } AnimationEvents::LoopCycleFinished(entity) => { println!("Loop cycle finished"); } } } } ``` -------------------------------- ### Control Animation at Runtime Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/README.md Example demonstrating how to change the currently playing animation based on user input. ```rust fn change_animation( mut animations: Query<&mut AseAnimation>, input: Res>, ) { if let Ok(mut anim) = animations.get_single_mut() { if input.pressed(KeyCode::KeyW) { anim.animation.play("walk", AnimationRepeat::Loop); } else { anim.animation.play("idle", AnimationRepeat::Loop); } } } ``` -------------------------------- ### Animations in Bevy UI Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/README.md Example of how to use `AseAnimation` with `ImageNode` for animations within the Bevy UI. ```rust // animations in bevy ui cmd.spawn(( Button, ImageNode::default(), // RenderTarget AseAnimation { aseprite: server.load("player.aseprite"), animation: Animation::tag("walk-right"), }, )); ``` -------------------------------- ### Spawning a Demo Static Slice Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/README.md Example of how to load a static sprite from an aseprite file using slices and the `AseSlice` component. ```rust // Load a static slice from an aseprite file // create for any static atlas with marked regions aka slices. fn spawn_demo_static_slice(mut cmd : Commands, server : Res){ cmd.spawn(( AseSlice { name: "ghost_red".into(), aseprite: server.load("ball.aseprite"), }, Sprite::default(), )); } ``` -------------------------------- ### Basic Asset Loading Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/aseprite-asset.md Example of how to load an aseprite file using Bevy's asset system and spawn an AseAnimation component. ```rust fn setup(mut cmd: Commands, server: Res) { let handle: Handle = server.load("sprites/player.aseprite"); cmd.spawn(( AseAnimation { animation: Animation::tag("idle"), aseprite: handle, }, Sprite::default(), )); } ``` -------------------------------- ### Asset Not Ready Check Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-animation.md Example of checking if an aseprite asset has loaded using the Assets resource. ```rust fn check_loaded( animations: Query<&AseAnimation>, aseprites: Res>, ) { for anim in animations.iter() { if aseprites.contains(&anim.aseprite) { println!("Animation asset loaded and ready"); } else { println!("Animation asset still loading..."); } } } ``` -------------------------------- ### UI Animation Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-animation.md Example of setting up a UI animation using the AseAnimation component with ImageNode. ```rust fn setup(mut cmd: Commands, server: Res) { cmd.spawn(( Button, ImageNode::default(), // UI render target AseAnimation { animation: Animation::tag("idle"), aseprite: server.load("ui.aseprite"), }, )); } ``` -------------------------------- ### Load and Play an Animation Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/README.md Example of how to spawn an entity with an AseAnimation component to load and play an animation. ```rust fn setup(mut cmd: Commands, server: Res) { cmd.spawn(( AseAnimation { animation: Animation::tag("walk"), aseprite: server.load("player.aseprite"), }, Sprite::default(), )); } ``` -------------------------------- ### Sprite Animation Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-animation.md Basic example of setting up a sprite animation using the AseAnimation component. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn setup(mut cmd: Commands, server: Res) { // Simple animation with defaults cmd.spawn(( AseAnimation { animation: Animation::tag("walk"), aseprite: server.load("player.aseprite"), }, Sprite::default(), Transform::default(), )); } ``` -------------------------------- ### Query All Animations Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-animation.md Example of querying all AseAnimation components to modify them, such as changing playback speed. ```rust fn update_all_animations( mut animations: Query<&mut AseAnimation>, ) { for mut anim in animations.iter_mut() { anim.animation.speed *= 1.1; } } ``` -------------------------------- ### Automatic Management Example Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/animation-state.md Example of how AnimationState is automatically added to an entity when an AseAnimation component is present, ensured by the #[require(AnimationState)] attribute. ```rust fn setup(mut cmd: Commands, server: Res) { cmd.spawn(( AseAnimation { animation: Animation::tag("walk"), aseprite: server.load("player.aseprite"), }, Sprite::default(), // AnimationState is automatically added by the #[require(...)] attribute )); } ``` -------------------------------- ### Change Animation Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-animation.md Example of changing the current animation at runtime. ```rust fn player_input( mut animations: Query<&mut AseAnimation>, input: Res>, ) { if let Ok(mut anim) = animations.get_single_mut() { if input.just_pressed(KeyCode::KeyW) { anim.animation.play("walk-up", AnimationRepeat::Loop); } else if input.just_released(KeyCode::KeyW) { anim.animation.play("idle", AnimationRepeat::Loop); } } } ``` -------------------------------- ### Sending the NextFrameEvent Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/advanced-components.md Example function demonstrating how to send a `NextFrameEvent` to advance an animation. ```rust use bevy::prelude::*; use bevy_aseprite_ultra::prelude::*; fn trigger_next_frame( entity: Entity, mut cmd: Commands, ) { cmd.trigger(NextFrameEvent(entity)); } ``` -------------------------------- ### Registering AnimationState for Reflection Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/animation-state.md Example of how to register the AnimationState type for Bevy's reflection system. ```rust app.register_type::(); ``` -------------------------------- ### Checking Loaded Frames Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/aseprite-asset.md Example of how to check the number of frames in a loaded Aseprite asset and print their durations. ```rust fn check_frames( aseprites: Res>, handle: Handle, ) { if let Some(aseprite) = aseprites.get(&handle) { let frame_count = aseprite.frame_durations.len(); println!("Aseprite has {} frames", frame_count); for (i, duration) in aseprite.frame_durations.iter().enumerate() { println!(" Frame {}: {:.2}ms", i, duration.as_secs_f32() * 1000.0); } } } ``` -------------------------------- ### Chain Animations Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/README.md Example of chaining multiple animations together using the Animation builder API. ```rust let anim = Animation::tag("attack1") .with_repeat(AnimationRepeat::Count(1)) .with_then("attack2", AnimationRepeat::Count(1)) .with_then("idle", AnimationRepeat::Loop); ``` -------------------------------- ### UI Layout with Slices Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-slice.md Example of using slices for UI layout, such as an inventory grid. ```rust fn setup(mut cmd: Commands, server: Res) { // Inventory grid for row in 0..4 { for col in 0..4 { cmd.spawn(( Node { width: Val::Px(64.0), height: Val::Px(64.0), margin: UiRect::all(Val::Px(4.0)), ..default() }, ImageNode::default(), AseSlice { name: "empty_slot".into(), aseprite: server.load("ui.aseprite"), }, )); } } } ``` -------------------------------- ### Slices in Bevy UI Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/README.md Example of how to use `AseSlice` with `ImageNode` for static sprites within the Bevy UI. ```rust // slices in bevy ui cmd.spawn(( Node { width: Val::Px(100.), height: Val::Px(100.), border: UiRect::all(Val::Px(5.)), ..default() }, ImageNode::default(), // RenderTarget AseSlice { name: "ghost_red".into(), aseprite: server.load("ghost_slices.aseprite"), }, )); ``` -------------------------------- ### Toggle Between Slices Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-slice.md Example system to toggle between two slices using the Space key. ```rust #[derive(Component)] pub struct TogglableSlice { slices: [String; 2], current: usize, } fn toggle_slice( mut slices: Query<(&mut AseSlice, &mut TogglableSlice)>, input: Res>, ) { if input.just_pressed(KeyCode::Space) { for (mut slice, mut toggle) in slices.iter_mut() { toggle.current = (toggle.current + 1) % toggle.slices.len(); slice.name = toggle.slices[toggle.current].clone(); } } } ``` -------------------------------- ### Control Multiple Animations Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/advanced-components.md This example demonstrates how to trigger the next frame for multiple Aseprite animations simultaneously using a button press. ```rust fn advance_multiple_animations( animations: Query>, input: Res>, mut cmd: Commands, ) { if input.just_pressed(KeyCode::Space) { for entity in animations.iter() { cmd.trigger(NextFrameEvent(entity)); } } } ``` -------------------------------- ### Cycle Through Multiple Slices Source: https://github.com/lommix/bevy_aseprite_ultra/blob/master/_autodocs/api-reference/ase-slice.md Example system to cycle through a list of slices over time. ```rust #[derive(Component)] pub struct SliceCycle { current: usize, slices: Vec, } fn cycle_slice( mut cycles: Query<(&mut AseSlice, &mut SliceCycle)>, time: Res