diff --git a/game/dist/map_gameMap.end.json b/game/dist/map_gameMap.end.json new file mode 100644 index 00000000..77e1c780 --- /dev/null +++ b/game/dist/map_gameMap.end.json @@ -0,0 +1,4 @@ +[ + 0, + 0 +] \ No newline at end of file diff --git a/game/game_logic/src/rendering/utilities/map_render.rs b/game/game_logic/src/rendering/utilities/map_render.rs index 6452595e..b552a889 100644 --- a/game/game_logic/src/rendering/utilities/map_render.rs +++ b/game/game_logic/src/rendering/utilities/map_render.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, path::PathBuf, sync::Arc}; use crate::{ - asset_manager::{load_texture_from_internal_data, InternalData}, + asset_manager::{load_json_structure, load_texture_from_internal_data, InternalData}, model::{world_object::WorldSpaceObjectCollider, world_object_package::WorldObjectPackage}, }; use nalgebra as na; @@ -79,6 +79,7 @@ pub struct MapRenderer { map: Map, tile_textures: HashMap, world_objects: WorldObjectPackage, + world_end: na::Vector2, } impl MapRenderer { @@ -86,6 +87,7 @@ impl MapRenderer { pub fn new( tmx_path: &str, objects_path: &str, + end_path: &str, raylib: &mut RaylibHandle, raylib_thread: &RaylibThread, ) -> Result { @@ -123,11 +125,13 @@ impl MapRenderer { // Load the world objects let world_objects = WorldObjectPackage::load(raylib, raylib_thread, objects_path).unwrap(); + let world_end = load_json_structure(end_path).unwrap(); Ok(Self { map, tile_textures, world_objects, + world_end, }) } @@ -264,10 +268,7 @@ impl MapRenderer { Vector2::new(screen_width as f32, screen_height as f32), camera, ); - let player_position = na::Vector2::new( - player_position.x, - player_position.y * -1.0, - ); + let player_position = na::Vector2::new(player_position.x, player_position.y * -1.0); // Handle each layer from the bottom up for layer in self.map.layers() { @@ -324,7 +325,8 @@ impl MapRenderer { // Check if there is an object at this tile for obj_ref in &self.world_objects.object_references { if obj_ref.get_tile_space_position().x == sampler_x as f32 - && obj_ref.get_tile_space_position().y == sampler_y as f32 + && obj_ref.get_tile_space_position().y + == sampler_y as f32 { // Get access to the actual object definition let object_key = obj_ref.into_key(); @@ -344,7 +346,8 @@ impl MapRenderer { .unwrap(); tex.render_automatic( draw_handle, - obj_ref.get_world_space_position() - (tex.size() / 2.0), + obj_ref.get_world_space_position() + - (tex.size() / 2.0), None, Some(tex.size() / 2.0), Some(obj_ref.rotation_degrees), @@ -356,7 +359,8 @@ impl MapRenderer { .bottom_static_textures .get_mut(&object_key) .unwrap(); - let p: Vector2 = obj_ref.get_world_space_position().into(); + let p: Vector2 = + obj_ref.get_world_space_position().into(); let r1 = Rectangle { x: 0.0, y: 0.0, @@ -390,8 +394,10 @@ impl MapRenderer { if let Some(footprint_radius) = obj_def.visualization_radius { - let player_dist_to_object = - (obj_ref.get_world_space_position() - player_position).norm(); + let player_dist_to_object = (obj_ref + .get_world_space_position() + - player_position) + .norm(); // debug!( // "Player dist to object: {}", // player_dist_to_object @@ -409,7 +415,8 @@ impl MapRenderer { .unwrap(); tex.render_automatic( draw_handle, - obj_ref.get_world_space_position() - (tex.size() / 2.0), + obj_ref.get_world_space_position() + - (tex.size() / 2.0), None, Some(tex.size() / 2.0), Some(obj_ref.rotation_degrees), @@ -421,7 +428,8 @@ impl MapRenderer { .top_static_textures .get_mut(&object_key) .unwrap(); - let p: Vector2 = obj_ref.get_world_space_position().into(); + let p: Vector2 = + obj_ref.get_world_space_position().into(); let r1 = Rectangle { x: 0.0, y: 0.0, @@ -478,6 +486,16 @@ impl MapRenderer { self.world_objects.world_space_colliders.clone() } + pub fn is_point_inside_win_zone(&self, position: na::Vector2) -> bool { + // Convert the position to a tile position + let tile_x = (position.x / 128.0).floor() as i32; + let tile_y = ((position.y * -1.0) / 128.0).floor() as i32; + debug!("Tile x: {}, y: {}", tile_x, tile_y); + + // Check if the tile is inside the win zone + tile_x == self.world_end.x && tile_y == self.world_end.y + } + // /// Used to modify the player's velocity based on the effects of the world // pub fn effect_velocity_with_collisions( // &self, diff --git a/game/game_logic/src/scenes/player_interaction.rs b/game/game_logic/src/scenes/player_interaction.rs index b9374575..41374b14 100644 --- a/game/game_logic/src/scenes/player_interaction.rs +++ b/game/game_logic/src/scenes/player_interaction.rs @@ -30,6 +30,7 @@ pub struct PlayableScene { world_colliders: Vec, show_debug_info: bool, play_start_time: DateTime, + player_start_position: na::Vector2, } impl PlayableScene { @@ -42,22 +43,27 @@ impl PlayableScene { let map_renderer = MapRenderer::new( "map_gameMap.tmx", "map_gameMap.objects.json", + "map_gameMap.end.json", raylib_handle, thread, ) .unwrap(); let world_colliders = map_renderer.get_world_colliders(); + // Define the player start position + let player_start_position = na::Vector2::new( + 10.0 * constants.tile_size as f32, + -10.0 * constants.tile_size as f32, + ); + // Load the game music let game_soundtrack = load_music_from_internal_data(thread, "assets/audio/gameSoundtrack.mp3").unwrap(); Self { has_updated_discord_rpc: false, - player: Player::new(na::Vector2::new( - 10.0 * constants.tile_size as f32, - -10.0 * constants.tile_size as f32, - )), + player_start_position, + player: Player::new(player_start_position), world_map: map_renderer, camera: raylib::camera::Camera2D { target: raylib::math::Vector2 { x: 0.0, y: 0.0 }, @@ -98,6 +104,8 @@ impl PlayableScene { .unwrap(); self.has_updated_discord_rpc = true; self.play_start_time = Utc::now(); + self.player.position = self.player_start_position; + self.player.velocity = na::Vector2::new(0.0, 0.0); } // Ensure the game soundtrack is playing @@ -119,9 +127,6 @@ impl PlayableScene { self.draw_ui(&mut draw, constants); // NOTE: If you want to trigger a cutscene, do it here by using one of: - // return MenuStateSignal::DoFinishedCutscene { - // playtime: Utc::now().signed_duration_since(self.play_start_time), - // }; // return MenuStateSignal::DoMeltedDeathCutscene { // playtime: Utc::now().signed_duration_since(self.play_start_time), // }; @@ -129,6 +134,16 @@ impl PlayableScene { // playtime: Utc::now().signed_duration_since(self.play_start_time), // }; + // Handle winning + if self + .world_map + .is_point_inside_win_zone(self.player.position) + { + return MenuStateSignal::DoFinishedCutscene { + playtime: Utc::now().signed_duration_since(self.play_start_time), + }; + } + // A little hack to make pausing work if draw.is_key_pressed(KeyboardKey::KEY_ESCAPE) { return MenuStateSignal::DoPauseMenu; diff --git a/game/game_logic/src/scenes/test_fox.rs b/game/game_logic/src/scenes/test_fox.rs index a4d19043..99d68e94 100644 --- a/game/game_logic/src/scenes/test_fox.rs +++ b/game/game_logic/src/scenes/test_fox.rs @@ -27,6 +27,7 @@ impl TestFoxScene { let map_renderer = MapRenderer::new( "map_gameMap.tmx", "map_gameMap.objects.json", + "map_gameMap.end.json", raylib_handle, thread, )