use bevy::prelude::*;
use bevy_sprite3d::prelude::*;
#[derive(States, Hash, Clone, PartialEq, Eq, Debug, Default)] #[rustfmt::skip]
enum GameState { #[default] Loading, Ready }
#[derive(Resource, Default)]
struct ImageAssets
{
image: Handle<Image>, layout: Handle<TextureAtlasLayout>, }
#[derive(Component, Deref, DerefMut)]
struct AnimationTimer(Timer);
fn main()
{
App::new().add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
.add_plugins(Sprite3dPlugin)
.init_state::<GameState>()
.add_systems(Startup,
|asset_server: Res<AssetServer>,
mut assets: ResMut<ImageAssets>,
#[rustfmt::skip]
mut texture_atlases: ResMut<Assets<TextureAtlasLayout>>| {
assets.image = asset_server.load("gabe-idle-run.png");
assets.layout = texture_atlases.add(
TextureAtlasLayout::from_grid(UVec2::new(24, 24), 7, 1, None, None)
);
})
.add_systems(Update, setup.run_if(in_state(GameState::Loading)))
.add_systems(Update, animate_sprite.run_if(in_state(GameState::Ready)))
.insert_resource(ImageAssets::default())
.run();
}
#[rustfmt::skip]
fn setup(
asset_server : Res<AssetServer>,
assets : Res<ImageAssets>,
mut commands : Commands,
mut next_state : ResMut<NextState<GameState>>,
) {
if !asset_server.get_load_state(assets.image.id()).is_some_and(|s| s.is_loaded()) { return; }
next_state.set(GameState::Ready);
commands.spawn(Camera3d::default()).insert(Transform::from_xyz(0., 0., 5.));
let texture_atlas = TextureAtlas {
layout: assets.layout.clone(),
index: 3,
};
commands.spawn((
Sprite { image: assets.image.clone(), texture_atlas: Some(texture_atlas), ..default() },
Sprite3d {
pixels_per_metre: 32.,
alpha_mode: AlphaMode::Blend,
unlit: true,
..default()
},
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
));
}
fn animate_sprite(time: Res<Time>,
atlases: Res<Assets<TextureAtlasLayout>>,
mut query: Query<(&mut AnimationTimer, &mut Sprite)>)
{
for (mut timer, mut sprite) in query.iter_mut() {
timer.tick(time.delta());
if timer.just_finished() {
let atlas = sprite.texture_atlas.as_mut().unwrap();
if let Some(layouts) = atlases.get(&atlas.layout) {
atlas.index = (atlas.index + 1) % layouts.textures.len();
}
}
}
}