diff --git a/assets/config/card.ron b/assets/config/card.ron new file mode 100644 index 0000000..16e000f --- /dev/null +++ b/assets/config/card.ron @@ -0,0 +1,27 @@ + +( + card_texture_path: "image/card/yellow_card.png", + cards: { + BasicStep: CardInfo( + name: "Basic Step", + description: "A-one and a-two and a-step.", + texture_path: "image/card/step.png", + ), + DoubleBeat: CardInfo( + name: "Double Beat", + description: "Two beats, rapid fire!", + texture_path: "image/card/double_beat.png", + ), + CounterPoint: CardInfo( + name: "Counter Point", + description: "Notes that move apart synchronously", + texture_path: "image/card/counter_point.png", + ), + Splits: CardInfo( + name: "Splits", + description: "Split in two!", + texture_path: "image/card/splits.png", + ), + + } +) \ No newline at end of file diff --git a/assets/config/deck_dock.ron b/assets/config/deck_dock.ron index d344838..d81ede2 100644 --- a/assets/config/deck_dock.ron +++ b/assets/config/deck_dock.ron @@ -3,6 +3,6 @@ minimum_card_distance: 16, card_width: 20, dock_height: 20.0, - max_card_scale: 5, - min_card_scale: 1, + max_card_scale: 1, + min_card_scale: 0.1, ) \ No newline at end of file diff --git a/assets/image/card/counter_point.aseprite b/assets/image/card/counter_point.aseprite new file mode 100644 index 0000000..b3bbc68 Binary files /dev/null and b/assets/image/card/counter_point.aseprite differ diff --git a/assets/image/card/counter_point.png b/assets/image/card/counter_point.png new file mode 100644 index 0000000..2285a9d Binary files /dev/null and b/assets/image/card/counter_point.png differ diff --git a/assets/image/card/double_beat.aseprite b/assets/image/card/double_beat.aseprite new file mode 100644 index 0000000..f044484 Binary files /dev/null and b/assets/image/card/double_beat.aseprite differ diff --git a/assets/image/card/double_beat.png b/assets/image/card/double_beat.png new file mode 100644 index 0000000..278c114 Binary files /dev/null and b/assets/image/card/double_beat.png differ diff --git a/assets/image/card/splits.aseprite b/assets/image/card/splits.aseprite new file mode 100644 index 0000000..4b16c9c Binary files /dev/null and b/assets/image/card/splits.aseprite differ diff --git a/assets/image/card/splits.png b/assets/image/card/splits.png new file mode 100644 index 0000000..8fac2a8 Binary files /dev/null and b/assets/image/card/splits.png differ diff --git a/assets/image/card/step.aseprite b/assets/image/card/step.aseprite new file mode 100644 index 0000000..052bed8 Binary files /dev/null and b/assets/image/card/step.aseprite differ diff --git a/assets/image/card/step.png b/assets/image/card/step.png new file mode 100644 index 0000000..f80fb85 Binary files /dev/null and b/assets/image/card/step.png differ diff --git a/assets/image/card/yellow_card.aseprite b/assets/image/card/yellow_card.aseprite new file mode 100644 index 0000000..7c87f40 Binary files /dev/null and b/assets/image/card/yellow_card.aseprite differ diff --git a/assets/image/card/yellow_card.png b/assets/image/card/yellow_card.png new file mode 100644 index 0000000..09feee4 Binary files /dev/null and b/assets/image/card/yellow_card.png differ diff --git a/src/game/card.rs b/src/game/card.rs index f9a51fb..ec5eb71 100644 --- a/src/game/card.rs +++ b/src/game/card.rs @@ -1,53 +1,89 @@ -use bevy::asset::embedded_asset; use bevy::ecs::system::SystemId; +use bevy::ecs::system::SystemState; use bevy::prelude::*; use bevy::utils::HashMap; -use pyri_state::prelude::*; +use serde::Deserialize; +use serde::Serialize; -use crate::screen::Screen; +use crate::util::prelude::*; pub(super) fn plugin(app: &mut App) { - // TODO: setup correct asset loading for cards - embedded_asset!(app, "cards/sample_card.png"); + app.configure::>(); +} - app.add_systems( - StateFlush, - Screen::Playing.on_edge(exit_playing, enter_playing), - ); +#[derive(Asset, Reflect, Serialize, Deserialize)] +pub struct CardConfig { + pub card_texture_path: String, + #[serde(skip)] + pub card_texture: Handle, + cards: HashMap, } -#[derive(Eq, PartialEq, Hash, Copy, Clone)] -pub enum CardKey { - Placeholder, +#[derive(Asset, Reflect, Serialize, Deserialize)] +struct CardInfo { + name: String, + description: String, + texture_path: String, + #[serde(skip)] + texture: Handle, +} + +impl Config for CardConfig { + const PATH: &'static str = "config/card.ron"; + const EXTENSION: &'static str = "card.ron"; + + fn on_load(&mut self, world: &mut World) { + let id = world.register_system(basic_attack); + let mut system_state = SystemState::>::new(world); + let asset_server = system_state.get_mut(world); + + self.card_texture = asset_server.load(&self.card_texture_path); + for card in self.cards.values_mut() { + card.texture = asset_server.load(&card.texture_path); + } + + let cards = self.cards.iter().map(|(key, value)| { + ( + *key, + Card { + display_name: value.name.clone(), + description: value.description.clone(), + action: id, + texture: value.texture.clone(), + }, + ) + }); + + world.insert_resource(CardStorage(cards.collect())); + } + + fn is_ready(&self, asset_server: &AssetServer) -> bool { + asset_server.is_loaded_with_dependencies(&self.card_texture) + && self + .cards + .values() + .all(|x| asset_server.is_loaded_with_dependencies(&x.texture)) + } } -// TODO: Remove this `allow` later. #[allow(dead_code)] pub struct Card { - pub path: String, + pub display_name: String, + pub description: String, + pub texture: Handle, pub action: SystemId, } +#[derive(Reflect, Eq, PartialEq, Hash, Copy, Clone, Serialize, Deserialize)] +pub enum CardKey { + BasicStep, + DoubleBeat, + CounterPoint, + Splits, +} + #[derive(Resource, Deref, DerefMut)] pub struct CardStorage(pub HashMap); // TODO: Move this into a sub-folder of storing different attacks? fn basic_attack(In(_): In) {} - -fn enter_playing(world: &mut World) { - let id = world.register_system(basic_attack); - world.insert_resource(CardStorage( - [( - CardKey::Placeholder, - Card { - path: "embedded://blobo_party/game/cards/sample_card.png".to_string(), - action: id, - }, - )] - .into(), - )); -} - -fn exit_playing(mut _commands: Commands) { - // TODO: despawn cards? -} diff --git a/src/game/deck.rs b/src/game/deck.rs index 42e327a..eb4c3ea 100644 --- a/src/game/deck.rs +++ b/src/game/deck.rs @@ -11,9 +11,11 @@ use crate::screen::Screen; pub(super) fn plugin(app: &mut App) { app.add_systems( Update, - Screen::Playing.on_update((execute_queued_cards - .in_set(UpdateSet::Update) - .run_if(on_step(4)),)), + Screen::Playing.on_update( + execute_queued_cards + .in_set(UpdateSet::Update) + .run_if(resource_added::.and_then(on_step(4))), + ), ); } @@ -37,11 +39,7 @@ impl Deck { pub fn create_deck(mut entity: EntityWorldMut) { entity.insert(Deck { - cards: vec![ - CardKey::Placeholder, - CardKey::Placeholder, - CardKey::Placeholder, - ], + cards: vec![], next_card: 0, }); } diff --git a/src/game/deck_dock.rs b/src/game/deck_dock.rs index 05141b2..d00b802 100644 --- a/src/game/deck_dock.rs +++ b/src/game/deck_dock.rs @@ -1,12 +1,11 @@ use bevy::prelude::*; -use bevy::render::texture::ImageLoaderSettings; -use bevy::render::texture::ImageSampler; use leafwing_input_manager::common_conditions::action_just_pressed; use pyri_state::prelude::*; use serde::Deserialize; use serde::Serialize; use crate::core::UpdateSet; +use crate::game::card::CardConfig; use crate::game::card::CardKey; use crate::game::card::CardStorage; use crate::game::step::on_step; @@ -97,7 +96,7 @@ struct CardPosition(usize); fn add_card(mut added_card_event_writer: EventWriter) { added_card_event_writer.send(AddCardEvent { - card: CardKey::Placeholder, + card: CardKey::BasicStep, index: 0, }); } @@ -126,22 +125,37 @@ fn handle_added_cards( } fn visual_card(mut entity: EntityWorldMut, card_key: CardKey) { - let asset_server = entity.world().resource::(); + let config_handle = entity.world().resource::>(); + let config = r!(entity + .world() + .resource::>() + .get(&config_handle.0),); + + entity + .insert((ImageBundle { + style: Style { + position_type: PositionType::Absolute, + ..default() + }, + transform: Transform::from_scale(Vec3::splat(0.1)), + image: UiImage::new(config.card_texture.clone()), + ..default() + },)) + .with_children(|children| { + children.spawn_with(move |e: EntityWorldMut| add_icon(e, card_key)); + }); +} + +fn add_icon(mut entity: EntityWorldMut, card_key: CardKey) { let card_storage = entity.world().resource::(); - let card_path = card_storage[&card_key].path.clone(); + let card = &card_storage[&card_key]; entity.insert((ImageBundle { style: Style { - position_type: PositionType::Absolute, + position_type: PositionType::Relative, ..default() }, - transform: Transform::from_scale(Vec3::splat(5.0)), - image: UiImage::new(asset_server.load_with_settings( - card_path, - |settings: &mut ImageLoaderSettings| { - settings.sampler = ImageSampler::linear(); - }, - )), + image: UiImage::new(card.texture.clone()), ..default() },)); }