diff --git a/Cargo.lock b/Cargo.lock index c22856b..82ff31d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,7 +242,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -326,7 +326,7 @@ checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -369,9 +369,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" +checksum = "5208975e568d83b6b05cc0a063c8e7e9acc2b43bee6da15616a5b73e109d7437" dependencies = [ "jobserver", "libc", @@ -1111,7 +1111,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -1897,7 +1897,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -1927,7 +1927,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -2428,22 +2428,22 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -2703,9 +2703,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.68" +version = "2.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6" dependencies = [ "proc-macro2", "quote", @@ -2738,7 +2738,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] @@ -2978,7 +2978,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", "wasm-bindgen-shared", ] @@ -3012,7 +3012,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3696,7 +3696,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.69", ] [[package]] diff --git a/assets/entities/ghost.png b/assets/entities/ghost.png new file mode 100644 index 0000000..065843a Binary files /dev/null and b/assets/entities/ghost.png differ diff --git a/assets/furniture/bedroom/ac.png b/assets/furniture/bedroom/ac.png new file mode 100644 index 0000000..6afd96f Binary files /dev/null and b/assets/furniture/bedroom/ac.png differ diff --git a/assets/furniture/bedroom/bed.png b/assets/furniture/bedroom/bed.png new file mode 100644 index 0000000..31a6971 Binary files /dev/null and b/assets/furniture/bedroom/bed.png differ diff --git a/assets/furniture/bedroom/bookshelf.png b/assets/furniture/bedroom/bookshelf.png new file mode 100644 index 0000000..aa1f8c6 Binary files /dev/null and b/assets/furniture/bedroom/bookshelf.png differ diff --git a/assets/furniture/bedroom/couch.png b/assets/furniture/bedroom/couch.png new file mode 100644 index 0000000..5be07ee Binary files /dev/null and b/assets/furniture/bedroom/couch.png differ diff --git a/assets/furniture/bedroom/cupboard.png b/assets/furniture/bedroom/cupboard.png new file mode 100644 index 0000000..a04685f Binary files /dev/null and b/assets/furniture/bedroom/cupboard.png differ diff --git a/assets/furniture/bedroom/display_off.png b/assets/furniture/bedroom/display_off.png new file mode 100644 index 0000000..167d216 Binary files /dev/null and b/assets/furniture/bedroom/display_off.png differ diff --git a/assets/furniture/bedroom/display_on.png b/assets/furniture/bedroom/display_on.png new file mode 100644 index 0000000..63caaa8 Binary files /dev/null and b/assets/furniture/bedroom/display_on.png differ diff --git a/assets/furniture/bedroom/drawer.png b/assets/furniture/bedroom/drawer.png new file mode 100644 index 0000000..3dc372e Binary files /dev/null and b/assets/furniture/bedroom/drawer.png differ diff --git a/assets/furniture/bedroom/elec/ac.png b/assets/furniture/bedroom/elec/ac.png new file mode 100644 index 0000000..b06c68f Binary files /dev/null and b/assets/furniture/bedroom/elec/ac.png differ diff --git a/assets/furniture/bedroom/elec/display_off.png b/assets/furniture/bedroom/elec/display_off.png new file mode 100644 index 0000000..b9c337b Binary files /dev/null and b/assets/furniture/bedroom/elec/display_off.png differ diff --git a/assets/furniture/bedroom/elec/display_on.png b/assets/furniture/bedroom/elec/display_on.png new file mode 100644 index 0000000..203edd3 Binary files /dev/null and b/assets/furniture/bedroom/elec/display_on.png differ diff --git a/assets/furniture/bedroom/elec/keyboard.png b/assets/furniture/bedroom/elec/keyboard.png new file mode 100644 index 0000000..467c6d1 Binary files /dev/null and b/assets/furniture/bedroom/elec/keyboard.png differ diff --git a/assets/furniture/bedroom/elec/laptop_off.png b/assets/furniture/bedroom/elec/laptop_off.png new file mode 100644 index 0000000..ef2125b Binary files /dev/null and b/assets/furniture/bedroom/elec/laptop_off.png differ diff --git a/assets/furniture/bedroom/elec/laptop_on.png b/assets/furniture/bedroom/elec/laptop_on.png new file mode 100644 index 0000000..0dafdfa Binary files /dev/null and b/assets/furniture/bedroom/elec/laptop_on.png differ diff --git a/assets/furniture/bedroom/elec/mini_ac.png b/assets/furniture/bedroom/elec/mini_ac.png new file mode 100644 index 0000000..72bb3e5 Binary files /dev/null and b/assets/furniture/bedroom/elec/mini_ac.png differ diff --git a/assets/furniture/bedroom/elec/mouse.png b/assets/furniture/bedroom/elec/mouse.png new file mode 100644 index 0000000..a52559f Binary files /dev/null and b/assets/furniture/bedroom/elec/mouse.png differ diff --git a/assets/furniture/bedroom/elec/nightlight.png b/assets/furniture/bedroom/elec/nightlight.png new file mode 100644 index 0000000..0453cbc Binary files /dev/null and b/assets/furniture/bedroom/elec/nightlight.png differ diff --git a/assets/furniture/bedroom/elec/pc.png b/assets/furniture/bedroom/elec/pc.png new file mode 100644 index 0000000..6dd2087 Binary files /dev/null and b/assets/furniture/bedroom/elec/pc.png differ diff --git a/assets/furniture/bedroom/elec/phone.png b/assets/furniture/bedroom/elec/phone.png new file mode 100644 index 0000000..8209f0d Binary files /dev/null and b/assets/furniture/bedroom/elec/phone.png differ diff --git a/assets/furniture/bedroom/elec/receiver.png b/assets/furniture/bedroom/elec/receiver.png new file mode 100644 index 0000000..af14a3e Binary files /dev/null and b/assets/furniture/bedroom/elec/receiver.png differ diff --git a/assets/furniture/bedroom/elec/tv.png b/assets/furniture/bedroom/elec/tv.png new file mode 100644 index 0000000..a0717a8 Binary files /dev/null and b/assets/furniture/bedroom/elec/tv.png differ diff --git a/assets/furniture/bedroom/elec/window_ac.png b/assets/furniture/bedroom/elec/window_ac.png new file mode 100644 index 0000000..de76c65 Binary files /dev/null and b/assets/furniture/bedroom/elec/window_ac.png differ diff --git a/assets/furniture/bedroom/keyboard.png b/assets/furniture/bedroom/keyboard.png new file mode 100644 index 0000000..66f9605 Binary files /dev/null and b/assets/furniture/bedroom/keyboard.png differ diff --git a/assets/furniture/bedroom/laptop_off.png b/assets/furniture/bedroom/laptop_off.png new file mode 100644 index 0000000..422ebdf Binary files /dev/null and b/assets/furniture/bedroom/laptop_off.png differ diff --git a/assets/furniture/bedroom/laptop_on.png b/assets/furniture/bedroom/laptop_on.png new file mode 100644 index 0000000..dacd39b Binary files /dev/null and b/assets/furniture/bedroom/laptop_on.png differ diff --git a/assets/furniture/bedroom/metal/ac.png b/assets/furniture/bedroom/metal/ac.png new file mode 100644 index 0000000..64331a0 Binary files /dev/null and b/assets/furniture/bedroom/metal/ac.png differ diff --git a/assets/furniture/bedroom/metal/bed.png b/assets/furniture/bedroom/metal/bed.png new file mode 100644 index 0000000..6240803 Binary files /dev/null and b/assets/furniture/bedroom/metal/bed.png differ diff --git a/assets/furniture/bedroom/metal/cupboard.png b/assets/furniture/bedroom/metal/cupboard.png new file mode 100644 index 0000000..5d456ae Binary files /dev/null and b/assets/furniture/bedroom/metal/cupboard.png differ diff --git a/assets/furniture/bedroom/metal/display_off.png b/assets/furniture/bedroom/metal/display_off.png new file mode 100644 index 0000000..317414c Binary files /dev/null and b/assets/furniture/bedroom/metal/display_off.png differ diff --git a/assets/furniture/bedroom/metal/display_on.png b/assets/furniture/bedroom/metal/display_on.png new file mode 100644 index 0000000..2911755 Binary files /dev/null and b/assets/furniture/bedroom/metal/display_on.png differ diff --git a/assets/furniture/bedroom/metal/drawer.png b/assets/furniture/bedroom/metal/drawer.png new file mode 100644 index 0000000..b3f1b0d Binary files /dev/null and b/assets/furniture/bedroom/metal/drawer.png differ diff --git a/assets/furniture/bedroom/metal/keyboard.png b/assets/furniture/bedroom/metal/keyboard.png new file mode 100644 index 0000000..16ee085 Binary files /dev/null and b/assets/furniture/bedroom/metal/keyboard.png differ diff --git a/assets/furniture/bedroom/metal/laptop_off.png b/assets/furniture/bedroom/metal/laptop_off.png new file mode 100644 index 0000000..125ec32 Binary files /dev/null and b/assets/furniture/bedroom/metal/laptop_off.png differ diff --git a/assets/furniture/bedroom/metal/laptop_on.png b/assets/furniture/bedroom/metal/laptop_on.png new file mode 100644 index 0000000..6e965a1 Binary files /dev/null and b/assets/furniture/bedroom/metal/laptop_on.png differ diff --git a/assets/furniture/bedroom/metal/mini_ac.png b/assets/furniture/bedroom/metal/mini_ac.png new file mode 100644 index 0000000..684c1d6 Binary files /dev/null and b/assets/furniture/bedroom/metal/mini_ac.png differ diff --git a/assets/furniture/bedroom/metal/mouse.png b/assets/furniture/bedroom/metal/mouse.png new file mode 100644 index 0000000..5ea958d Binary files /dev/null and b/assets/furniture/bedroom/metal/mouse.png differ diff --git a/assets/furniture/bedroom/metal/nightlight.png b/assets/furniture/bedroom/metal/nightlight.png new file mode 100644 index 0000000..68ab2bc Binary files /dev/null and b/assets/furniture/bedroom/metal/nightlight.png differ diff --git a/assets/furniture/bedroom/metal/nightstand.png b/assets/furniture/bedroom/metal/nightstand.png new file mode 100644 index 0000000..34feb95 Binary files /dev/null and b/assets/furniture/bedroom/metal/nightstand.png differ diff --git a/assets/furniture/bedroom/metal/pc.png b/assets/furniture/bedroom/metal/pc.png new file mode 100644 index 0000000..c188052 Binary files /dev/null and b/assets/furniture/bedroom/metal/pc.png differ diff --git a/assets/furniture/bedroom/metal/phone.png b/assets/furniture/bedroom/metal/phone.png new file mode 100644 index 0000000..e5dfee0 Binary files /dev/null and b/assets/furniture/bedroom/metal/phone.png differ diff --git a/assets/furniture/bedroom/metal/receiver.png b/assets/furniture/bedroom/metal/receiver.png new file mode 100644 index 0000000..85998ee Binary files /dev/null and b/assets/furniture/bedroom/metal/receiver.png differ diff --git a/assets/furniture/bedroom/metal/tv.png b/assets/furniture/bedroom/metal/tv.png new file mode 100644 index 0000000..db327b1 Binary files /dev/null and b/assets/furniture/bedroom/metal/tv.png differ diff --git a/assets/furniture/bedroom/metal/wardrobe.png b/assets/furniture/bedroom/metal/wardrobe.png new file mode 100644 index 0000000..f62a89c Binary files /dev/null and b/assets/furniture/bedroom/metal/wardrobe.png differ diff --git a/assets/furniture/bedroom/metal/window_ac.png b/assets/furniture/bedroom/metal/window_ac.png new file mode 100644 index 0000000..d05c464 Binary files /dev/null and b/assets/furniture/bedroom/metal/window_ac.png differ diff --git a/assets/furniture/bedroom/mini_ac.png b/assets/furniture/bedroom/mini_ac.png new file mode 100644 index 0000000..8cff862 Binary files /dev/null and b/assets/furniture/bedroom/mini_ac.png differ diff --git a/assets/furniture/bedroom/mouse.png b/assets/furniture/bedroom/mouse.png new file mode 100644 index 0000000..f46605b Binary files /dev/null and b/assets/furniture/bedroom/mouse.png differ diff --git a/assets/furniture/bedroom/nightlight.png b/assets/furniture/bedroom/nightlight.png new file mode 100644 index 0000000..2bfa186 Binary files /dev/null and b/assets/furniture/bedroom/nightlight.png differ diff --git a/assets/furniture/bedroom/nightstand.png b/assets/furniture/bedroom/nightstand.png new file mode 100644 index 0000000..508d115 Binary files /dev/null and b/assets/furniture/bedroom/nightstand.png differ diff --git a/assets/furniture/bedroom/pc.png b/assets/furniture/bedroom/pc.png new file mode 100644 index 0000000..3a6736f Binary files /dev/null and b/assets/furniture/bedroom/pc.png differ diff --git a/assets/furniture/bedroom/phone.png b/assets/furniture/bedroom/phone.png new file mode 100644 index 0000000..dd913e5 Binary files /dev/null and b/assets/furniture/bedroom/phone.png differ diff --git a/assets/furniture/bedroom/receiver.png b/assets/furniture/bedroom/receiver.png new file mode 100644 index 0000000..dde1fec Binary files /dev/null and b/assets/furniture/bedroom/receiver.png differ diff --git a/assets/furniture/bedroom/tv.png b/assets/furniture/bedroom/tv.png new file mode 100644 index 0000000..fb79085 Binary files /dev/null and b/assets/furniture/bedroom/tv.png differ diff --git a/assets/furniture/bedroom/tv_stand.png b/assets/furniture/bedroom/tv_stand.png new file mode 100644 index 0000000..e71737d Binary files /dev/null and b/assets/furniture/bedroom/tv_stand.png differ diff --git a/assets/furniture/bedroom/wardrobe.png b/assets/furniture/bedroom/wardrobe.png new file mode 100644 index 0000000..4914c80 Binary files /dev/null and b/assets/furniture/bedroom/wardrobe.png differ diff --git a/assets/furniture/bedroom/window.png b/assets/furniture/bedroom/window.png new file mode 100644 index 0000000..ab76274 Binary files /dev/null and b/assets/furniture/bedroom/window.png differ diff --git a/assets/furniture/bedroom/window_ac.png b/assets/furniture/bedroom/window_ac.png new file mode 100644 index 0000000..86e3d8b Binary files /dev/null and b/assets/furniture/bedroom/window_ac.png differ diff --git a/assets/music/Galactic_Rap.ogg b/assets/music/Galactic_Rap.ogg new file mode 100644 index 0000000..3a0f56d Binary files /dev/null and b/assets/music/Galactic_Rap.ogg differ diff --git a/assets/music/Galactic_Rap_Destroyed.ogg b/assets/music/Galactic_Rap_Destroyed.ogg new file mode 100644 index 0000000..df5329a Binary files /dev/null and b/assets/music/Galactic_Rap_Destroyed.ogg differ diff --git a/assets/music/Galactic_Rap_Speedup.ogg b/assets/music/Galactic_Rap_Speedup.ogg new file mode 100644 index 0000000..34d2da0 Binary files /dev/null and b/assets/music/Galactic_Rap_Speedup.ogg differ diff --git a/assets/music/Mesmerizing_Galaxy_Broken.ogg b/assets/music/Mesmerizing_Galaxy_Broken.ogg new file mode 100644 index 0000000..69c9cee Binary files /dev/null and b/assets/music/Mesmerizing_Galaxy_Broken.ogg differ diff --git a/assets/music/Mesmerizing_Galaxy_Loop.ogg b/assets/music/Mesmerizing_Galaxy_Loop.ogg new file mode 100644 index 0000000..923d690 Binary files /dev/null and b/assets/music/Mesmerizing_Galaxy_Loop.ogg differ diff --git a/assets/sounds/bzz.ogg b/assets/sounds/bzz.ogg new file mode 100644 index 0000000..029f567 Binary files /dev/null and b/assets/sounds/bzz.ogg differ diff --git a/build.rs b/build.rs index b218bb6..11082bd 100644 --- a/build.rs +++ b/build.rs @@ -17,6 +17,9 @@ struct Assets { /// of the constant storing their png. assets: BTreeMap, + /// Sound assets. + sound_assets: BTreeMap, + /// Asset groups contained within this asset group, mapping their name to the assets /// that group contains. groups: BTreeMap> @@ -37,15 +40,19 @@ impl AssetsWriter { } } - fn add_png>( + fn asset_name>(canonical_path: P) -> String { + let mut hasher = DefaultHasher::new(); + canonical_path.as_ref().hash(&mut hasher); + let hash = hasher.finish(); + format!("ASSET_{hash:X}") + } + + fn add_png + Copy>( &mut self, canonical_path: P, png: tiny_skia::Pixmap ) -> String { - let mut hasher = DefaultHasher::new(); - canonical_path.as_ref().hash(&mut hasher); - let hash = hasher.finish(); - let const_name = format!("ASSET_{hash:X}"); + let const_name = Self::asset_name(canonical_path); let out_dir = env::var_os("OUT_DIR").unwrap(); let out_dir: PathBuf = out_dir.into(); @@ -62,6 +69,18 @@ impl AssetsWriter { const_name } + fn add_ogg + Copy>(&mut self, canonical_path: P) -> String { + let const_name = Self::asset_name(canonical_path); + writeln!(self.file, "// {}", canonical_path.as_ref().display()).unwrap(); + writeln!( + self.file, + "const {const_name}: &[u8] = include_bytes!(\"{}\");", + canonical_path.as_ref().display() + ) + .unwrap(); + const_name + } + fn finish(mut self) { fn write_assets_struct( file: &mut File, @@ -85,6 +104,13 @@ impl AssetsWriter { asset_name.to_snake_case() )?; } + for asset_name in root.sound_assets.keys() { + writeln!( + file, + "{indent}\tpub {}: comfy::Sound,", + asset_name.to_snake_case() + )?; + } for group_name in root.groups.keys() { writeln!( file, @@ -101,6 +127,9 @@ impl AssetsWriter { for asset_const_name in root.assets.values() { writeln!(file, "{indent}\t\tc.load_texture_from_bytes({asset_const_name:?}, {asset_const_name});")?; } + for asset_const_name in root.sound_assets.values() { + writeln!(file, "{indent}\t\tcomfy::load_sound_from_bytes({asset_const_name:?}, {asset_const_name}, Default::default());")?; + } for group_name in root.groups.keys() { writeln!(file, "{indent}\t\t{group_name}::Assets::load(c);")?; } @@ -118,6 +147,13 @@ impl AssetsWriter { asset_name.to_snake_case() )?; } + for (asset_name, asset_const_name) in &root.sound_assets { + writeln!( + file, + "{indent}\t{}: comfy::sound_id({asset_const_name:?}),", + asset_name.to_snake_case() + )?; + } for group_name in root.groups.keys() { writeln!( file, @@ -170,6 +206,8 @@ fn process_dir + Copy>( groups.pop(); } else if path.extension().map(|ext| ext == "svg").unwrap_or(false) { process_svg(&path, dir, writer, groups); + } else if path.extension().map(|ext| ext == "ogg").unwrap_or(false) { + process_ogg(&path, dir, writer, groups); } } } @@ -196,7 +234,8 @@ fn process_svg + Copy, Q: AsRef>( resvg::render(&tree, transform, &mut pixmap.as_mut()); let const_name = writer.add_png( - file.as_ref() + &file + .as_ref() .canonicalize() .expect("Failed to canonicalize"), pixmap @@ -218,3 +257,33 @@ fn process_svg + Copy, Q: AsRef>( const_name ); } + +fn process_ogg + Copy, Q: AsRef>( + file: P, + dir: Q, + writer: &mut AssetsWriter, + groups: &[String] +) { + let const_name = writer.add_ogg( + &file + .as_ref() + .canonicalize() + .expect("Failed to canonicalize") + ); + let mut group = &mut writer.root; + for group_name in groups { + if !group.groups.contains_key(group_name) { + group.groups.insert(group_name.to_owned(), Box::default()); + } + group = group.groups.get_mut(group_name).unwrap(); + } + group.sound_assets.insert( + file.as_ref() + .file_stem() + .expect("File doesn't have a stem") + .to_str() + .expect("Non-UTF8 file names aren't allowed") + .into(), + const_name + ); +} diff --git a/src/activities/house/mod.rs b/src/activities/house/mod.rs index 54cb9b2..a8f3184 100644 --- a/src/activities/house/mod.rs +++ b/src/activities/house/mod.rs @@ -21,63 +21,68 @@ pub struct HouseState { human_layer: bool //Human, magnetic, electric } -pub fn setup(state: &mut crate::State, ctx: &mut EngineContext<'_>) { - let house = { +impl HouseState { + pub fn generate_new_house(ctx: &mut EngineContext<'_>) -> Self { let room_count = random_i32(2, MAX_ROOMS) as usize; let mut rooms = Vec::new(); - for _ in 0..room_count { + for _ in 0 .. room_count { rooms.push(Room::new(ctx)); } let player = Player::new(rooms.first().unwrap()); - HouseState { current_room_id: 0, room_count, + HouseState { + current_room_id: 0, + room_count, rooms, player, human_layer: false } - }; - - state.house = Some(house); + } } pub fn draw(state: &crate::State, _ctx: &comfy::EngineContext<'_>) { - if let Some(house) = &state.house { - //Draw House - house - .rooms.get(house.current_room_id).unwrap().draw(house.human_layer, house.player.can_see_metal(0.1)); + let Some(house) = state.house() else { + error!("How can I render a house when I'm not in one?!?"); + return; + }; - //Draw Grid - //state.house.grid.draw(); + //Draw House + house + .rooms + .get(house.current_room_id) + .unwrap() + .draw(house.human_layer, house.player.can_see_metal(0.1)); - //Draw Player - house.player.draw(); - } + //Draw Grid + //state.house.grid.draw(); + + //Draw Player + house.player.draw(); } pub fn update(state: &mut crate::State, ctx: &mut comfy::EngineContext<'_>) { - if let Some(house) = &mut state.house { - let current_room = house.rooms.get(house.current_room_id).unwrap(); - house.player.update(¤t_room.grid); + let house = state.house_mut(ctx); + let current_room = house.rooms.get(house.current_room_id).unwrap(); + house.player.update(¤t_room.grid); - if house.player.is_moving_to_right_room(current_room) { - if house.current_room_id < (house.room_count - 1) { - house.current_room_id +=1; + if house.player.is_moving_to_right_room(current_room) { + if house.current_room_id < (house.room_count - 1) { + house.current_room_id += 1; - let current_room = house.rooms.get(house.current_room_id).unwrap(); - house.player.reset_on_room(current_room, true); - } else { - house.player.reset_on_room(current_room, false); - } - } else if house.player.is_moving_to_left_room(current_room) { - if house.current_room_id > 0 { - house.current_room_id -=1; + let current_room = house.rooms.get(house.current_room_id).unwrap(); + house.player.reset_on_room(current_room, true); + } else { + house.player.reset_on_room(current_room, false); + } + } else if house.player.is_moving_to_left_room(current_room) { + if house.current_room_id > 0 { + house.current_room_id -= 1; - let current_room = house.rooms.get(house.current_room_id).unwrap(); - house.player.reset_on_room(current_room, false); - } else { - house.player.reset_on_room(current_room, true); - } + let current_room = house.rooms.get(house.current_room_id).unwrap(); + house.player.reset_on_room(current_room, false); + } else { + house.player.reset_on_room(current_room, true); } } } diff --git a/src/activities/house/player.rs b/src/activities/house/player.rs index f37f0d8..d78cfbb 100644 --- a/src/activities/house/player.rs +++ b/src/activities/house/player.rs @@ -70,13 +70,24 @@ impl Player { } else { let mut current_index = 0; for (i, node_pos) in room.grid.nodes.iter().enumerate().rev() { - if in_node_range(&vec2((room.size.0 as f32 / 2.0 + 0.5) * SCALE, self.position.y), node_pos, 1.0) { + if in_node_range( + &vec2((room.size.0 as f32 / 2.0 + 0.5) * SCALE, self.position.y), + node_pos, + 1.0 + ) { current_index = i; } } - let connction_index = room.grid.connections.iter().enumerate().find(|(_i, (_node_1, node_2))| *node_2 == current_index).map(|(i, _)| i).unwrap(); - + let connction_index = room + .grid + .connections + .iter() + .enumerate() + .find(|(_i, (_node_1, node_2))| *node_2 == current_index) + .map(|(i, _)| i) + .unwrap(); + self.connection = connction_index; self.next_connections = vec![connction_index - 1]; } diff --git a/src/activities/house/room.rs b/src/activities/house/room.rs index 7dbadd2..d43b720 100644 --- a/src/activities/house/room.rs +++ b/src/activities/house/room.rs @@ -27,7 +27,7 @@ struct Tile { #[derive(Debug)] pub struct Room { - room_type: RoomType, + _room_type: RoomType, pub size: (u8, u8), //(width, height) pub grid: Grid, furnitures: Vec @@ -54,7 +54,7 @@ impl Room { let furnitures = Self::random_room_furniture(&room_type, size, ctx); Room { - room_type, + _room_type: room_type, size, grid: Self::create_grid(size.0, size.1), furnitures @@ -80,23 +80,29 @@ impl Room { let mut furnitures = Vec::new(); let mut empty_spots: IndexSet = (0 .. width).collect(); - let mut assets_used: HashSet<&'static str> = HashSet::new(); - fn random_empty_spot(empty_spots: &mut IndexSet) -> Option { + fn random_empty_spot(empty_spots: &mut IndexSet) -> Option { if empty_spots.is_empty() { return None; } let random_idx = usize::gen_range(0, empty_spots.len()); empty_spots.swap_remove_index(random_idx) } + fn random_appliance(empty_spots: &mut Vec) -> Option { + if empty_spots.is_empty() { + return None; + } + let random_idx = usize::gen_range(0, empty_spots.len()); + Some(empty_spots.swap_remove(random_idx)) + } const SIDEBOARD_HEIGHT: f32 = 0.1; const STOVE_HEIGHT: f32 = 0.025; const SINK_HEIGHT: f32 = 0.5; - #[allow(clippy::single_match, unreachable_patterns)] // we'll add more stuff later + #[allow(clippy::single_match)] // we'll add more stuff later match room_type { - _ => { + RoomType::Kitchen => { // in a kitchen, we always add a fridge let fridge_pos = u8::gen_range(0, 2) * (width - 1); empty_spots.swap_remove(&fridge_pos); @@ -159,12 +165,21 @@ impl Room { z: 1 }); - // let's add half of the remaining positions as drawers + // the current list of empty spots is the same list we can use to place + // on-the-counter appliances later + let mut empty_spots_clone = empty_spots.clone(); + + // build a list of the remaining kitchen appliances. we only want them + // included once, most kitchens don't contain two washing machines etc + let mut remaining_appliances: IndexSet<&'static str> = + ["dishwasher", "dryer", "minifridge", "washing_machine"] + .into_iter() + .collect(); + + // let's add at most half of the remaining positions as big appliances for _ in 0 .. empty_spots.len() / 2 { - let asset = match u8::gen_range(0, 2) { - 0 => "drawer", - 1 => "drawer_cupboard", - _ => unreachable!() + let Some(asset) = random_empty_spot(&mut remaining_appliances) else { + break; }; let Some(spot) = random_empty_spot(&mut empty_spots) else { error!("WTF I shouldn't've used more than half of the available spots"); @@ -183,6 +198,60 @@ impl Room { z: 1 }); } + + // and fill the remainder with drawers + while !empty_spots.is_empty() { + let asset = match u8::gen_range(0, 2) { + 0 => "drawer", + 1 => "drawer_cupboard", + _ => unreachable!() + }; + let Some(spot) = random_empty_spot(&mut empty_spots) else { + error!("WTF I should still have spots available"); + return furnitures; + }; + furnitures.push(Tile { + pos: vec2(spot as f32, 0.0), + size: vec2(1.0, 1.0), + f: Furniture::new("kitchen", asset, ctx), + z: 0 + }); + furnitures.push(Tile { + pos: vec2(spot as f32, 1.0), + size: vec2(1.0, SIDEBOARD_HEIGHT), + f: Furniture::new("kitchen", "sideboard_1", ctx), + z: 1 + }); + } + + // build a list of on-the-counter kitchen appliances. we only want them + // included once, most kitchens don't contain two toasters etc + let mut remaining_appliances: Vec<(&'static str, f32, f32)> = [ + ("blender", 0.3, 0.45), + ("kettle", 0.3, 0.4), + ("toaster", 0.5, 0.25) + ] + .into_iter() + .collect(); + + // and then we fill like half the counter with appliances + for _ in 0 .. empty_spots_clone.len() / 2 { + let Some((asset, asset_w, asset_h)) = + random_appliance(&mut remaining_appliances) + else { + break; + }; + let Some(spot) = random_empty_spot(&mut empty_spots_clone) else { + error!("WTF I shouldn't've used more than half of the available spots"); + return furnitures; + }; + furnitures.push(Tile { + pos: vec2(spot as f32 + 0.5, 1.0 + SIDEBOARD_HEIGHT), + size: vec2(asset_w, asset_h), + f: Furniture::new("kitchen", asset, ctx), + z: 0 + }); + } }, _ => {} @@ -241,7 +310,6 @@ impl Room { Grid::new(nodes, connections) } - //Human, magnetic, electric pub fn draw(&self, human_layer: bool, magnet_layer: bool) { let (width, height) = self.size; diff --git a/src/activities/mod.rs b/src/activities/mod.rs index dfa2b9e..4f3efbd 100644 --- a/src/activities/mod.rs +++ b/src/activities/mod.rs @@ -1,10 +1,11 @@ +use comfy::IVec2; + pub mod house; pub mod overworld; #[derive(Debug, Default)] pub enum Activity { + House(IVec2), #[default] - House, - #[allow(dead_code)] Overworld } diff --git a/src/activities/overworld/mod.rs b/src/activities/overworld/mod.rs index f8bee45..d938547 100644 --- a/src/activities/overworld/mod.rs +++ b/src/activities/overworld/mod.rs @@ -1,9 +1,10 @@ +use crate::{activities::Activity, game::ZLayer, State}; use comfy::{ - draw_rect_outline, draw_sprite, main_camera_mut, EngineContext, IVec2, Vec2, RED, - WHITE + draw_circle, draw_rect_outline, draw_sprite, error, info, is_key_down, + main_camera_mut, EngineContext, IVec2, KeyCode, Vec2, RED, WHITE }; - -use crate::game::ZLayer; +use std::time::Instant; +use worldgen::MovementCost; pub mod worldgen; @@ -21,11 +22,172 @@ pub fn draw(state: &crate::State, _engine: &comfy::EngineContext<'_>) { draw_rect_outline(coords.as_vec2(), Vec2::ONE, 0.1, RED, 10); } } + draw_circle(state.ghost.overworld_pos, 0.5, RED, ZLayer::Ghost.into()); } -pub fn update(state: &mut crate::State, _engine: &mut EngineContext<'_>) { - let mut camera = main_camera_mut(); - camera.center = Vec2::ZERO; - camera.zoom = 30.0; - state.overworld.get_or_generate_tile(IVec2::ZERO); +fn update_move_player(state: &mut State, ctx: &mut EngineContext<'_>) { + let now = Instant::now(); + + // Are there any pending position updates? If so, we ignore all user input and execute + // the pending updates. + if state.ghost.overworld_movement_pending != Vec2::ZERO { + info!( + "Pending Movement: {:?}", + state.ghost.overworld_movement_pending + ); + state.ghost.update_overworld_pos(now); + return; + } + + // Otherwise, we check for user inputs, and update the pending movement accordingly. + let tile_pos = IVec2 { + x: state.ghost.overworld_pos.x.round() as _, + y: state.ghost.overworld_pos.y.round() as _ + }; + let Some(tile) = state.overworld.get_tile(tile_pos).copied() else { + error!("How can we be standing inside a non-generated tile?"); + return; + }; + + let mut requested_pos = None; + let mut requested_pos_diff = None; + let mut requested_cost_curr = None; + let mut requested_cost_new = None; + + if is_key_down(KeyCode::Up) { + let diff = IVec2 { x: 0, y: 1 }; + let new_pos = tile_pos + diff; + let new_tile = state.overworld.get_or_generate_tile(new_pos); + if new_tile.can_stand_inside() { + requested_pos = Some(new_pos); + requested_pos_diff = Some(diff); + requested_cost_curr = Some(tile.movement_cost_up()); + requested_cost_new = Some(new_tile.movement_cost_down()); + } else { + info!("Rejecting movement - cannot stand in the requested tile."); + } + } + + if is_key_down(KeyCode::Down) { + let diff = IVec2 { x: 0, y: -1 }; + let new_pos = tile_pos + diff; + let new_tile = state.overworld.get_or_generate_tile(new_pos); + if new_tile.can_stand_inside() { + requested_pos = Some(new_pos); + requested_pos_diff = Some(diff); + requested_cost_curr = Some(tile.movement_cost_down()); + requested_cost_new = Some(new_tile.movement_cost_up()); + } else { + info!("Rejecting movement - cannot stand in the requested tile."); + } + } + + if is_key_down(KeyCode::Left) { + let diff = IVec2 { x: -1, y: 0 }; + let new_pos = tile_pos + diff; + let new_tile = state.overworld.get_or_generate_tile(new_pos); + if new_tile.can_stand_inside() { + requested_pos = Some(new_pos); + requested_pos_diff = Some(diff); + requested_cost_curr = Some(tile.movement_cost_left()); + requested_cost_new = Some(new_tile.movement_cost_right()); + } else { + info!("Rejecting movement - cannot stand in the requested tile."); + } + } + + if is_key_down(KeyCode::Right) { + let diff = IVec2 { x: 1, y: 0 }; + let new_pos = tile_pos + diff; + let new_tile = state.overworld.get_or_generate_tile(new_pos); + if new_tile.can_stand_inside() { + requested_pos = Some(new_pos); + requested_pos_diff = Some(diff); + requested_cost_curr = Some(tile.movement_cost_right()); + requested_cost_new = Some(new_tile.movement_cost_left()); + } else { + info!("Rejecting movement - cannot stand in the requested tile."); + } + } + + // only continue if some movement was requested + let Some(_requested_pos) = requested_pos else { + return; + }; + let Some(requested_pos_diff) = requested_pos_diff else { + return; + }; + let Some(requested_cost_curr) = requested_cost_curr else { + return; + }; + let Some(requested_cost_new) = requested_cost_new else { + return; + }; + + state.ghost.overworld_movement_speed = match (requested_cost_curr, requested_cost_new) + { + // movement in this direction not possible + (MovementCost::Infinite, _) | (_, MovementCost::Infinite) => { + info!("Rejecting movement - movement cost is infinite"); + return; + }, + + // we are walking on a path + (MovementCost::Path, MovementCost::Path) => 10.0, + + // we are walking across an obstacle + (MovementCost::Obstacle, _) | (_, MovementCost::Obstacle) => 1.0, + + // we are walking on grass + _ => 5.0 + }; + state.ghost.overworld_movement_pending = Vec2 { + x: requested_pos_diff.x as _, + y: requested_pos_diff.y as _ + }; + state.ghost.overworld_pos_last_update = now; +} + +pub fn update(state: &mut State, ctx: &mut EngineContext<'_>) { + let mut camera = main_camera_mut(); + camera.center = state.ghost.overworld_pos; + camera.zoom = 30.0; + + // move player + update_move_player(state, ctx); + + //move into house if player stepp at door + { + let tile_pos = IVec2 { + x: state.ghost.overworld_pos.x.round() as _, + y: state.ghost.overworld_pos.y.round() as _ + }; + let current_tile = state.overworld.get_or_generate_tile(tile_pos); + if current_tile.can_enter_house() { + info!("enter house at {tile_pos}"); + state.activity = Activity::House(tile_pos); + state.house_mut(ctx); // gen new house + } + } + + // generate more chunks if needed + { + let half_viewport = (camera.world_viewport() * 0.5 + 3.0).as_ivec2(); + let rounded_ghost_pos = IVec2 { + x: state.ghost.overworld_pos.x.round() as _, + y: state.ghost.overworld_pos.y.round() as _ + }; + state.overworld.get_or_generate_tile( + rounded_ghost_pos + IVec2::new(half_viewport.x, half_viewport.y) + ); + state.overworld.get_or_generate_tile( + rounded_ghost_pos + IVec2::new(half_viewport.x, -half_viewport.y) + ); + state.overworld.get_or_generate_tile( + rounded_ghost_pos + IVec2::new(-half_viewport.x, half_viewport.y) + ); + state.overworld.get_or_generate_tile( + rounded_ghost_pos + IVec2::new(-half_viewport.x, -half_viewport.y) + ); + } } diff --git a/src/activities/overworld/worldgen.rs b/src/activities/overworld/worldgen.rs index 5af1dcd..83e9067 100644 --- a/src/activities/overworld/worldgen.rs +++ b/src/activities/overworld/worldgen.rs @@ -2,8 +2,7 @@ #![allow(dead_code)] use crate::assets::ASSETS; -use comfy::{IVec2, TextureHandle, UVec2}; -use log::info; +use comfy::{info, IVec2, TextureHandle, UVec2}; use std::collections::HashMap; pub enum MovementCost { @@ -117,28 +116,61 @@ impl Tile { } pub fn can_stand_inside(&self) -> bool { - unimplemented!() + #[allow(clippy::match_like_matches_macro)] // I believe this is better readable + match self { + Self::House { door: false, .. } => false, + _ => true + } } pub fn movement_cost_left(&self) -> MovementCost { - unimplemented!() + match self { + Self::Grass => MovementCost::Default, + Self::Path { left: true, .. } => MovementCost::Path, + Self::Path { left: false, .. } => MovementCost::Default, + Self::Fence { left: false, .. } => MovementCost::Obstacle, + _ => MovementCost::Infinite + } } pub fn movement_cost_right(&self) -> MovementCost { - unimplemented!() + match self { + Self::Grass => MovementCost::Default, + Self::Path { right: true, .. } => MovementCost::Path, + Self::Path { right: false, .. } => MovementCost::Default, + Self::Fence { right: false, .. } => MovementCost::Obstacle, + _ => MovementCost::Infinite + } } pub fn movement_cost_up(&self) -> MovementCost { - unimplemented!() + match self { + Self::Grass => MovementCost::Default, + Self::Path { top: true, .. } => MovementCost::Path, + Self::Path { top: false, .. } => MovementCost::Default, + Self::Fence { top: false, .. } => MovementCost::Obstacle, + _ => MovementCost::Infinite + } } pub fn movement_cost_down(&self) -> MovementCost { - unimplemented!() + match self { + Self::Grass => MovementCost::Default, + Self::Path { bottom: true, .. } => MovementCost::Path, + Self::Path { bottom: false, .. } => MovementCost::Default, + Self::Fence { bottom: false, .. } => MovementCost::Obstacle, + Self::House { door: true, .. } => MovementCost::Path, + _ => MovementCost::Infinite + } } pub fn can_enter_house(&self) -> bool { - unimplemented!() + #[allow(clippy::match_like_matches_macro)] // I believe this is better readable + match self { + Self::House { door: true, .. } => true, + _ => false + } } } /// The size of a chunk (both width and height). This value squared gives the amount of /// tiles in the chunk. -const CHUNK_SIZE: u32 = 100; +const CHUNK_SIZE: u32 = 50; /// Chunks #[derive(Debug)] @@ -286,7 +318,10 @@ impl Chunk { fence_vert, grass, house(ASSETS.overworld.house_bottom_left), - house(ASSETS.overworld.house_bottom_door), + Tile::House { + door: true, + texture: ASSETS.overworld.house_bottom_door + }, house(ASSETS.overworld.house_bottom_window), house(ASSETS.overworld.house_bottom_window), house(ASSETS.overworld.house_bottom_right), @@ -403,7 +438,15 @@ fn world_to_chunk_and_local_coords(world_coords: IVec2) -> (IVec2, UVec2) { } impl Overworld { - fn get_tile(&self, world_coords: IVec2) -> Option<&Tile> { + /// Return a [`Tile`] at the given world coordinates, or `None` if that tile has not + /// been generated yet. Uses engine/world cordinates. + pub fn get_tile(&self, world_coords: IVec2) -> Option<&Tile> { + let mut coords = world_coords; + coords.y *= -1; + self.get_tile_private(coords) + } + + fn get_tile_private(&self, world_coords: IVec2) -> Option<&Tile> { let (chunk_coords, local_chunk_coords) = world_to_chunk_and_local_coords(world_coords); @@ -411,15 +454,15 @@ impl Overworld { chunk.get_tile(local_chunk_coords) } - /// Return a [`Tile`] at the given world coordinates, or `None` if that tile has not - /// been generated yet. use engine/world cordinates. + /// Return a [`Tile`] at the given world coordinates. Generates tiles if necessary. + /// Uses engine/world cordinates. pub fn get_or_generate_tile(&mut self, world_coords: IVec2) -> &Tile { let mut coords = world_coords; coords.y *= -1; - self.get_or_generate_tiles_private(coords) + self.get_or_generate_tile_private(coords) } - fn get_or_generate_tiles_private(&mut self, world_coords: IVec2) -> &Tile { + fn get_or_generate_tile_private(&mut self, world_coords: IVec2) -> &Tile { let (chunk_coords, local_chunk_coords) = world_to_chunk_and_local_coords(world_coords); @@ -430,21 +473,21 @@ impl Overworld { chunk.get_tile(local_chunk_coords).unwrap() } - /// Iterate over all generated tiles and its engine/world cordinates. using a [`Tile`] at the given world coordinates, or `None` if that tile has not - /// been generated yet. + /// Iterate over all generated tiles in all generated chunks and their engine/world + /// cordinates. pub fn iter_tiles(&self) -> impl Iterator { - self.iter_tilese_private().map(|(coords, tile)| { + self.iter_tiles_private().map(|(coords, tile)| { let mut w_coords = coords; w_coords.y *= -1; (w_coords, tile) }) } - /// iterate over all tiles and its global coords - fn iter_tilese_private(&self) -> impl Iterator { + /// Iterate over all generated tiles in all generated chunks. + fn iter_tiles_private(&self) -> impl Iterator { self.chunks.iter().flat_map(|(chunk_coords, chunk)| { chunk.iter_tiles().map(|(local_coords, tile)| { - // never fail because chunksize fits alswas into i32 + // never fail because chunksize fits always into i32 let local_coords: IVec2 = local_coords.try_into().unwrap(); (local_coords + (*chunk_coords * CHUNK_SIZE as i32), tile) }) diff --git a/src/game.rs b/src/game.rs index 4f5c162..9cdbbe1 100644 --- a/src/game.rs +++ b/src/game.rs @@ -3,22 +3,64 @@ use crate::{ assets::Assets, State }; -use comfy::EngineContext; -use std::ops::Sub; +use comfy::{EngineContext, Vec2}; +use std::{ops::Sub, time::Instant}; #[derive(Debug)] pub struct Ghost { - /// current electric charge of the Ghost + /// Current electric charge of the Ghost. pub charge: f32, - /// max electric charge of the Ghost - pub max_charge: f32 + /// Max electric charge of the Ghost. + pub max_charge: f32, + + /// The position of the ghost in the overworld. Expressed in tile coordinates, but + /// as a float as a ghost takes more than one tick to move. + pub overworld_pos: Vec2, + /// Pending movement of the ghost in the overworld. + pub overworld_movement_pending: Vec2, + /// The current movement speed of the ghost in tiles/sec. + pub overworld_movement_speed: f32, + /// The timestamp of the last overworld position update. + pub overworld_pos_last_update: Instant +} + +impl Ghost { + pub fn update_overworld_pos(&mut self, now: Instant) { + // This calculation is extremely simplistic. It will not work properly if both + // x and y of movement_pending are non-zero. But we only move left,right,up,down + // so that should never happen! + let secs = now + .duration_since(self.overworld_pos_last_update) + .as_secs_f32(); + let mut movement = self.overworld_movement_pending.signum() + * self.overworld_movement_speed + * secs; + + // limit the movement to the remaining movement + if self.overworld_movement_pending.x.abs() < movement.x.abs() { + movement.x = self.overworld_movement_pending.x; + } + if self.overworld_movement_pending.y.abs() < movement.y.abs() { + movement.y = self.overworld_movement_pending.y; + } + + // execute the movement + self.overworld_pos += movement; + self.overworld_movement_pending -= movement; + self.overworld_pos_last_update = now; + } } impl Default for Ghost { fn default() -> Self { Self { charge: 1000.0, - max_charge: 1000.0 + max_charge: 1000.0, + + overworld_pos: Vec2::ZERO, + overworld_movement_pending: Vec2::ZERO, + overworld_movement_speed: 0.0, + overworld_pos_last_update: Instant::now() } } } @@ -50,19 +92,20 @@ impl Sub for ZLayer { pub fn setup(state: &mut State, ctx: &mut EngineContext<'_>) { Assets::load(ctx); - house::setup(state, ctx); + //house::setup(state, ctx); } pub fn update(state: &mut State, engine: &mut EngineContext<'_>) { + state.score += engine.delta * 10.0; match state.activity { - Activity::House => house::update(state, engine), + Activity::House(_) => house::update(state, engine), Activity::Overworld => overworld::update(state, engine) } } pub fn draw(state: &State, engine: &EngineContext<'_>) { match state.activity { - Activity::House => house::draw(state, engine), + Activity::House(_) => house::draw(state, engine), Activity::Overworld => overworld::draw(state, engine) } crate::ui::draw(state, engine); diff --git a/src/main.rs b/src/main.rs index 0ecf53c..608203d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,8 +15,8 @@ use self::{ game::Ghost }; use comfy::{ - init_game_config, pollster, run_comfy_main_async, EngineContext, EngineState, - GameConfig, GameLoop + etagere::euclid::default, init_game_config, pollster, run_comfy_main_async, + DevConfig, EngineContext, EngineState, GameConfig, GameLoop, HashMap, IVec2 }; const GAME_NAME: &str = "Powercreep"; @@ -27,7 +27,27 @@ struct State { activity: Activity, ghost: Ghost, overworld: Overworld, - house: Option + houses: HashMap, + score: f32 +} + +impl State { + fn get_house_pos(&self) -> Option { + match self.activity { + Activity::House(pos) => Some(pos), + _ => None + } + } + + fn house(&self) -> Option<&HouseState> { + self.houses.get(&self.get_house_pos()?) + } + + fn house_mut(&mut self, ctx: &mut EngineContext<'_>) -> &mut HouseState { + self.houses + .entry(self.get_house_pos().unwrap()) + .or_insert_with(|| HouseState::generate_new_house(ctx)) + } } impl GameLoop for State { @@ -37,17 +57,29 @@ impl GameLoop for State { fn update(&mut self, ctx: &mut EngineContext<'_>) { if !self.setup_called { + game::setup(self, ctx); game::setup(self, ctx); self.setup_called = true; } game::update(self, ctx); game::draw(self, ctx); + game::update(self, ctx); + game::draw(self, ctx); } } fn config(config: GameConfig) -> GameConfig { - config + let dev = DevConfig { + #[cfg(debug_assertions)] + show_fps: true, + ..Default::default() + }; + GameConfig { + tonemapping_enabled: true, + dev, + ..Default::default() + } } async fn run() { diff --git a/src/ui.rs b/src/ui.rs index 7de61ee..9d434b2 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,10 +1,11 @@ use crate::State; use comfy::{ - draw_rect, draw_rect_outline, screen_height, screen_to_world, screen_width, - EngineContext, Vec2, BLUE, RED + draw_rect, draw_rect_outline, egui, screen_height, screen_to_world, screen_width, + EngineContext, Vec2, BLUE, RED, WHITE }; +use egui::widget_text::RichText; -pub fn draw(state: &State, _engine: &EngineContext<'_>) { +pub fn draw_batterie(state: &State, _engine: &EngineContext<'_>) { // seperate fill state into smaller section for better readability let section_count = 5; let mut start_positon = screen_to_world(Vec2::new(screen_width(), screen_height())); @@ -29,3 +30,22 @@ pub fn draw(state: &State, _engine: &EngineContext<'_>) { draw_rect_outline(position, section_size, 0.1, RED, 100); } } + +pub fn draw_highscore(state: &State, _engine: &EngineContext<'_>) { + egui::Area::new("score") + .anchor(egui::Align2::RIGHT_TOP, egui::vec2(0.0, 0.0)) + .show(egui(), |ui| { + ui.label( + RichText::new(format!("{:.0}", state.score)) + .color(WHITE) + .monospace() + .size(16.0) + .strong() + ); + }); +} + +pub fn draw(state: &State, engine: &EngineContext<'_>) { + draw_batterie(state, engine); + draw_highscore(state, engine); +}