From a76dd7de72f7d17e2856bf37a6363ba159ba2b8e Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Sat, 2 Oct 2021 15:57:25 -0400 Subject: [PATCH 1/2] world map rendering --- game/assets/levels/level_0/background.png | Bin 0 -> 47431 bytes game/assets/levels/level_0/colliders.json | 32 +++++++++++ game/assets/levels/level_0/platforms.png | Bin 0 -> 16762 bytes game/assets/levels/levels.json | 3 ++ game/src/scenes/ingame_scene/level/loader.rs | 53 +++++++++++++++++++ game/src/scenes/ingame_scene/level/mod.rs | 11 ++++ game/src/scenes/ingame_scene/mod.rs | 26 +++++++-- game/src/scenes/ingame_scene/world.rs | 8 ++- game/src/scenes/mod.rs | 10 +++- game/src/utilities/datastore.rs | 2 + 10 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 game/assets/levels/level_0/background.png create mode 100644 game/assets/levels/level_0/colliders.json create mode 100644 game/assets/levels/level_0/platforms.png create mode 100644 game/assets/levels/levels.json create mode 100644 game/src/scenes/ingame_scene/level/loader.rs create mode 100644 game/src/scenes/ingame_scene/level/mod.rs diff --git a/game/assets/levels/level_0/background.png b/game/assets/levels/level_0/background.png new file mode 100644 index 0000000000000000000000000000000000000000..8fc5cff748145d10ab11fe1235d45e91b45fbec6 GIT binary patch literal 47431 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..94fecb2d76389669f2733fd577d1726a54aed51d GIT binary patch literal 16762 zcmeAS@N?(olHy`uVBq!ia0y~y;9tPN!2E)P4JdNz3S&6~17l03vvYu_v$H}$QGQxx zPAUU~#>Co*wjPHAL|XlWmj-Dyl?fD{2$-wW(Pfb(+7+O9g=?+Vj6GlYXPKyI>h(2c zA3Qk!=&I)K&FlEqH7WdHe)R0wk{3#<_oj|uYIJUeNyYA<;NMG;wp7dc0Kwi{e01Brt>|sW`40LoD!i^w&BvjH7Qv~f{z%6 zUe=61QMIP%-lH|4S!+uD{~hv(i;sL}wKh>@V~47Tz`_M>Mp_#Lm&d9fb((cf*zTX= zb^VFnis6zyGTbYin&137`2WH8oVACZv`iQAWVox}_t}uCrK~aSZsERu+2xf?Eb|++ z_r6_k)-com((7E^GL|p7%;MK`eQz@Bl{XwzcQ#86=ei`s#roiH&pu6do;yqrP4n~C z7SFL`ken6zip|1;#jShF-glqh%{#aA@9oR8?(-kKUXFdh=l#5ANRmoGlW+DTF0)wZEV@SoVHwPIR zfeIQX{9FHy0~Gb6U^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(ScgEv z&1PoMU;u-{|Lbl6p`&0l1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtt2h zzzW8?e+&%r*`T!mcs!JNpD#~>g+Zc2_RW6dzbVaL9b(ljdw{D9M!{$ZjE2By2#kin zXb6mkz-S1JhQMeDP#OXUnq|}=X8b#o$^>NXdl1eJ5;(AWE>r>{4I~$^ynwSIj2;GA zRFMX+20m1g0~{B?vs?(#6{E&L17kF7V5wp>-M~VEVOZuVxbH?8gERyVY=%_?AO}8R zo6cF+HQx}(Jm3wj2p(L%Cwtp~hs8j^ntA{KQ+|s%FIjY)6uctO0{2n?Qwf|6VYs2! z2M($Z;Q9rjE&-!H2pKg78a%@@Z2CBX-rH9;n<4JK5mMvegTKuJW<v^JTMrV9 zR;WrCreZWg1V@d5hS3NK8%t1A^?~DbP`ZMF2jvy$CCvgM^n_u6QPOB(q%Y-BW1wL= z8aA-RHJWZa4{ugs8YQ=qdxl*yr2pQD{`SagkczF{FT+WCfs j#PIBV56ck+VmwvDP*={T8N_#|1r))au6{1-oD!M<>%)IG literal 0 HcmV?d00001 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}")] From f1e10be5da0f67c72ea43097a7494bdc5c75d6fe Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Sat, 2 Oct 2021 16:53:50 -0400 Subject: [PATCH 2/2] Very basic collisions with the world (janky) --- game/assets/levels/level_0/platforms.png | Bin 16762 -> 16797 bytes game/src/character/collisions.rs | 38 +++++++++++++++++++---- game/src/character/mod.rs | 14 +++++++-- game/src/scenes/ingame_scene/mod.rs | 11 +++++-- game/src/scenes/ingame_scene/update.rs | 17 +++++++--- game/src/scenes/ingame_scene/world.rs | 4 ++- 6 files changed, 67 insertions(+), 17 deletions(-) diff --git a/game/assets/levels/level_0/platforms.png b/game/assets/levels/level_0/platforms.png index 94fecb2d76389669f2733fd577d1726a54aed51d..cfa8c08f0066bdbff45b98a28e911cefef3cba26 100644 GIT binary patch delta 407 zcmey>#5lK^al=zaHcRbmduC>Ae$B|Qz}n~O;utbnP)J%X@xEV{00V;rhu#kduBZ!b zVoMZQ>_Q!!4jC#he6P1zkSUDI_=6*#8Uq;Ao%~r>8^OrH&=7vtPkg@>Sn%Jii!2an zI5}mrf|)Mkd8WmTK|gfZh2a_)KIA?B{WY=meW7*ipB|tE4F9fxOtrba zyIG2biGi)jyU1)plh~GptePB+{-Pfm5A?MBGiOB@z`&rf`J$y7lR`TuQ1D)H<(+w9 z4gbsRs6xDUIPu^%fZ}SDqnT%3kl|QEZ{#mt&2}w;2KmX>3#?p+N9~jFZ5tAPn t*GPo|^}PDD!*(r_dLZ+UH7+fEqHz;dg*4X)_Z|Xi@pScbS?83{1OR~%ey{)l literal 16762 zcmeAS@N?(olHy`uVBq!ia0y~y;9tPN!2E)P4JdNz3S&6~17l03vvYu_v$H}$QGQxx zPAUU~#>Co*wjPHAL|XlWmj-Dyl?fD{2$-wW(Pfb(+7+O9g=?+Vj6GlYXPKyI>h(2c zA3Qk!=&I)K&FlEqH7WdHe)R0wk{3#<_oj|uYIJUeNyYA<;NMG;wp7dc0Kwi{e01Brt>|sW`40LoD!i^w&BvjH7Qv~f{z%6 zUe=61QMIP%-lH|4S!+uD{~hv(i;sL}wKh>@V~47Tz`_M>Mp_#Lm&d9fb((cf*zTX= zb^VFnis6zyGTbYin&137`2WH8oVACZv`iQAWVox}_t}uCrK~aSZsERu+2xf?Eb|++ z_r6_k)-com((7E^GL|p7%;MK`eQz@Bl{XwzcQ#86=ei`s#roiH&pu6do;yqrP4n~C z7SFL`ken6zip|1;#jShF-glqh%{#aA@9oR8?(-kKUXFdh=l#5ANRmoGlW+DTF0)wZEV@SoVHwPIR zfeIQX{9FHy0~Gb6U^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(ScgEv z&1PoMU;u-{|Lbl6p`&0l1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtt2h zzzW8?e+&%r*`T!mcs!JNpD#~>g+Zc2_RW6dzbVaL9b(ljdw{D9M!{$ZjE2By2#kin zXb6mkz-S1JhQMeDP#OXUnq|}=X8b#o$^>NXdl1eJ5;(AWE>r>{4I~$^ynwSIj2;GA zRFMX+20m1g0~{B?vs?(#6{E&L17kF7V5wp>-M~VEVOZuVxbH?8gERyVY=%_?AO}8R zo6cF+HQx}(Jm3wj2p(L%Cwtp~hs8j^ntA{KQ+|s%FIjY)6uctO0{2n?Qwf|6VYs2! z2M($Z;Q9rjE&-!H2pKg78a%@@Z2CBX-rH9;n<4JK5mMvegTKuJW<v^JTMrV9 zR;WrCreZWg1V@d5hS3NK8%t1A^?~DbP`ZMF2jvy$CCvgM^n_u6QPOB(q%Y-BW1wL= z8aA-RHJWZa4{ugs8YQ=qdxl*yr2pQD{`SagkczF{FT+WCfs j#PIBV56ck+VmwvDP*={T8N_#|1r))au6{1-oD!M<>%)IG diff --git a/game/src/character/collisions.rs b/game/src/character/collisions.rs index 1c571c7..c802015 100644 --- a/game/src/character/collisions.rs +++ b/game/src/character/collisions.rs @@ -2,11 +2,17 @@ use std::ops::Mul; use raylib::math::{Rectangle, Vector2}; +use crate::scenes::ingame_scene::world::WORLD_LEVEL_X_OFFSET; + use super::{CharacterState, MainCharacter}; pub const GRAVITY_PPS: f32 = 2.0; -pub fn modify_player_based_on_forces(player: &mut MainCharacter) -> Result<(), ()> { +pub fn modify_player_based_on_forces( + player: &mut MainCharacter, + colliders: &Vec, + level_height_offset: f32, +) -> Result<(), ()> { // Modify the player's velocity by the forces player.movement_force += player.base_velocity; player.velocity = player.movement_force; @@ -14,7 +20,7 @@ pub fn modify_player_based_on_forces(player: &mut MainCharacter) -> Result<(), ( // Predict the player's position next frame let predicted_player_position = player.position + player.velocity; - // Calculate a bounding rect around the player + // Calculate a bounding rect around the player both now, and one frame in the future let player_rect = Rectangle::new( predicted_player_position.x - (player.size.x / 2.0), predicted_player_position.y - (player.size.x / 2.0), @@ -25,10 +31,24 @@ pub fn modify_player_based_on_forces(player: &mut MainCharacter) -> Result<(), ( // Calculate a generic "floor" to always collide with let floor_rect = Rectangle::new(f32::MIN, 0.0, f32::MAX, 1.0); + // Check collision conditions + let check_player_colliding_with_floor = || floor_rect.check_collision_recs(&player_rect); + let check_player_colliding_with_floor_next_frame = + || player_rect.y + player_rect.height > floor_rect.y; + let check_player_colliding_with_colliders = || { + colliders.iter().any(|rect| { + let mut translated_rect = rect.clone(); + translated_rect.y += level_height_offset; + translated_rect.x += WORLD_LEVEL_X_OFFSET; + translated_rect.check_collision_recs(&player_rect) + }) + }; + // If the player is colliding, only apply the x force - if (floor_rect.check_collision_recs(&player_rect) - || player_rect.y + player_rect.height > floor_rect.y) - && player.velocity.y > 0.0 + if (check_player_colliding_with_floor() + || check_player_colliding_with_floor_next_frame() + || check_player_colliding_with_colliders()) + && player.velocity.y != 0.0 { player.velocity.y = 0.0; @@ -36,11 +56,17 @@ pub fn modify_player_based_on_forces(player: &mut MainCharacter) -> Result<(), ( if player.current_state == CharacterState::Jumping || player.current_state == CharacterState::Dashing { - player.update_player(Some(CharacterState::Running)); + player.update_player( + Some(CharacterState::Running), + colliders, + level_height_offset, + ); return Ok(()); } } + // Check sideways collisions + // 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 6fe758c..9c1b0d2 100644 --- a/game/src/character/mod.rs +++ b/game/src/character/mod.rs @@ -2,7 +2,10 @@ pub mod collisions; pub mod render; use chrono::{DateTime, Utc}; -use raylib::{math::Vector2, texture::Texture2D}; +use raylib::{ + math::{Rectangle, Vector2}, + texture::Texture2D, +}; use crate::utilities::anim_render::AnimatedSpriteSheet; @@ -48,7 +51,12 @@ impl MainCharacter { } } - pub fn update_player(&mut self, state: Option) { + pub fn update_player( + &mut self, + state: Option, + colliders: &Vec, + level_height_offset: f32, + ) { if let Some(state) = state { // Update the internal state if state != self.current_state { @@ -65,6 +73,6 @@ impl MainCharacter { } // Update the player based on the new velocity - modify_player_based_on_forces(self).unwrap(); + modify_player_based_on_forces(self, colliders, level_height_offset).unwrap(); } } diff --git a/game/src/scenes/ingame_scene/mod.rs b/game/src/scenes/ingame_scene/mod.rs index 70024d9..cbcb340 100644 --- a/game/src/scenes/ingame_scene/mod.rs +++ b/game/src/scenes/ingame_scene/mod.rs @@ -18,7 +18,7 @@ use tracing::{debug, trace}; mod hud; pub mod level; mod update; -mod world; +pub mod world; #[derive(Debug)] pub struct InGameScreen { @@ -43,7 +43,7 @@ impl InGameScreen { rotation: 0.0, zoom: 1.0, }, - player: MainCharacter::new(Vector2::new(0.0, -80.0), player_sprite_sheet), + player: MainCharacter::new(Vector2::new(0.0, -85.0), player_sprite_sheet), world_background: WorldPaintTexture::new(background_texture), levels, current_level_idx: 0, @@ -61,7 +61,12 @@ impl Action for InGameScreen { debug!("Running InGameScreen for the first time"); // Set the player to running - self.player.update_player(Some(CharacterState::Running)); + let cur_level = self.levels.get(self.current_level_idx).unwrap(); + self.player.update_player( + Some(CharacterState::Running), + &cur_level.colliders, + -cur_level.platform_tex.height as f32, + ); Ok(()) } diff --git a/game/src/scenes/ingame_scene/update.rs b/game/src/scenes/ingame_scene/update.rs index 0c98c86..754dbc2 100644 --- a/game/src/scenes/ingame_scene/update.rs +++ b/game/src/scenes/ingame_scene/update.rs @@ -17,6 +17,11 @@ impl FrameUpdate for InGameScreen { config: &GameConfig, ) { puffin::profile_function!(); + + // 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); @@ -28,16 +33,20 @@ impl FrameUpdate for InGameScreen { && !(self.player.current_state == CharacterState::Dashing); if is_jump { - self.player.update_player(Some(CharacterState::Jumping)); + 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)); + 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)); + self.player.update_player(Some(CharacterState::Running), &cur_level.colliders, + -cur_level.platform_tex.height as f32,); } else { - self.player.update_player(None); + self.player.update_player(None, &cur_level.colliders, + -cur_level.platform_tex.height as f32,); } } } diff --git a/game/src/scenes/ingame_scene/world.rs b/game/src/scenes/ingame_scene/world.rs index ee10f7e..4e9fd05 100644 --- a/game/src/scenes/ingame_scene/world.rs +++ b/game/src/scenes/ingame_scene/world.rs @@ -8,6 +8,8 @@ use crate::{ }; use raylib::prelude::*; +pub const WORLD_LEVEL_X_OFFSET: f32 = 200.0; + impl WorldSpaceRender for InGameScreen { fn render_world_space( &self, @@ -23,7 +25,7 @@ impl WorldSpaceRender for InGameScreen { // 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); + raylib.draw_texture_v(&cur_level.platform_tex, Vector2::new(WORLD_LEVEL_X_OFFSET, -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);