diff --git a/game/assets/configs/final_shader.json b/game/assets/configs/final_shader.json index a7df3a3..d9b2530 100644 --- a/game/assets/configs/final_shader.json +++ b/game/assets/configs/final_shader.json @@ -1,5 +1,5 @@ { "pixel_scale": 1.0, - "warp_factor": 0.0, - "scanline_darkness": 0.0 + "warp_factor": 0.5, + "scanline_darkness": 0.5 } diff --git a/game/src/character/mod.rs b/game/src/character/mod.rs new file mode 100644 index 0000000..2535864 --- /dev/null +++ b/game/src/character/mod.rs @@ -0,0 +1,19 @@ +pub mod render; + +use raylib::math::Vector2; + +#[derive(Debug, Clone)] +pub struct MainCharacter { + pub position: Vector2, +} + +impl MainCharacter { + + pub fn new(position: Vector2) -> Self { + Self { position } + } + + pub fn apply_force(&mut self, force: Vector2) { + self.position += force; + } +} diff --git a/game/src/character/render.rs b/game/src/character/render.rs new file mode 100644 index 0000000..bf29cf8 --- /dev/null +++ b/game/src/character/render.rs @@ -0,0 +1,13 @@ +use raylib::prelude::*; + +use crate::utilities::non_ref_raylib::HackedRaylibHandle; + +use super::MainCharacter; + +pub fn render_character_in_camera_space( + raylib: &mut RaylibMode2D<'_, HackedRaylibHandle>, + player: &MainCharacter, +) { + + raylib.draw_rectangle_v(player.position, Vector2::new(10.0, 20.0), Color::WHITE); +} diff --git a/game/src/lib.rs b/game/src/lib.rs index 936c22d..65ecea6 100644 --- a/game/src/lib.rs +++ b/game/src/lib.rs @@ -103,6 +103,7 @@ mod discord_rpc; mod scenes; mod utilities; pub use utilities::{datastore::StaticGameData, game_config::GameConfig}; +mod character; /// The game entrypoint pub async fn game_begin(game_config: &GameConfig) -> Result<(), Box> { diff --git a/game/src/scenes/ingame_scene/hud.rs b/game/src/scenes/ingame_scene/hud.rs new file mode 100644 index 0000000..60dc8eb --- /dev/null +++ b/game/src/scenes/ingame_scene/hud.rs @@ -0,0 +1,13 @@ +use crate::utilities::render_layer::ScreenSpaceRender; +use raylib::prelude::*; +use super::InGameScreen; + +impl ScreenSpaceRender for InGameScreen { + fn render_screen_space( + &self, + raylib: &mut crate::utilities::non_ref_raylib::HackedRaylibHandle, + ) { + // Calculate the logo position + let screen_size = raylib.get_screen_size(); + } +} diff --git a/game/src/scenes/ingame_scene/mod.rs b/game/src/scenes/ingame_scene/mod.rs new file mode 100644 index 0000000..934785b --- /dev/null +++ b/game/src/scenes/ingame_scene/mod.rs @@ -0,0 +1,81 @@ +use dirty_fsm::{Action, ActionFlag}; +use raylib::prelude::*; + +use crate::{character::MainCharacter, context::GameContext, utilities::render_layer::{FrameUpdate, ScreenSpaceRender, WorldSpaceRender}}; + +use super::{Scenes, ScreenError}; +use tracing::{debug, trace}; + +mod hud; +mod update; +mod world; + +#[derive(Debug)] +pub struct InGameScreen { + camera: Camera2D, + player: MainCharacter +} + +impl InGameScreen { + /// Construct a new `InGameScreen` + pub fn new() -> Self { + Self { + camera: Camera2D { + offset: Vector2::zero(), + target: Vector2::zero(), + rotation: 0.0, + zoom: 1.0, + }, + player: MainCharacter::new(Vector2::zero()), + } + } +} + +impl Action for InGameScreen { + fn on_register(&mut self) -> Result<(), ScreenError> { + debug!("Registered"); + Ok(()) + } + + fn on_first_run(&mut self, _context: &GameContext) -> Result<(), ScreenError> { + debug!("Running InGameScreen for the first time"); + + Ok(()) + } + + fn execute( + &mut self, + delta: &chrono::Duration, + context: &GameContext, + ) -> Result, ScreenError> { + trace!("execute() called on InGameScreen"); + + // Grab exclusive access to the renderer + let mut renderer = context.renderer.borrow_mut(); + + // Update the inputs and checking logic + self.update(&mut renderer, delta); + + // Wipe the background + renderer.clear_background(Color::BLACK); + + // Render the world + { + // Enter 2D mode + let mut raylib_camera_space = renderer.begin_mode2D(self.camera); + + // Render in world space + self.render_world_space(&mut raylib_camera_space); + } + + // Render the HUD + self.render_screen_space(&mut renderer); + + Ok(ActionFlag::Continue) + } + + fn on_finish(&mut self, _interrupted: bool) -> Result<(), ScreenError> { + debug!("Finished InGameScreen"); + Ok(()) + } +} diff --git a/game/src/scenes/ingame_scene/update.rs b/game/src/scenes/ingame_scene/update.rs new file mode 100644 index 0000000..3e2edf1 --- /dev/null +++ b/game/src/scenes/ingame_scene/update.rs @@ -0,0 +1,22 @@ +use std::ops::Div; + +use super::InGameScreen; +use crate::utilities::{non_ref_raylib::HackedRaylibHandle, render_layer::FrameUpdate}; +use chrono::Duration; +use raylib::prelude::*; + +impl FrameUpdate for InGameScreen { + fn update(&mut self, raylib: &HackedRaylibHandle, delta_seconds: &Duration) { + // Set the camera's offset based on screen size + self.camera.offset = raylib.get_screen_size().div(2.0); + + // Check the only possible keyboard inputs + let is_jump = raylib.is_key_down(KeyboardKey::KEY_SPACE); + let is_dash = raylib.is_key_down(KeyboardKey::KEY_LEFT_SHIFT); + let is_pause = raylib.is_key_down(KeyboardKey::KEY_ESCAPE); + + if is_jump { + self.player.apply_force(Vector2::new(0.0, 1.0)); + } + } +} diff --git a/game/src/scenes/ingame_scene/world.rs b/game/src/scenes/ingame_scene/world.rs new file mode 100644 index 0000000..84b8c85 --- /dev/null +++ b/game/src/scenes/ingame_scene/world.rs @@ -0,0 +1,13 @@ +use super::InGameScreen; +use crate::{ + character::render::render_character_in_camera_space, + utilities::{non_ref_raylib::HackedRaylibHandle, render_layer::WorldSpaceRender}, +}; +use raylib::prelude::*; + +impl WorldSpaceRender for InGameScreen { + fn render_world_space(&self, raylib: &mut RaylibMode2D<'_, HackedRaylibHandle>) { + // Render the player + render_character_in_camera_space(raylib, &self.player); + } +} diff --git a/game/src/scenes/loading_screen.rs b/game/src/scenes/loading_screen.rs index 9833c66..1c1409f 100644 --- a/game/src/scenes/loading_screen.rs +++ b/game/src/scenes/loading_screen.rs @@ -111,7 +111,7 @@ impl ScreenSpaceRender for LoadingScreen { trace!("Loading screen fade at {:.2}%", fade_percentage); // Render the background - raylib.clear_background(Color::WHITE); + raylib.clear_background(Color::BLACK); // Calculate the logo position let screen_size = raylib.get_screen_size(); diff --git a/game/src/scenes/main_menu_screen.rs b/game/src/scenes/main_menu_screen.rs index 3135218..1c68f9f 100644 --- a/game/src/scenes/main_menu_screen.rs +++ b/game/src/scenes/main_menu_screen.rs @@ -5,7 +5,16 @@ use dirty_fsm::{Action, ActionFlag}; use pkg_version::pkg_version_major; use raylib::prelude::*; -use crate::{context::GameContext, utilities::{datastore::{load_texture_from_internal_data, ResourceLoadError}, game_version::get_version_string, math::interpolate_exp, non_ref_raylib::HackedRaylibHandle, render_layer::ScreenSpaceRender}}; +use crate::{ + context::GameContext, + utilities::{ + datastore::{load_texture_from_internal_data, ResourceLoadError}, + game_version::get_version_string, + math::interpolate_exp, + non_ref_raylib::HackedRaylibHandle, + render_layer::ScreenSpaceRender, + }, +}; use super::{Scenes, ScreenError}; use tracing::{debug, info, trace}; @@ -40,7 +49,12 @@ impl Action for MainMenuScreen { trace!("execute() called on MainMenuScreen"); self.render_screen_space(&mut context.renderer.borrow_mut()); - Ok(ActionFlag::Continue) + // TODO: TEMP + if context.renderer.borrow_mut().is_key_pressed(KeyboardKey::KEY_SPACE) { + Ok(ActionFlag::SwitchState(Scenes::InGameScene)) + } else { + Ok(ActionFlag::Continue) + } } fn on_finish(&mut self, _interrupted: bool) -> Result<(), ScreenError> { @@ -55,7 +69,7 @@ impl ScreenSpaceRender for MainMenuScreen { raylib: &mut crate::utilities::non_ref_raylib::HackedRaylibHandle, ) { // Render the background - raylib.clear_background(Color::WHITE); + raylib.clear_background(Color::BLACK); // Calculate the logo position let screen_size = raylib.get_screen_size(); @@ -68,16 +82,20 @@ impl ScreenSpaceRender for MainMenuScreen { 10, screen_size.y as i32 - 35, 15, - Color::BLACK, + Color::WHITE, ); } // Render the game version info raylib.draw_text( - &format!("Version: {} Commit: {}", get_version_string(), env!("VERGEN_GIT_SHA_SHORT")), + &format!( + "Version: {} Commit: {}", + get_version_string(), + env!("VERGEN_GIT_SHA_SHORT") + ), 10, screen_size.y as i32 - 20, 15, - Color::BLACK, + Color::WHITE, ); } } diff --git a/game/src/scenes/mod.rs b/game/src/scenes/mod.rs index ead1c54..7a0f1e9 100644 --- a/game/src/scenes/mod.rs +++ b/game/src/scenes/mod.rs @@ -1,5 +1,5 @@ use self::{ - fsm_error_screen::FsmErrorScreen, loading_screen::LoadingScreen, + fsm_error_screen::FsmErrorScreen, ingame_scene::InGameScreen, loading_screen::LoadingScreen, main_menu_screen::MainMenuScreen, }; use crate::{ @@ -10,6 +10,7 @@ use dirty_fsm::StateMachine; use raylib::RaylibThread; pub mod fsm_error_screen; +pub mod ingame_scene; pub mod loading_screen; pub mod main_menu_screen; @@ -20,6 +21,7 @@ pub enum Scenes { FsmErrorScreen, LoadingScreen, MainMenuScreen, + InGameScene, } /// Contains any possible errors thrown while rendering @@ -45,5 +47,6 @@ 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())?; Ok(machine) } diff --git a/game/src/utilities/render_layer.rs b/game/src/utilities/render_layer.rs index 141c6fa..963bc26 100644 --- a/game/src/utilities/render_layer.rs +++ b/game/src/utilities/render_layer.rs @@ -3,7 +3,7 @@ use raylib::{prelude::RaylibMode2D, RaylibHandle}; use crate::utilities::non_ref_raylib::HackedRaylibHandle; pub trait FrameUpdate { - fn update(&mut self, raylib: &RaylibHandle, delta_seconds: f32); + fn update(&mut self, raylib: &HackedRaylibHandle, delta_seconds: &chrono::Duration); } pub trait ScreenSpaceRender {