load in the game logo placeholder

This commit is contained in:
Evan Pratten 2021-04-23 12:29:30 -04:00
parent ac5bd2c790
commit c551f0be0a
9 changed files with 95 additions and 74 deletions

View File

@ -11,3 +11,6 @@ serialstudio = "0.1.0"
serde = "1.0.125" serde = "1.0.125"
serde_json = "1.0.64" serde_json = "1.0.64"
failure = "0.1.8" failure = "0.1.8"
parry2d = "0.4.0"
log = "0.4.14"
env_logger = "0.8.3"

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -2,6 +2,8 @@
use std::fmt; use std::fmt;
use raylib::{RaylibHandle, RaylibThread};
use crate::resources::GlobalResources; use crate::resources::GlobalResources;
/// Overall states for the game /// Overall states for the game
@ -25,16 +27,16 @@ pub struct GameCore {
pub has_rendered_first_frame: bool, pub has_rendered_first_frame: bool,
/// Resources /// Resources
pub resources: Option<GlobalResources>, pub resources: GlobalResources,
} }
impl GameCore { impl GameCore {
pub fn new() -> Self { pub fn new(raylib: &mut RaylibHandle, thread: &RaylibThread) -> Self {
Self { Self {
state: GameState::Loading, state: GameState::Loading,
last_state_change_time: 0.0, last_state_change_time: 0.0,
has_rendered_first_frame:false, has_rendered_first_frame: false,
resources: None, resources: GlobalResources::load_all(raylib, thread).expect("Failed to load game assets. Can not launch!"),
} }
} }
} }

31
src/logic/ingame/mod.rs Normal file
View File

@ -0,0 +1,31 @@
use raylib::prelude::*;
use crate::{
gamecore::{GameCore, GameState},
lib::wrappers::audio::player::AudioPlayer,
};
use super::screen::Screen;
pub struct InGameScreen {}
impl InGameScreen {
pub fn new() -> Self {
Self {}
}
}
impl Screen for InGameScreen {
fn render(
&mut self,
draw_handle: &mut RaylibDrawHandle,
thread: &RaylibThread,
audio_system: &mut AudioPlayer,
game_core: &mut GameCore,
) -> Option<GameState> {
// Clear frame
draw_handle.clear_background(Color::WHITE);
return None;
}
}

View File

