Add the character in the most basic form

Co-authored-by: Carter Tomlenovich <cartertom@tuta.io>
This commit is contained in:
Evan Pratten 2021-10-01 19:27:10 -04:00
parent bb2a62fcb9
commit 2b471bd8d4
12 changed files with 194 additions and 11 deletions

View File

@ -1,5 +1,5 @@
{
"pixel_scale": 1.0,
"warp_factor": 0.0,
"scanline_darkness": 0.0
"warp_factor": 0.5,
"scanline_darkness": 0.5
}

19
game/src/character/mod.rs Normal file
View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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<dyn std::error::Error>> {

View File

@ -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();
}
}

View File

@ -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<Scenes, ScreenError, GameContext> 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<dirty_fsm::ActionFlag<Scenes>, 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(())
}
}

View File

@ -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));
}
}
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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<Scenes, ScreenError, GameContext> 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,
);
}
}

View File

@ -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)
}

View File

@ -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 {