diff --git a/game/assets/levels/level_0/background.png b/game/assets/levels/level_0/background.png index 8fc5cff..1e6e438 100644 Binary files a/game/assets/levels/level_0/background.png and b/game/assets/levels/level_0/background.png differ diff --git a/game/src/character/collisions.rs b/game/src/character/collisions.rs index c802015..13ce222 100644 --- a/game/src/character/collisions.rs +++ b/game/src/character/collisions.rs @@ -8,6 +8,7 @@ use super::{CharacterState, MainCharacter}; pub const GRAVITY_PPS: f32 = 2.0; +#[must_use] pub fn modify_player_based_on_forces( player: &mut MainCharacter, colliders: &Vec, @@ -56,16 +57,18 @@ pub fn modify_player_based_on_forces( if player.current_state == CharacterState::Jumping || player.current_state == CharacterState::Dashing { - player.update_player( + return player.update_player( Some(CharacterState::Running), colliders, level_height_offset, ); - return Ok(()); } } // Check sideways collisions + if player.velocity.y == 0.0 && check_player_colliding_with_colliders(){ + return Err(()); + } // Finally apply the velocity to the player player.position += player.velocity; diff --git a/game/src/character/mod.rs b/game/src/character/mod.rs index 9c1b0d2..872d7fb 100644 --- a/game/src/character/mod.rs +++ b/game/src/character/mod.rs @@ -38,7 +38,7 @@ impl MainCharacter { movement_force: Vector2::zero(), velocity: Vector2::zero(), base_velocity: Vector2::new(0.0, GRAVITY_PPS), - size: Vector2::new(100.0, 100.0), + size: Vector2::new(80.0, 100.0), sprite_sheet: AnimatedSpriteSheet::new( sprite_sheet, Vector2::new(300.0, 300.0), @@ -51,12 +51,13 @@ impl MainCharacter { } } + #[must_use] pub fn update_player( &mut self, state: Option, colliders: &Vec, level_height_offset: f32, - ) { + ) -> Result<(), ()> { if let Some(state) = state { // Update the internal state if state != self.current_state { @@ -73,6 +74,14 @@ impl MainCharacter { } // Update the player based on the new velocity - modify_player_based_on_forces(self, colliders, level_height_offset).unwrap(); + modify_player_based_on_forces(self, colliders, level_height_offset) + } + + pub fn reset(&mut self) { + self.position = Vector2::new(0.0, 0.0); + self.velocity = Vector2::zero(); + self.movement_force = Vector2::zero(); + self.current_state = CharacterState::default(); + self.state_set_timestamp = Utc::now(); } } diff --git a/game/src/lib.rs b/game/src/lib.rs index 3dc760f..d6a98ca 100644 --- a/game/src/lib.rs +++ b/game/src/lib.rs @@ -74,7 +74,7 @@ use std::{cell::RefCell, sync::mpsc::TryRecvError}; use discord_sdk::activity::ActivityBuilder; use raylib::prelude::*; -use tracing::{error, info}; +use tracing::{error, info, warn}; use utilities::discord::DiscordConfig; use crate::{ @@ -224,6 +224,7 @@ pub async fn game_begin(game_config: &mut GameConfig) -> Result<(), Box } diff --git a/game/src/scenes/ingame_scene/mod.rs b/game/src/scenes/ingame_scene/mod.rs index bfe505e..af5e290 100644 --- a/game/src/scenes/ingame_scene/mod.rs +++ b/game/src/scenes/ingame_scene/mod.rs @@ -28,6 +28,7 @@ pub struct InGameScreen { world_background: WorldPaintTexture, levels: Vec, current_level_idx: usize, + player_dead: bool, } impl InGameScreen { @@ -48,6 +49,7 @@ impl InGameScreen { world_background: WorldPaintTexture::new(background_texture), levels, current_level_idx: 0, + player_dead: false, } } } @@ -63,7 +65,7 @@ impl Action for InGameScreen { // Set the player to running let cur_level = self.levels.get(self.current_level_idx).unwrap(); - self.player.update_player( + let _ = self.player.update_player( Some(CharacterState::Running), &cur_level.colliders, -cur_level.platform_tex.height as f32, @@ -112,6 +114,10 @@ impl Action for InGameScreen { if renderer.is_key_pressed(KeyboardKey::KEY_ESCAPE) { Ok(ActionFlag::SwitchState(Scenes::PauseScreen)) + } else if self.player_dead { + + // TODO: (luna) make this switch to the death screen plz + Ok(ActionFlag::SwitchState(Scenes::FsmErrorScreen)) } else { Ok(ActionFlag::Continue) } @@ -119,6 +125,13 @@ impl Action for InGameScreen { fn on_finish(&mut self, _interrupted: bool) -> Result<(), ScreenError> { debug!("Finished InGameScreen"); + + // Handle resetting if the player dies + if self.player_dead { + self.player_dead = false; + self.player.reset(); + } + Ok(()) } } diff --git a/game/src/scenes/ingame_scene/update.rs b/game/src/scenes/ingame_scene/update.rs index 754dbc2..2b16ea5 100644 --- a/game/src/scenes/ingame_scene/update.rs +++ b/game/src/scenes/ingame_scene/update.rs @@ -21,7 +21,6 @@ impl FrameUpdate for InGameScreen { // Get the current level let cur_level = self.levels.get(self.current_level_idx).unwrap(); - // Set the camera's offset based on screen size self.camera.offset = raylib.get_screen_size().div(Vector2::new(2.0, 1.05)); self.camera.target = Vector2::new(self.player.position.x, self.camera.target.y); @@ -32,22 +31,39 @@ impl FrameUpdate for InGameScreen { let is_dash = raylib.is_key_pressed(KeyboardKey::KEY_LEFT_SHIFT) && !(self.player.current_state == CharacterState::Dashing); - if is_jump { - self.player.update_player(Some(CharacterState::Jumping), &cur_level.colliders, - -cur_level.platform_tex.height as f32,); + let collision_result = if is_jump { + self.player.update_player( + Some(CharacterState::Jumping), + &cur_level.colliders, + -cur_level.platform_tex.height as f32, + ) } else if is_dash { - self.player.update_player(Some(CharacterState::Dashing), &cur_level.colliders, - -cur_level.platform_tex.height as f32,); + self.player.update_player( + Some(CharacterState::Dashing), + &cur_level.colliders, + -cur_level.platform_tex.height as f32, + ) } else { if self.player.current_state != CharacterState::Jumping && self.player.current_state != CharacterState::Dashing { - self.player.update_player(Some(CharacterState::Running), &cur_level.colliders, - -cur_level.platform_tex.height as f32,); + self.player.update_player( + Some(CharacterState::Running), + &cur_level.colliders, + -cur_level.platform_tex.height as f32, + ) } else { - self.player.update_player(None, &cur_level.colliders, - -cur_level.platform_tex.height as f32,); + self.player.update_player( + None, + &cur_level.colliders, + -cur_level.platform_tex.height as f32, + ) } + }; + + // Handle running into a wall + if let Err(_) = collision_result { + self.player_dead = true; } } } diff --git a/game/src/scenes/ingame_scene/world.rs b/game/src/scenes/ingame_scene/world.rs index 2832a11..ea1a30e 100644 --- a/game/src/scenes/ingame_scene/world.rs +++ b/game/src/scenes/ingame_scene/world.rs @@ -22,10 +22,23 @@ impl WorldSpaceRender for InGameScreen { 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); + cur_level.background_tex.render(raylib, Vector2::new(0.0, -1080.0), &self.camera); // Render the platform layer - raylib.draw_texture_v(&cur_level.platform_tex, Vector2::new(WORLD_LEVEL_X_OFFSET, -cur_level.platform_tex.height as f32), Color::WHITE); + raylib.draw_texture_v( + &cur_level.platform_tex, + Vector2::new(WORLD_LEVEL_X_OFFSET, -cur_level.platform_tex.height as f32), + Color::WHITE, + ); + + if config.debug_view { + for collider in &cur_level.colliders { + let mut translated_collider = collider.clone(); + translated_collider.y += -cur_level.platform_tex.height as f32; + translated_collider.x += WORLD_LEVEL_X_OFFSET; + raylib.draw_rectangle_lines_ex(translated_collider, 5, Color::RED); + } + } // Render the floor as a line let screen_world_zero = raylib.get_screen_to_world2D(Vector2::zero(), self.camera); @@ -40,7 +53,6 @@ impl WorldSpaceRender for InGameScreen { config.colors.white, ); - // Render the player render_character_in_camera_space(raylib, &self.player, &config); }