diff --git a/game/assets/levels/level_0/appearing_platforms.png b/game/assets/levels/level_0/appearing_platforms.png index f2b35f9..53b660a 100644 Binary files a/game/assets/levels/level_0/appearing_platforms.png 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 66a3756..e6a0a49 100644 --- a/game/assets/levels/level_0/colliders.json +++ b/game/assets/levels/level_0/colliders.json @@ -1,44 +1,63 @@ [ { "x": -500, - "y": 1000, + "y": 760, "width": 16000, "height": 10 }, { - "x": 322, - "y": 926, - "width": 610, - "height": 73 + "x": 834, + "y": 592 + , + "width": 415, + "height": 54 }, { - "x": 852, - "y": 823, - "width": 81, - "height": 178 + "x": 1385, + "y": 374, + "width": 415, + "height": 54 }, { - "x": 852, - "y": 823, - "width": 258, - "height": 33 + "x": 1808, + "y": 376, + "width": 59, + "height": 379 }, { - "x": 1599, - "y": 699, - "width": 918, - "height": 63 + "x": 2352, + "y": 376, + "width": 59, + "height": 379 }, { - "x": 2733, - "y": 789, - "width": 108, - "height": 211 - }, - { - "x": 1110, - "y": 942, - "width": 366, + "x": 3534, + "y": 590, + "width": 381, "height": 57 + }, + { + "x": 4299, + "y": 425, + "width": 197, + "height": 330 + }, + { + "x": 4885, + "y": 584, + "width": 380, + "height": 64 + }, + { + "x": 6333, + "y": 530, + "width": 415, + "height": 58 + }, + { + "x": 7007, + "y": 393, + "width": 1124, + "height": 52 } ] diff --git a/game/assets/levels/level_0/disappearing_platforms.png b/game/assets/levels/level_0/disappearing_platforms.png index 3e1666c..06f75ca 100644 Binary files a/game/assets/levels/level_0/disappearing_platforms.png and b/game/assets/levels/level_0/disappearing_platforms.png differ diff --git a/game/assets/levels/level_0/level0.xcf b/game/assets/levels/level_0/level0.xcf new file mode 100644 index 0000000..186b613 Binary files /dev/null and b/game/assets/levels/level_0/level0.xcf differ diff --git a/game/assets/levels/level_0/platforms.png b/game/assets/levels/level_0/platforms.png index cfa8c08..1cc7ca8 100644 Binary files a/game/assets/levels/level_0/platforms.png and b/game/assets/levels/level_0/platforms.png differ diff --git a/game/assets/levels/level_0/zones.json b/game/assets/levels/level_0/zones.json index f5f518d..10fb295 100644 --- a/game/assets/levels/level_0/zones.json +++ b/game/assets/levels/level_0/zones.json @@ -1,28 +1,34 @@ { "appear": [ { - "x": 1110, - "y": 942, - "width": 366, - "height": 57 + "x": 8130, + "y": 0, + "width": 56, + "height": 442 + }, + { + "x": 9867, + "y": 698, + "width": 447, + "height": 58 } ], "disappear": [ { - "x": 792, - "y": 462, - "width": 54, - "height": 468 + "x": 2079, + "y": 0, + "width": 61, + "height": 378 }, { - "x": 2005, - "y": 641, - "width": 141, - "height": 289 + "x": 8131, + "y": 440, + "width": 56, + "height": 313 } ], "win": { - "x": 3000, + "x": 12000, "y": 0, "width": 100, "height": 3000 diff --git a/game/src/character/mod.rs b/game/src/character/mod.rs index a02853b..4ee74e9 100644 --- a/game/src/character/mod.rs +++ b/game/src/character/mod.rs @@ -72,7 +72,7 @@ impl MainCharacter { // Handle extra external forces based on the character state self.movement_force = match &state { CharacterState::Running => Vector2::new(10.0, 0.0), - CharacterState::Jumping => Vector2::new(10.0, -30.0), + CharacterState::Jumping => Vector2::new(10.0, -40.0), CharacterState::Dashing => Vector2::new(30.0, -20.0), }; diff --git a/game/src/scenes/death_screen.rs b/game/src/scenes/death_screen.rs index 19b3582..80e117c 100644 --- a/game/src/scenes/death_screen.rs +++ b/game/src/scenes/death_screen.rs @@ -2,6 +2,7 @@ use std::ops::{Div, Sub}; use chrono::{DateTime, Utc}; use dirty_fsm::{Action, ActionFlag}; +use discord_sdk::activity::{ActivityBuilder, Assets}; use pkg_version::pkg_version_major; use raylib::prelude::*; @@ -14,7 +15,7 @@ use crate::{GameConfig, context::GameContext, utilities::{ }}; use super::{Scenes, ScreenError}; -use tracing::{debug, info, trace}; +use tracing::{debug, info, error, trace}; #[derive(Debug)] pub struct DeathScreen { @@ -36,9 +37,19 @@ impl Action for DeathScreen { Ok(()) } - fn on_first_run(&mut self, _context: &GameContext) -> Result<(), ScreenError> { + fn on_first_run(&mut self, context: &GameContext) -> Result<(), ScreenError> { debug!("Running DeathScreen for the first time"); + if let Err(e) = context.discord_rpc_send.send(Some( + ActivityBuilder::default() + .details("dead... again") + .assets( + Assets::default().large("game-logo-small", Some(context.config.name.clone())), + ) + )) { + error!("Failed to update discord: {}", e); + } + Ok(()) } diff --git a/game/src/scenes/how_to_play_screen.rs b/game/src/scenes/how_to_play_screen.rs index b41f542..bcfb308 100644 --- a/game/src/scenes/how_to_play_screen.rs +++ b/game/src/scenes/how_to_play_screen.rs @@ -2,6 +2,7 @@ use std::ops::{Div, Sub}; use chrono::{DateTime, Utc}; use dirty_fsm::{Action, ActionFlag}; +use discord_sdk::activity::{ActivityBuilder, Assets}; use pkg_version::pkg_version_major; use raylib::prelude::*; @@ -18,7 +19,7 @@ use crate::{ }; use super::{Scenes, ScreenError}; -use tracing::{debug, info, trace}; +use tracing::{debug, error, info, trace}; #[derive(Debug)] pub struct HowToPlayScreen { @@ -40,9 +41,19 @@ impl Action for HowToPlayScreen { Ok(()) } - fn on_first_run(&mut self, _context: &GameContext) -> Result<(), ScreenError> { + fn on_first_run(&mut self, context: &GameContext) -> Result<(), ScreenError> { debug!("Running HowToPlayScreen for the first time"); + if let Err(e) = context.discord_rpc_send.send(Some( + ActivityBuilder::default() + .details("learning how to play") + .assets( + Assets::default().large("game-logo-small", Some(context.config.name.clone())), + ), + )) { + error!("Failed to update discord: {}", e); + } + Ok(()) } diff --git a/game/src/scenes/ingame_scene/level/loader.rs b/game/src/scenes/ingame_scene/level/loader.rs index 05ff1ad..08a9e48 100644 --- a/game/src/scenes/ingame_scene/level/loader.rs +++ b/game/src/scenes/ingame_scene/level/loader.rs @@ -29,46 +29,53 @@ 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( - 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), - )?, - 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)) - .unwrap() - .data - .into(), - ) - .unwrap(), - )?, - zones: serde_json::from_str( - &String::from_utf8( - StaticGameData::get(&format!("levels/{}/zones.json", level_name)) - .unwrap() - .data - .into(), - ) - .unwrap(), - )?, + let zones = serde_json::from_str( + &String::from_utf8( + StaticGameData::get(&format!("levels/{}/zones.json", level_name)) + .unwrap() + .data + .into(), + ) + .unwrap(), + )?; + levels.push({ + let mut l = Level { + name: level_name.to_string(), + background_tex: WorldPaintTexture::new(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), + )?, + 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)) + .unwrap() + .data + .into(), + ) + .unwrap(), + )?, + zones, + }; + for a in &l.zones.appear { + l.colliders.push(a.clone()); + } + l }); } Ok(levels) diff --git a/game/src/scenes/ingame_scene/mod.rs b/game/src/scenes/ingame_scene/mod.rs index 9ed9748..69e33b0 100644 --- a/game/src/scenes/ingame_scene/mod.rs +++ b/game/src/scenes/ingame_scene/mod.rs @@ -1,3 +1,4 @@ +use chrono::{DateTime, Utc}; use dirty_fsm::{Action, ActionFlag}; use discord_sdk::activity::{ActivityBuilder, Assets}; use raylib::prelude::*; @@ -29,6 +30,7 @@ pub struct InGameScreen { levels: Vec, current_level_idx: usize, player_dead: bool, + level_switch_timestamp: DateTime, } impl InGameScreen { @@ -50,6 +52,7 @@ impl InGameScreen { levels, current_level_idx: 0, player_dead: false, + level_switch_timestamp: Utc::now(), } } } @@ -66,6 +69,7 @@ impl Action for InGameScreen { // Handle cleanup after death self.player_dead = false; self.player.reset(); + self.level_switch_timestamp = Utc::now(); // Set the player to running let cur_level = self.levels.get(context.current_level).unwrap(); @@ -77,9 +81,12 @@ impl Action for InGameScreen { // Update discord if let Err(e) = context.discord_rpc_send.send(Some( - ActivityBuilder::default().details("in game").assets( - Assets::default().large("game-logo-small", Some(context.config.name.clone())), - ), + ActivityBuilder::default() + .details(format!("LVL {}", context.current_level)) + .assets( + Assets::default().large("game-logo-small", Some(context.config.name.clone())), + ) + .start_timestamp(self.level_switch_timestamp), )) { error!("Failed to update discord: {}", e); } @@ -94,7 +101,11 @@ impl Action for InGameScreen { ) -> Result, ScreenError> { puffin::profile_function!(); trace!("execute() called on InGameScreen"); - self.current_level_idx = context.current_level; + + if self.current_level_idx != context.current_level { + self.current_level_idx = context.current_level; + self.level_switch_timestamp = Utc::now(); + } // Grab exclusive access to the renderer let mut renderer = context.renderer.borrow_mut(); diff --git a/game/src/scenes/ingame_scene/world.rs b/game/src/scenes/ingame_scene/world.rs index 7ed6877..aa79317 100644 --- a/game/src/scenes/ingame_scene/world.rs +++ b/game/src/scenes/ingame_scene/world.rs @@ -45,11 +45,13 @@ impl WorldSpaceRender for InGameScreen { .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 + // 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 + ((zone.x + WORLD_LEVEL_X_OFFSET + (zone.width / 2.0)) - self.player.position.x) + .abs() as i32 }) .min() .unwrap_or(i32::MAX); @@ -86,11 +88,13 @@ impl WorldSpaceRender for InGameScreen { .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 + // 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 + ((zone.x + WORLD_LEVEL_X_OFFSET + (zone.width / 2.0)) - self.player.position.x) + .abs() as i32 }) .min() .unwrap_or(i32::MAX); diff --git a/game/src/scenes/next_level_screen.rs b/game/src/scenes/next_level_screen.rs index c7c5ccb..5714600 100644 --- a/game/src/scenes/next_level_screen.rs +++ b/game/src/scenes/next_level_screen.rs @@ -2,6 +2,7 @@ use std::ops::{Div, Sub}; use chrono::{DateTime, Utc}; use dirty_fsm::{Action, ActionFlag}; +use discord_sdk::activity::{ActivityBuilder, Assets}; use pkg_version::pkg_version_major; use raylib::prelude::*; @@ -18,7 +19,7 @@ use crate::{ }; use super::{Scenes, ScreenError}; -use tracing::{debug, info, trace}; +use tracing::{debug, error, info, trace}; #[derive(Debug)] pub struct NextLevelScreen { @@ -40,8 +41,17 @@ impl Action for NextLevelScreen { Ok(()) } - fn on_first_run(&mut self, _context: &GameContext) -> Result<(), ScreenError> { + fn on_first_run(&mut self, context: &GameContext) -> Result<(), ScreenError> { debug!("Running NextLevelScreen for the first time"); + + if let Err(e) = context.discord_rpc_send.send(Some( + ActivityBuilder::default().details("accepting fate").assets( + Assets::default().large("game-logo-small", Some(context.config.name.clone())), + ), + )) { + error!("Failed to update discord: {}", e); + } + Ok(()) } @@ -58,7 +68,6 @@ impl Action for NextLevelScreen { } else { Ok(ActionFlag::Continue) } - } fn on_finish(&mut self, _interrupted: bool) -> Result<(), ScreenError> { @@ -112,8 +121,9 @@ impl ScreenSpaceRender for NextLevelScreen { ); //Next Level - let hovering_next_button = Rectangle::new(80.0, screen_size.y as f32 / 2.0 + 50.0, 200.0, 40.0) - .check_collision_point_rec(mouse_position); + let hovering_next_button = + Rectangle::new(80.0, screen_size.y as f32 / 2.0 + 50.0, 200.0, 40.0) + .check_collision_point_rec(mouse_position); raylib.draw_rgb_split_text( Vector2::new(80.0, screen_size.y / 2.0 + 50.0), ">> Next Level", diff --git a/game/src/scenes/options_screen.rs b/game/src/scenes/options_screen.rs index 3f85ef6..b0b3832 100644 --- a/game/src/scenes/options_screen.rs +++ b/game/src/scenes/options_screen.rs @@ -2,6 +2,7 @@ use std::ops::{Div, Sub}; use chrono::{DateTime, Utc}; use dirty_fsm::{Action, ActionFlag}; +use discord_sdk::activity::{ActivityBuilder, Assets}; use pkg_version::pkg_version_major; use raylib::prelude::*; @@ -18,7 +19,7 @@ use crate::{ }; use super::{Scenes, ScreenError}; -use tracing::{debug, info, trace}; +use tracing::{debug, error, info, trace}; #[derive(Debug)] pub struct OptionsScreen { @@ -40,9 +41,19 @@ impl Action for OptionsScreen { Ok(()) } - fn on_first_run(&mut self, _context: &GameContext) -> Result<(), ScreenError> { + fn on_first_run(&mut self, context: &GameContext) -> Result<(), ScreenError> { debug!("Running OptionsScreen for the first time"); + if let Err(e) = context.discord_rpc_send.send(Some( + ActivityBuilder::default() + .details("we gott'em boys!") + .assets( + Assets::default().large("game-logo-small", Some(context.config.name.clone())), + ), + )) { + error!("Failed to update discord: {}", e); + } + // Rick-roll the user let _ = webbrowser::open("https://www.youtube.com/watch?v=dQw4w9WgXcQ"); @@ -108,7 +119,6 @@ impl ScreenSpaceRender for OptionsScreen { Color::WHITE, ); - //Back to Menu let hovering_back = Rectangle::new(35.0, screen_size.y as f32 - 80.0, 200.0, 40.0) .check_collision_point_rec(mouse_position); diff --git a/game/src/scenes/win_screen.rs b/game/src/scenes/win_screen.rs index 1a85052..dc2851f 100644 --- a/game/src/scenes/win_screen.rs +++ b/game/src/scenes/win_screen.rs @@ -2,6 +2,7 @@ use std::ops::{Div, Sub}; use chrono::{DateTime, Utc}; use dirty_fsm::{Action, ActionFlag}; +use discord_sdk::activity::{ActivityBuilder, Assets}; use pkg_version::pkg_version_major; use raylib::prelude::*; @@ -18,7 +19,7 @@ use crate::{ }; use super::{Scenes, ScreenError}; -use tracing::{debug, info, trace}; +use tracing::{debug, error, info, trace}; #[derive(Debug)] pub struct WinScreen { @@ -42,8 +43,19 @@ impl Action for WinScreen { Ok(()) } - fn on_first_run(&mut self, _context: &GameContext) -> Result<(), ScreenError> { + fn on_first_run(&mut self, context: &GameContext) -> Result<(), ScreenError> { debug!("Running WinScreen for the first time"); + + if let Err(e) = context.discord_rpc_send.send(Some( + ActivityBuilder::default() + .details("somehow won the game") + .assets( + Assets::default().large("game-logo-small", Some(context.config.name.clone())), + ), + )) { + error!("Failed to update discord: {}", e); + } + Ok(()) }