diff --git a/game/assets/levels/level_0/appearing_platforms.png b/game/assets/levels/level_0/appearing_platforms.png new file mode 100644 index 0000000..f2b35f9 Binary files /dev/null and b/game/assets/levels/level_0/appearing_platforms.png differ diff --git a/game/assets/levels/level_0/colliders.json b/game/assets/levels/level_0/colliders.json index 513a595..66a3756 100644 --- a/game/assets/levels/level_0/colliders.json +++ b/game/assets/levels/level_0/colliders.json @@ -34,5 +34,11 @@ "y": 789, "width": 108, "height": 211 + }, + { + "x": 1110, + "y": 942, + "width": 366, + "height": 57 } ] diff --git a/game/assets/levels/level_0/disappearing_platforms.png b/game/assets/levels/level_0/disappearing_platforms.png new file mode 100644 index 0000000..3e1666c Binary files /dev/null and b/game/assets/levels/level_0/disappearing_platforms.png differ diff --git a/game/assets/levels/level_0/zones.json b/game/assets/levels/level_0/zones.json new file mode 100644 index 0000000..f5f518d --- /dev/null +++ b/game/assets/levels/level_0/zones.json @@ -0,0 +1,30 @@ +{ + "appear": [ + { + "x": 1110, + "y": 942, + "width": 366, + "height": 57 + } + ], + "disappear": [ + { + "x": 792, + "y": 462, + "width": 54, + "height": 468 + }, + { + "x": 2005, + "y": 641, + "width": 141, + "height": 289 + } + ], + "win": { + "x": 3000, + "y": 0, + "width": 100, + "height": 3000 + } +} diff --git a/game/src/scenes/ingame_scene/level/loader.rs b/game/src/scenes/ingame_scene/level/loader.rs index 8680ae3..05ff1ad 100644 --- a/game/src/scenes/ingame_scene/level/loader.rs +++ b/game/src/scenes/ingame_scene/level/loader.rs @@ -1,6 +1,12 @@ use raylib::{RaylibHandle, RaylibThread}; -use crate::{StaticGameData, utilities::{datastore::{load_texture_from_internal_data, ResourceLoadError}, world_paint_texture::WorldPaintTexture}}; +use crate::{ + utilities::{ + datastore::{load_texture_from_internal_data, ResourceLoadError}, + world_paint_texture::WorldPaintTexture, + }, + StaticGameData, +}; use super::Level; @@ -23,8 +29,6 @@ pub fn load_all_levels( let mut levels = Vec::new(); for level_name in &level_names { - - levels.push(Level { name: level_name.to_string(), background_tex: WorldPaintTexture::new(load_texture_from_internal_data( @@ -37,6 +41,16 @@ pub fn load_all_levels( thread, &format!("levels/{}/platforms.png", level_name), )?, + appearing_platform_tex: load_texture_from_internal_data( + raylib_handle, + thread, + &format!("levels/{}/appearing_platforms.png", level_name), + )?, + disappearing_platform_tex: load_texture_from_internal_data( + raylib_handle, + thread, + &format!("levels/{}/disappearing_platforms.png", level_name), + )?, colliders: serde_json::from_str( &String::from_utf8( StaticGameData::get(&format!("levels/{}/colliders.json", level_name)) @@ -46,6 +60,15 @@ pub fn load_all_levels( ) .unwrap(), )?, + zones: serde_json::from_str( + &String::from_utf8( + StaticGameData::get(&format!("levels/{}/zones.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 index 1c48789..35bc6e0 100644 --- a/game/src/scenes/ingame_scene/level/mod.rs +++ b/game/src/scenes/ingame_scene/level/mod.rs @@ -4,10 +4,20 @@ use crate::utilities::world_paint_texture::WorldPaintTexture; pub mod loader; +#[derive(Debug, Deserialize)] +pub struct LevelZones { + pub appear: Vec, + pub disappear: Vec, + pub win: Rectangle, +} + #[derive(Debug)] pub struct Level { pub name: String, pub background_tex: WorldPaintTexture, pub platform_tex: Texture2D, - pub colliders: Vec + pub appearing_platform_tex: Texture2D, + pub disappearing_platform_tex: Texture2D, + pub colliders: Vec, + pub zones: LevelZones, } diff --git a/game/src/scenes/ingame_scene/world.rs b/game/src/scenes/ingame_scene/world.rs index 1c146a4..7ed6877 100644 --- a/game/src/scenes/ingame_scene/world.rs +++ b/game/src/scenes/ingame_scene/world.rs @@ -1,14 +1,19 @@ -use std::ops::Mul; +use std::ops::{Div, Mul, Sub}; use super::InGameScreen; use crate::{ character::render::render_character_in_camera_space, - utilities::{non_ref_raylib::HackedRaylibHandle, render_layer::WorldSpaceRender}, + utilities::{ + math::interpolate_exp, non_ref_raylib::HackedRaylibHandle, render_layer::WorldSpaceRender, + }, GameConfig, }; use raylib::prelude::*; +use tracing::trace; pub const WORLD_LEVEL_X_OFFSET: f32 = 200.0; +pub const APPEAR_FADE_DISTANCE: f32 = 16.0; +pub const DISAPPEAR_FADE_DISTANCE: f32 = 18.0; impl WorldSpaceRender for InGameScreen { fn render_world_space( @@ -33,6 +38,88 @@ impl WorldSpaceRender for InGameScreen { Color::WHITE, ); + { + // Calculate the distance between the player and the nearest appearing zone + let appear_zone_dist = cur_level + .zones + .appear + .iter() + .map(|zone| { + Vector2::new( + zone.x + WORLD_LEVEL_X_OFFSET + (zone.width / 2.0), + zone.y - cur_level.platform_tex.height as f32, + ) + .distance_to(self.player.position) as i32 + }) + .min() + .unwrap_or(i32::MAX); + let appear_opacity = interpolate_exp( + (appear_zone_dist as f32) + .sub(APPEAR_FADE_DISTANCE.div(2.0)) + .div(APPEAR_FADE_DISTANCE) + .mul(-1.0), + -APPEAR_FADE_DISTANCE..APPEAR_FADE_DISTANCE, + 0.0..1.0, + 8.0, + ); + trace!( + "Appearing values: ({}, {})", + appear_zone_dist, + appear_opacity + ); + + // Render the appearing layer + raylib.draw_texture_v( + &cur_level.appearing_platform_tex, + Vector2::new( + WORLD_LEVEL_X_OFFSET, + -cur_level.appearing_platform_tex.height as f32, + ), + Color::WHITE.fade(appear_opacity), + ); + } + + { + // Calculate the distance between the player and the nearest disappearing zone + let disappear_zone_dist = cur_level + .zones + .disappear + .iter() + .map(|zone| { + Vector2::new( + zone.x + WORLD_LEVEL_X_OFFSET + (zone.width / 2.0), + zone.y - cur_level.platform_tex.height as f32, + ) + .distance_to(self.player.position) as i32 + }) + .min() + .unwrap_or(i32::MAX); + let disappear_opacity = interpolate_exp( + (disappear_zone_dist as f32) + .sub(DISAPPEAR_FADE_DISTANCE.div(2.0)) + .div(DISAPPEAR_FADE_DISTANCE) + .mul(-1.0), + -DISAPPEAR_FADE_DISTANCE..DISAPPEAR_FADE_DISTANCE, + 0.0..1.0, + 8.0, + ); + trace!( + "Disappearing values: ({}, {})", + disappear_zone_dist, + disappear_opacity + ); + + // Render the appearing layer + raylib.draw_texture_v( + &cur_level.disappearing_platform_tex, + Vector2::new( + WORLD_LEVEL_X_OFFSET, + -cur_level.disappearing_platform_tex.height as f32, + ), + Color::WHITE.fade(1.0 - disappear_opacity), + ); + } + #[cfg(all(debug_assertions, feature = "collider_debug"))] { for collider in &cur_level.colliders {