diff --git a/assets/config/actor.ron b/assets/config/actor.ron new file mode 100644 index 0000000..877d0c8 --- /dev/null +++ b/assets/config/actor.ron @@ -0,0 +1,14 @@ +( + actors: { + "lucy": Actor( + name: "Lucy", + texture_path: "image/lucy.png", + texture_atlas_grid: TextureAtlasGrid( + tile_size: UVec2(8, 8), + columns: 5, + rows: 1, + ), + ), + }, + player: "lucy", +) diff --git a/assets/image/lucy.aseprite b/assets/image/lucy.aseprite new file mode 100644 index 0000000..7d494a8 Binary files /dev/null and b/assets/image/lucy.aseprite differ diff --git a/assets/image/lucy.png b/assets/image/lucy.png new file mode 100644 index 0000000..336ddc5 Binary files /dev/null and b/assets/image/lucy.png differ diff --git a/assets/mockup/blobo.aseprite b/assets/mockup/blobo.aseprite deleted file mode 100644 index bde100d..0000000 Binary files a/assets/mockup/blobo.aseprite and /dev/null differ diff --git a/src/game.rs b/src/game.rs index 272d4e0..3c0fead 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,5 +1,6 @@ //! Game mechanics and content +pub mod actor; mod step; use bevy::prelude::*; @@ -9,7 +10,7 @@ use crate::util::prelude::*; pub(super) fn plugin(app: &mut App) { app.configure::(); - app.add_plugins(step::plugin); + app.add_plugins((actor::plugin, step::plugin)); } #[derive(Resource, Reflect)] diff --git a/src/game/actor.rs b/src/game/actor.rs new file mode 100644 index 0000000..8e98f20 --- /dev/null +++ b/src/game/actor.rs @@ -0,0 +1,79 @@ +use bevy::ecs::system::EntityCommand; +use bevy::ecs::system::SystemState; +use bevy::prelude::*; +use bevy::utils::HashMap; +use serde::Deserialize; +use serde::Serialize; + +use crate::util::prelude::*; + +pub(super) fn plugin(app: &mut App) { + app.configure::>(); +} + +// TODO: Require all actor assets loaded before continuing to `Screen::Playing`. +#[derive(Asset, Reflect, Serialize, Deserialize)] +struct ActorConfig { + actors: HashMap, + player: String, +} + +impl Config for ActorConfig { + const PATH: &'static str = "config/actor.ron"; + + const EXTENSION: &'static str = "actor.ron"; + + fn on_load(&mut self, world: &mut World) { + let mut system_state = + SystemState::<(Res, ResMut>)>::new(world); + let (asset_server, mut layouts) = system_state.get_mut(world); + + for actor in self.actors.values_mut() { + actor.texture = asset_server.load(&actor.texture_path); + actor.texture_atlas_layout = layouts.add(&actor.texture_atlas_grid); + } + } +} + +#[derive(Reflect, Serialize, Deserialize)] +struct Actor { + name: String, + texture_path: String, + #[serde(skip)] + texture: Handle, + texture_atlas_grid: TextureAtlasGrid, + #[serde(skip)] + texture_atlas_layout: Handle, +} + +fn actor_helper(mut entity: EntityWorldMut, key: Option) { + let config_handle = entity.world().resource::>(); + let config = r!(entity + .world() + .resource::>() + .get(&config_handle.0)); + let actor = r!(config.actors.get(key.as_ref().unwrap_or(&config.player))); + + entity.insert(( + Name::new(actor.name.clone()), + SpriteBundle { + texture: actor.texture.clone_weak(), + ..default() + }, + TextureAtlas { + layout: actor.texture_atlas_layout.clone_weak(), + index: 0, + }, + )); +} + +pub fn actor(key: impl Into) -> impl EntityCommand { + let key = key.into(); + move |entity: EntityWorldMut| { + actor_helper(entity, Some(key)); + } +} + +pub fn player(entity: EntityWorldMut) { + actor_helper(entity, None); +} diff --git a/src/screen/playing.rs b/src/screen/playing.rs index 2e3acd6..aabf309 100644 --- a/src/screen/playing.rs +++ b/src/screen/playing.rs @@ -1,3 +1,4 @@ +use bevy::math::vec3; use bevy::prelude::*; use bevy_asset_loader::prelude::*; use leafwing_input_manager::common_conditions::action_just_pressed; @@ -6,6 +7,7 @@ use pyri_state::prelude::*; use pyri_state::schedule::ResolveStateSet; use crate::core::camera::CameraRoot; +use crate::game::actor; use crate::screen::fade_in; use crate::screen::Screen; use crate::ui::prelude::*; @@ -33,6 +35,12 @@ impl Configure for PlayingAssets { fn enter_playing(mut commands: Commands) { commands.spawn_with(fade_in); + commands.spawn_with(actor::player); + commands + .spawn_with(actor::actor("lucy")) + .insert(TransformBundle::from_transform( + Transform::from_translation(vec3(10.0, 0.0, 0.0)), + )); } fn exit_playing(