diff --git a/game/assets/levels/level_0/background.png b/game/assets/levels/level_0/background.png new file mode 100644 index 0000000..8fc5cff Binary files /dev/null and b/game/assets/levels/level_0/background.png differ diff --git a/game/assets/levels/level_0/colliders.json b/game/assets/levels/level_0/colliders.json new file mode 100644 index 0000000..21920a4 --- /dev/null +++ b/game/assets/levels/level_0/colliders.json @@ -0,0 +1,32 @@ +[ + { + "x": 322, + "y": 926, + "width": 610, + "height": 73 + }, + { + "x": 852, + "y": 882, + "width": 81, + "height": 178 + }, + { + "x": 852, + "y": 882, + "width": 258, + "height": 33 + }, + { + "x": 1599, + "y": 699, + "width": 918, + "height": 63 + }, + { + "x": 2733, + "y": 789, + "width": 108, + "height": 211 + } +] diff --git a/game/assets/levels/level_0/platforms.png b/game/assets/levels/level_0/platforms.png new file mode 100644 index 0000000..94fecb2 Binary files /dev/null and b/game/assets/levels/level_0/platforms.png differ diff --git a/game/assets/levels/levels.json b/game/assets/levels/levels.json new file mode 100644 index 0000000..614f9a8 --- /dev/null +++ b/game/assets/levels/levels.json @@ -0,0 +1,3 @@ +[ + "level_0" +] diff --git a/game/src/scenes/ingame_scene/level/loader.rs b/game/src/scenes/ingame_scene/level/loader.rs new file mode 100644 index 0000000..3ca4add --- /dev/null +++ b/game/src/scenes/ingame_scene/level/loader.rs @@ -0,0 +1,53 @@ +use raylib::{RaylibHandle, RaylibThread}; + +use crate::{ + utilities::datastore::{load_texture_from_internal_data, ResourceLoadError}, + StaticGameData, +}; + +use super::Level; + +pub fn load_all_levels( + raylib_handle: &mut RaylibHandle, + thread: &RaylibThread, +) -> Result, ResourceLoadError> { + // Get a listing of all levels we have + let level_names: Vec = serde_json::from_str( + &String::from_utf8( + StaticGameData::get("levels/levels.json") + .expect("Could not load levels.json") + .data + .into(), + ) + .unwrap(), + )?; + + // Build a level list + let mut levels = Vec::new(); + + for level_name in &level_names { + levels.push(Level { + name: level_name.to_string(), + background_tex: load_texture_from_internal_data( + raylib_handle, + thread, + &format!("levels/{}/background.png", level_name), + )?, + platform_tex: load_texture_from_internal_data( + raylib_handle, + thread, + &format!("levels/{}/platforms.png", level_name), + )?, + colliders: serde_json::from_str( + &String::from_utf8( + StaticGameData::get(&format!("levels/{}/colliders.json", level_name)) + .unwrap() + .data + .into(), + ) + .unwrap(), + )?, + }); + } + Ok(levels) +} diff --git a/game/src/scenes/ingame_scene/level/mod.rs b/game/src/scenes/ingame_scene/level/mod.rs new file mode 100644 index 0000000..2119b36 --- /dev/null +++ b/game/src/scenes/ingame_scene/level/mod.rs @@ -0,0 +1,11 @@ +use raylib::{math::Rectangle, texture::Texture2D}; + +pub mod loader; + +#[derive(Debug)] +pub struct Level { + pub name: String, + pub background_tex: Texture2D, + pub platform_tex: Texture2D, + pub colliders: Vec +} diff --git a/game/src/scenes/ingame_scene/mod.rs b/game/src/scenes/ingame_scene/mod.rs index 34d65be..70024d9 100644 --- a/game/src/scenes/ingame_scene/mod.rs +++ b/game/src/scenes/ingame_scene/mod.rs @@ -1,12 +1,22 @@ use dirty_fsm::{Action, ActionFlag}; use raylib::prelude::*; -use crate::{character::{CharacterState, MainCharacter}, context::GameContext, utilities::{render_layer::{FrameUpdate, ScreenSpaceRender, WorldSpaceRender}, world_paint_texture::WorldPaintTexture}}; +use crate::{ + character::{CharacterState, MainCharacter}, + context::GameContext, + utilities::{ + render_layer::{FrameUpdate, ScreenSpaceRender, WorldSpaceRender}, + world_paint_texture::WorldPaintTexture, + }, +}; + +use self::level::Level; use super::{Scenes, ScreenError}; use tracing::{debug, trace}; mod hud; +pub mod level; mod update; mod world; @@ -14,12 +24,18 @@ mod world; pub struct InGameScreen { camera: Camera2D, player: MainCharacter, - world_background: WorldPaintTexture + world_background: WorldPaintTexture, + levels: Vec, + current_level_idx: usize, } impl InGameScreen { /// Construct a new `InGameScreen` - pub fn new(player_sprite_sheet: Texture2D, background_texture: Texture2D) -> Self { + pub fn new( + player_sprite_sheet: Texture2D, + background_texture: Texture2D, + levels: Vec, + ) -> Self { Self { camera: Camera2D { offset: Vector2::zero(), @@ -28,7 +44,9 @@ impl InGameScreen { zoom: 1.0, }, player: MainCharacter::new(Vector2::new(0.0, -80.0), player_sprite_sheet), - world_background: WorldPaintTexture::new(background_texture) + world_background: WorldPaintTexture::new(background_texture), + levels, + current_level_idx: 0, } } } diff --git a/game/src/scenes/ingame_scene/world.rs b/game/src/scenes/ingame_scene/world.rs index cf5afdf..ee10f7e 100644 --- a/game/src/scenes/ingame_scene/world.rs +++ b/game/src/scenes/ingame_scene/world.rs @@ -16,8 +16,14 @@ impl WorldSpaceRender for InGameScreen { ) { puffin::profile_function!(); + // Get the current level + let cur_level = self.levels.get(self.current_level_idx).unwrap(); + // Render the world background - self.world_background.render(raylib, Vector2::new(0.0, -1080.0), &self.camera); + // self.world_background.render(raylib, Vector2::new(0.0, -1080.0), &self.camera); + + // Render the platform layer + raylib.draw_texture_v(&cur_level.platform_tex, Vector2::new(-10.0, -cur_level.platform_tex.height as f32), Color::WHITE); // Render the floor as a line let screen_world_zero = raylib.get_screen_to_world2D(Vector2::zero(), self.camera); diff --git a/game/src/scenes/mod.rs b/game/src/scenes/mod.rs index 7951f15..018934b 100644 --- a/game/src/scenes/mod.rs +++ b/game/src/scenes/mod.rs @@ -1,5 +1,7 @@ use self::{ - fsm_error_screen::FsmErrorScreen, ingame_scene::InGameScreen, loading_screen::LoadingScreen, + fsm_error_screen::FsmErrorScreen, + ingame_scene::{level::loader::load_all_levels, InGameScreen}, + loading_screen::LoadingScreen, main_menu_screen::MainMenuScreen, }; use crate::{ @@ -48,6 +50,7 @@ pub fn build_screen_state_machine( load_texture_from_internal_data(raylib_handle, thread, "character/player_run.png").unwrap(); let world_background = load_texture_from_internal_data(raylib_handle, thread, "default-texture.png").unwrap(); + let levels = load_all_levels(raylib_handle, thread).unwrap(); // Set up the state machine let mut machine = StateMachine::new(); @@ -57,6 +60,9 @@ pub fn build_screen_state_machine( LoadingScreen::new(raylib_handle, thread)?, )?; machine.add_action(Scenes::MainMenuScreen, MainMenuScreen::new())?; - machine.add_action(Scenes::InGameScene, InGameScreen::new(player_sprite_sheet, world_background))?; + machine.add_action( + Scenes::InGameScene, + InGameScreen::new(player_sprite_sheet, world_background, levels), + )?; Ok(machine) } diff --git a/game/src/utilities/datastore.rs b/game/src/utilities/datastore.rs index 506f46d..d181204 100644 --- a/game/src/utilities/datastore.rs +++ b/game/src/utilities/datastore.rs @@ -14,6 +14,8 @@ pub struct StaticGameData; #[derive(Debug, Error)] pub enum ResourceLoadError { + #[error(transparent)] + JsonDeser(#[from] serde_json::Error), #[error(transparent)] Io(#[from] std::io::Error), #[error("Could not load embedded asset: {0}")]