use std::{hash::Hash, time::Duration}; use animation::AnimBundle; use bevy::{ecs::system::SystemId, prelude::*, sprite::MaterialMesh2dBundle, utils::HashMap}; use bevy_rapier2d::prelude::*; use crate::{AppState, METER}; use super::set::IngameSet; mod animation; #[derive(Component)] struct Player; #[derive(Resource)] struct PlayerSpawnOneshot(SystemId); impl FromWorld for PlayerSpawnOneshot { fn from_world(world: &mut World) -> Self { Self(world.register_system(add_player)) } } pub(super) fn player_plugin(app: &mut App) { app.add_systems(OnEnter(AppState::InGame), add_player.in_set(IngameSet)) .init_resource::(); } #[derive(Component, Hash, PartialEq, Eq, Default)] enum PlayerAnimations { #[default] Idle, Walk, } pub fn add_player( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, mut texture_atlas_layouts: ResMut>, asset_server: Res, ) { let tex_idle = asset_server.load("idle.png"); let layout_idle = TextureAtlasLayout::from_grid(UVec2::splat(512), 2, 1, None, None); let layout_idle_handle = texture_atlas_layouts.add(layout_idle); let tex_walk = asset_server.load("walk.png"); let layout_walk = TextureAtlasLayout::from_grid(UVec2::splat(512), 4, 1, None, None); let layout_walk_handle = texture_atlas_layouts.add(layout_walk); let anims = animation::AnimationManager::default() .insert( PlayerAnimations::Idle, animation::Animation::new( TextureAtlas { layout: layout_idle_handle, index: 0, }, 2, 4, tex_idle, ), ) .insert( PlayerAnimations::Walk, animation::Animation::new( TextureAtlas { layout: layout_walk_handle, index: 0, }, 2, 4, tex_walk, ), ); commands.spawn(( Player, AnimBundle { tag: PlayerAnimations::Idle, mgr: anims, }, SpriteBundle { transform: Transform::from_scale(Vec3::splat(50.)), ..Default::default() }, )); }