@ -3,7 +3,6 @@ use raylib::prelude::*;
use crate::{ use crate::{
gamecore::{GameCore, GameState}, gamecore::{GameCore, GameState},
lib::wrappers::audio::player::AudioPlayer, lib::wrappers::audio::player::AudioPlayer,
resources::GlobalResources,
}; };
use super::screen::Screen; use super::screen::Screen;
@ -13,8 +12,6 @@ const RUST_ORANGE: Color = Color::new(222, 165, 132, 255);
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
enum LoadingScreenState { enum LoadingScreenState {
Preload,
LoadingResources,
GameLogo, GameLogo,
RaylibLogo, RaylibLogo,
Finished, Finished,
@ -28,50 +25,11 @@ pub struct LoadingScreen {
impl LoadingScreen { impl LoadingScreen {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
state: LoadingScreenState::Preload, state: LoadingScreenState::GameLogo,
last_state_switch_time: 0.0, last_state_switch_time: 0.0,
} }
} }
fn load_global_resources(
&mut self,
draw_handle: &mut RaylibDrawHandle,
game_core: &mut GameCore,
win_height: i32,
win_width: i32,
) {
// Show a loading message (this will stay on screen until all resources are loaded)
draw_handle.draw_text(
"Loading Assets...",
(win_width / 2) - 90,
(win_height / 3) * 2,
25,
Color::BLACK,
);
if self.state == LoadingScreenState::LoadingResources {
// Load the global resources
let resources = GlobalResources::load_all();
// Handle a loading error
if resources.is_err() {
println!("ERROR: Failed to load game resources!");
panic!("{:?}", resources.err());
}
// Set the global resources
game_core.resources = Some(resources.unwrap());
// Set the loading screen state to move on to the game logo
self.state = LoadingScreenState::GameLogo;
self.last_state_switch_time = draw_handle.get_time();
return;
}
// Update internal state
self.state = LoadingScreenState::LoadingResources;
}
fn get_logo_mask(&self, playthrough_percent: f64) -> Color { fn get_logo_mask(&self, playthrough_percent: f64) -> Color {
// Determine the alpha // Determine the alpha
let alpha; let alpha;
@ -105,10 +63,18 @@ impl LoadingScreen {
(draw_handle.get_time() - self.last_state_switch_time) / SECONDS_PER_LOGO; (draw_handle.get_time() - self.last_state_switch_time) / SECONDS_PER_LOGO;
// Build a color mask // Build a color mask
let mask = self.get_logo_mask( playthrough_percent); let mask = self.get_logo_mask(playthrough_percent);
// Get the logo
let logo = &game_core.resources.game_logo;
// Render the logo // Render the logo
// TODO draw_handle.draw_texture(
logo,
(win_width / 2) - (logo.width / 2),
(win_height / 2) - (logo.height / 2),
mask,
);
// Move on to next logo if needed // Move on to next logo if needed
if playthrough_percent >= 1.0 { if playthrough_percent >= 1.0 {
@ -130,14 +96,14 @@ impl LoadingScreen {
(draw_handle.get_time() - self.last_state_switch_time) / SECONDS_PER_LOGO; (draw_handle.get_time() - self.last_state_switch_time) / SECONDS_PER_LOGO;
// Build a color mask // Build a color mask
let mask = self.get_logo_mask( playthrough_percent); let mask = self.get_logo_mask(playthrough_percent);
// Create modified colors // Create modified colors
let alpha_orange = Color { let alpha_orange = Color {
r: RUST_ORANGE.r, r: RUST_ORANGE.r,
g: RUST_ORANGE.g, g: RUST_ORANGE.g,
b: RUST_ORANGE.b, b: RUST_ORANGE.b,
a: mask.a a: mask.a,
}; };
// Render the raylib logo // Render the raylib logo
@ -182,6 +148,7 @@ impl Screen for LoadingScreen {
fn render( fn render(
&mut self, &mut self,
draw_handle: &mut RaylibDrawHandle, draw_handle: &mut RaylibDrawHandle,
thread: &RaylibThread,
_audio_system: &mut AudioPlayer, _audio_system: &mut AudioPlayer,
game_core: &mut GameCore, game_core: &mut GameCore,
) -> Option<GameState> { ) -> Option<GameState> {
@ -194,12 +161,6 @@ impl Screen for LoadingScreen {
// Call the appropriate internal handler function // Call the appropriate internal handler function
match self.state { match self.state {
LoadingScreenState::Preload => {
self.load_global_resources(draw_handle, game_core, win_height, win_width)
}
LoadingScreenState::LoadingResources => {
self.load_global_resources(draw_handle, game_core, win_height, win_width)
}
LoadingScreenState::GameLogo => { LoadingScreenState::GameLogo => {
self.show_game_logo(draw_handle, game_core, win_height, win_width) self.show_game_logo(draw_handle, game_core, win_height, win_width)
} }
@ -212,7 +173,6 @@ impl Screen for LoadingScreen {
// A DEBUG warning and skip button // A DEBUG warning and skip button
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
// Render debug text // Render debug text
draw_handle.draw_text("RUNNING IN DEBUG MODE", 0, 0, 20, Color::RED); draw_handle.draw_text("RUNNING IN DEBUG MODE", 0, 0, 20, Color::RED);
draw_handle.draw_text("Press ESC to skip this screen", 0, 25, 20, Color::RED); draw_handle.draw_text("Press ESC to skip this screen", 0, 25, 20, Color::RED);
@ -220,7 +180,6 @@ impl Screen for LoadingScreen {
if draw_handle.is_key_pressed(KeyboardKey::KEY_ESCAPE) { if draw_handle.is_key_pressed(KeyboardKey::KEY_ESCAPE) {
return Some(GameState::MainMenu); return Some(GameState::MainMenu);
} }
} }
return None; return None;

View File

@ -1,6 +1,9 @@
use raylib::prelude::*; use raylib::prelude::*;
use crate::{gamecore::{GameCore, GameState}, lib::wrappers::audio::player::AudioPlayer}; use crate::{
gamecore::{GameCore, GameState},
lib::wrappers::audio::player::AudioPlayer,
};
use super::screen::Screen; use super::screen::Screen;
@ -16,10 +19,10 @@ impl Screen for MainMenuScreen {
fn render( fn render(
&mut self, &mut self,
draw_handle: &mut RaylibDrawHandle, draw_handle: &mut RaylibDrawHandle,
thread: &RaylibThread,
audio_system: &mut AudioPlayer, audio_system: &mut AudioPlayer,
game_core: &mut GameCore, game_core: &mut GameCore,
) -> Option<GameState> { ) -> Option<GameState> {
// Clear frame // Clear frame
draw_handle.clear_background(Color::RED); draw_handle.clear_background(Color::RED);

View File

@ -1,12 +1,16 @@
use raylib::prelude::RaylibDrawHandle; use raylib::{prelude::RaylibDrawHandle, RaylibThread};
use crate::{gamecore::{GameCore, GameState}, lib::wrappers::audio::player::AudioPlayer}; use crate::{
gamecore::{GameCore, GameState},
lib::wrappers::audio::player::AudioPlayer,
};
/// A trait describing all game screens /// A trait describing all game screens
pub trait Screen { pub trait Screen {
fn render( fn render(
&mut self, &mut self,
draw_handle: &mut RaylibDrawHandle, draw_handle: &mut RaylibDrawHandle,
thread: &RaylibThread,
audio_system: &mut AudioPlayer, audio_system: &mut AudioPlayer,
game_core: &mut GameCore, game_core: &mut GameCore,
) -> Option<GameState>; ) -> Option<GameState>;

View File

@ -5,6 +5,7 @@ mod resources;
use gamecore::{GameCore, GameState}; use gamecore::{GameCore, GameState};
use lib::{utils::profiler::GameProfiler, wrappers::audio::player::AudioPlayer}; use lib::{utils::profiler::GameProfiler, wrappers::audio::player::AudioPlayer};
use log::{debug, info};
use logic::{loadingscreen::LoadingScreen, mainmenu::MainMenuScreen, screen::Screen}; use logic::{loadingscreen::LoadingScreen, mainmenu::MainMenuScreen, screen::Screen};
use raylib::prelude::*; use raylib::prelude::*;
@ -17,6 +18,9 @@ const WINDOW_TITLE: &str = r"Ludum Dare 48";
const MAX_FPS: u32 = 60; const MAX_FPS: u32 = 60;
fn main() { fn main() {
// Configure the logger
env_logger::init();
// Configure a window // Configure a window
let (mut raylib, raylib_thread) = raylib::init() let (mut raylib, raylib_thread) = raylib::init()
.size( .size(
@ -31,7 +35,7 @@ fn main() {
raylib.set_exit_key(None); raylib.set_exit_key(None);
// Set up the game's core state // Set up the game's core state
let mut game_core = GameCore::new(); let mut game_core = GameCore::new(&mut raylib, &raylib_thread);
// Set up the game's profiler // Set up the game's profiler
let mut profiler = GameProfiler::new(); let mut profiler = GameProfiler::new();
@ -50,17 +54,24 @@ fn main() {
// Call appropriate render function // Call appropriate render function
let new_state: Option<GameState> = match game_core.state { let new_state: Option<GameState> = match game_core.state {
GameState::Loading => { GameState::Loading => loading_screen.render(
loading_screen.render(&mut draw_handle, &mut audio_system, &mut game_core) &mut draw_handle,
} &raylib_thread,
GameState::MainMenu => { &mut audio_system,
main_menu_screen.render(&mut draw_handle, &mut audio_system, &mut game_core) &mut game_core,
} ),
GameState::MainMenu => main_menu_screen.render(
&mut draw_handle,
&raylib_thread,
&mut audio_system,
&mut game_core,
),
}; };
if new_state.is_some() { if new_state.is_some() {
game_core.state = new_state.unwrap(); game_core.state = new_state.unwrap();
game_core.last_state_change_time = draw_handle.get_time(); game_core.last_state_change_time = draw_handle.get_time();
debug!("Switching global state to: {}", game_core.state);
} }
// Feed the profiler // Feed the profiler

View File

@ -1,11 +1,19 @@
use failure::Error; use failure::Error;
use raylib::{RaylibHandle, RaylibThread, texture::{Image, Texture2D}};
/// This struct contains all textures and sounds that must be loaded into (V)RAM at the start of the game /// This struct contains all textures and sounds that must be loaded into (V)RAM at the start of the game
pub struct GlobalResources {} pub struct GlobalResources {
// Branding
pub game_logo: Texture2D
}
impl GlobalResources { impl GlobalResources {
/// Load all resources. **THIS WILL HANG!** /// Load all resources. **THIS WILL HANG!**
pub fn load_all() -> Result<GlobalResources, Error> { pub fn load_all(raylib: &mut RaylibHandle, thread: &RaylibThread) -> Result<GlobalResources, String> {
Ok(GlobalResources {}) Ok(GlobalResources {
game_logo: raylib.load_texture_from_image(&thread, &Image::load_image("./assets/img/logos/game-logo.png")?)?
})
} }
} }