From f31a32c7ec2d5a7f6f5226a59fb334d19229560a Mon Sep 17 00:00:00 2001
From: Evan Pratten <ewpratten@gmail.com>
Date: Sat, 2 Oct 2021 23:36:30 -0400
Subject: [PATCH] Appearing platforms

---
 .../levels/level_0/appearing_platforms.png    | Bin 0 -> 16253 bytes
 game/assets/levels/level_0/colliders.json     |   6 +++
 game/assets/levels/level_0/zones.json         |  17 ++++++++
 game/src/scenes/ingame_scene/level/loader.rs  |  24 +++++++++--
 game/src/scenes/ingame_scene/level/mod.rs     |  11 ++++-
 game/src/scenes/ingame_scene/world.rs         |  40 +++++++++++++++++-
 6 files changed, 92 insertions(+), 6 deletions(-)
 create mode 100644 game/assets/levels/level_0/appearing_platforms.png
 create mode 100644 game/assets/levels/level_0/zones.json

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 0000000000000000000000000000000000000000..f2b35f97f7a6350a7de6ff1344198dd79dda4ddf
GIT binary patch
literal 16253
zcmeI&dn{W~90%}o+fJ>X!(y1JrQ$heK{_@;J=zFu&|sN)WGoEzT0OE#RVQAt*(7L;
zT4rQXEZZNOjj55ag>6^_V~AmfOi1jdUGEYy`@_FW?00T%a_{$^oZRy{_x|(CDdGhB
zX;F+R2q7&N(>n+u9VtS@MRhe*@^S>rL<kedGZ-8egF#J6<Hf}%#v)`@E+{|Ce8Dle
z#tv=>vJvrhQ~Nl#?Fx(O35Sb0<|7oDYt^$29f=do+P+M5SuU^Zy`Nw5utmE?MEy#f
zou9wEc-&&D(%@WA*36pw;M0XKQv%_erjr9p#$=~Sm*IYK)qt$HK2&TjHN!};aYpGk
zD?~iOWU$%0h?+~^Hn+k%5~gB2JZQDC1@ZbkT{drAZ9y<=W!rDFc6zOfWk}1NYoA>+
zS-A6x@VZn|y>TYBBFv88HY9Jpn9vj4<H#Mhj_k{6PMex-<|Z^>VJo_s7b3&wU1ia<
z2Za_)-Fj)kDVw%KjS-f;UXnq5cZK<=L%F|ss8Q)rjV7=B<?nLk^k$;0drn+wz(SJ_
zW$TUvF+VSEGPU!%X=65lRF`MlvC`@ytY!~=PCCISZ6py5N0S1^i1wL6xh2CTHk2}?
zM>#OPRoZDy)_hNxapon<(ret2k%YUXMyHc}ODZ~6*H>!?pKMJGOFrnxN7JG_0|QJ{
z%c2(J@8^w__#y3RyroJGrZB_P5z^4dPYg+Fj;KO%1}nga{E<Q=Y8hb@O4Slm5zE^%
zBx`(Gj$x_}!W)X#Rdsynp@9GhfB*=900@8p2!H?xfB*=900``B0pVCa5ibTHs&dqq
z!-WO{AOHd&00JNY0w4eaAOHd&00JPeF9e#fTm?d=$@pG?Jth>bqfNr=0>Yn>CZ2or
zgGV3$0w4eaAOHd&00JNY0w4eaAOHgUL!d$6cF&WFgw)5<>47NhZCID4cI|wQUK2Bp
zc0RkGfY%A2fdB}A00@8p2!O!<EAYI%3ZMM6TkDUNM}#gV{TREBzQb`f#rgMs%bfrr
z3lH)icdE-M(&Fv_g%C3SN_>UdyAux>W*Y=-wk6=Z*_QaH{}h+U|3u1A6m_fPufy^Q
K^ltHr68!==1=wZ)

literal 0
HcmV?d00001

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/zones.json b/game/assets/levels/level_0/zones.json
new file mode 100644
index 0000000..2c61932
--- /dev/null
+++ b/game/assets/levels/level_0/zones.json
@@ -0,0 +1,17 @@
+{
+    "appear": [
+        {
+            "x": 1110,
+            "y": 942,
+            "width": 366,
+            "height": 57
+        }
+    ],
+    "disappear": [],
+    "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..55d220e 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,11 @@ 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),
+            )?,
             colliders: serde_json::from_str(
                 &String::from_utf8(
                     StaticGameData::get(&format!("levels/{}/colliders.json", level_name))
@@ -46,6 +55,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..3ce213d 100644
--- a/game/src/scenes/ingame_scene/level/mod.rs
+++ b/game/src/scenes/ingame_scene/level/mod.rs
@@ -4,10 +4,19 @@ use crate::utilities::world_paint_texture::WorldPaintTexture;
 
 pub mod loader;
 
+#[derive(Debug, Deserialize)]
+pub struct LevelZones {
+    pub appear: Vec<Rectangle>,
+    pub disappear: Vec<Rectangle>,
+    pub win: Rectangle,
+}
+
 #[derive(Debug)]
 pub struct Level {
     pub name: String,
     pub background_tex: WorldPaintTexture,
     pub platform_tex: Texture2D,
-    pub colliders: Vec<Rectangle>
+    pub appearing_platform_tex: Texture2D,
+    pub colliders: Vec<Rectangle>,
+    pub zones: LevelZones,
 }
diff --git a/game/src/scenes/ingame_scene/world.rs b/game/src/scenes/ingame_scene/world.rs
index 1c146a4..f6893ae 100644
--- a/game/src/scenes/ingame_scene/world.rs
+++ b/game/src/scenes/ingame_scene/world.rs
@@ -1,14 +1,18 @@
-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 = 15.0;
 
 impl WorldSpaceRender for InGameScreen {
     fn render_world_space(
@@ -33,6 +37,38 @@ 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.y - cur_level.platform_tex.height as f32,
+                )
+                .distance_to(self.player.position) as i32
+            })
+            .min()
+            .unwrap();
+        let 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, 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(opacity),
+        );
+
         #[cfg(all(debug_assertions, feature = "collider_debug"))]
         {
             for collider in &cur_level.colliders {