diff --git a/src/activities/house/room.rs b/src/activities/house/room.rs index aa3170f..7d3a06c 100644 --- a/src/activities/house/room.rs +++ b/src/activities/house/room.rs @@ -1,9 +1,8 @@ use super::{furniture::Furniture, grid::Grid}; use crate::game::{self, ZLayer}; use comfy::{ - draw_circle, draw_rect, draw_rect_outline, draw_sprite, error, random_i32, - texture_id, vec2, EngineContext, HashSet, RandomRange as _, Vec2, GOLD, GREEN, - PURPLE, RED, WHITE + draw_rect, draw_rect_outline, draw_sprite, error, random_i32, texture_id, vec2, + EngineContext, HashSet, RandomRange as _, Vec2, GREEN, PURPLE, RED, WHITE }; use indexmap::IndexSet; diff --git a/src/game.rs b/src/game.rs index 6352858..534288d 100644 --- a/src/game.rs +++ b/src/game.rs @@ -75,7 +75,8 @@ pub enum ZLayer { MapMax = -1, Human = 0, Ghost = 1, - UI = 100 + UI = 100, + GameOver = 1000 } impl From for i32 { @@ -134,40 +135,44 @@ pub const HOUSE_DISCHARGE_RATE: f32 = 30.0; pub const GHOST_CHARGE_RATE: f32 = 200.0; pub fn update(state: &mut State, ctx: &mut EngineContext<'_>) { - // Update the score. It's based on time. - state.score += ctx.delta * 10.0; - - // Update the currently active activity. - match state.activity { - Activity::House(_) => house::update(state, ctx), - Activity::Overworld => overworld::update(state, ctx) - } - - // We update the charge of houses here - the charge will always decrease, even if the - // house is not the current activity. - for (house_pos, house) in &mut state.houses { - house.charge -= ctx.delta * HOUSE_DISCHARGE_RATE; + if state.ghost.charge > 0.0 { + // Update the score. It's based on time. + state.score += ctx.delta * 10.0; + // Update the currently active activity. match state.activity { - Activity::House(pos) if *house_pos == pos => { - // The ghost is currently inside the house. Increase its discarge rate. - house.charge -= ctx.delta * GHOST_DISCHARGE_RATE; - if house.charge < 0.0 { - state.ghost.charge += house.charge; - house.charge = 0.0; - } - - // And possibly also charge the ghost when inside a house. - if state.ghost.charge < state.ghost.max_charge { - let charge_transfer = (ctx.delta * GHOST_CHARGE_RATE) - .min(state.ghost.max_charge - state.ghost.charge) - .min(house.charge); - state.ghost.charge += charge_transfer; - house.charge -= charge_transfer; - } - }, - _ => {} + Activity::House(_) => house::update(state, ctx), + Activity::Overworld => overworld::update(state, ctx) } + + // We update the charge of houses here - the charge will always decrease, even if the + // house is not the current activity. + for (house_pos, house) in &mut state.houses { + house.charge -= ctx.delta * HOUSE_DISCHARGE_RATE; + + match state.activity { + Activity::House(pos) if *house_pos == pos => { + // The ghost is currently inside the house. Increase its discarge rate. + house.charge -= ctx.delta * GHOST_DISCHARGE_RATE; + if house.charge < 0.0 { + state.ghost.charge += house.charge; + house.charge = 0.0; + } + + // And possibly also charge the ghost when inside a house. + if state.ghost.charge < state.ghost.max_charge { + let charge_transfer = (ctx.delta * GHOST_CHARGE_RATE) + .min(state.ghost.max_charge - state.ghost.charge) + .min(house.charge); + state.ghost.charge += charge_transfer; + house.charge -= charge_transfer; + } + }, + _ => {} + } + } + } else { + crate::game_over::update(state, ctx); } // Make sure the ghost's charge never drops below 0. @@ -180,4 +185,7 @@ pub fn draw(state: &State, engine: &EngineContext<'_>) { Activity::Overworld => overworld::draw(state, engine) } crate::ui::draw(state, engine); + if state.ghost.charge <= 0.0 { + crate::game_over::draw(state, engine); + } } diff --git a/src/game_over.rs b/src/game_over.rs new file mode 100644 index 0000000..0e2f434 --- /dev/null +++ b/src/game_over.rs @@ -0,0 +1,52 @@ +use std::mem::take; + +use crate::{game::ZLayer, State}; +use comfy::{ + draw_rect, egui, + egui::{Align, Layout}, + is_key_pressed, main_camera, Color, EngineContext, WHITE +}; +use egui::{Align2, RichText}; +use log::info; + +pub fn update(state: &mut State, _engine: &mut EngineContext<'_>) { + if is_key_pressed(comfy::KeyCode::Return) { + info!("Restart game"); + take(state); //reset to default + } +} + +pub fn draw(state: &State, _engine: &EngineContext<'_>) { + let cam = main_camera(); + draw_rect( + cam.center, + cam.world_viewport() * 1.2, + Color::new(0.0, 0.0, 0.0, 0.5), + ZLayer::GameOver.into() + ); + + egui::Area::new("game_over") + .anchor(Align2::CENTER_CENTER, egui::vec2(0.0, 0.0)) + .show(egui(), |ui| { + ui.with_layout(Layout::top_down_justified(Align::Center), |ui| { + ui.heading( + RichText::new( + "The poor spirit lost all their energy and starve to death" + ) + .color(WHITE) + .strong() + .size(50.0) + ); + ui.label( + RichText::new(format!("\nYour Score:\n{:.0}", state.score)) + .color(WHITE) + .size(30.0) + ); + ui.label( + RichText::new("\n\n\npress enter for restart") + .color(WHITE) + .size(30.0) + ); + }) + }); +} diff --git a/src/main.rs b/src/main.rs index 5b79150..ec4ea4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,9 +5,9 @@ mod assets { include!(env!("ASSETS_RS")); } - mod activities; mod game; +mod game_over; mod ui; use std::env::var; @@ -70,14 +70,12 @@ impl State { impl GameLoop for State { fn new(_c: &mut EngineState) -> Self { - Self { - dev: dev_from_env(), - ..Default::default() - } + Default::default() } fn update(&mut self, ctx: &mut EngineContext<'_>) { if !self.setup_called { + self.dev = dev_from_env(); game::setup(self, ctx); game::setup(self, ctx); self.setup_called = true;