game-wip-dontplay/src/app.rs
2023-04-03 15:37:14 +02:00

184 lines
5.7 KiB
Rust

use std::fmt::{self};
use egui_sfml::{egui, SfEgui};
use gamedebug_core::imm_dbg;
use sfml::{
graphics::{Color, RenderTarget, RenderWindow},
window::{Event, Key},
};
use crate::{
debug::DebugState,
game::GameState,
graphics::{self, NATIVE_RESOLUTION},
input::KbInput,
math::{wp_to_tp, WorldPos},
res::Res,
};
/// Application level state (includes game and ui state, etc.)
pub struct App {
pub rw: RenderWindow,
pub should_quit: bool,
pub game: GameState,
pub res: Res,
pub sf_egui: SfEgui,
pub kb_input: KbInput,
pub debug: DebugState,
}
impl App {
pub fn new() -> anyhow::Result<Self> {
let rw = graphics::make_window();
let sf_egui = SfEgui::new(&rw);
Ok(Self {
rw,
should_quit: false,
game: GameState::default(),
res: Res::load()?,
sf_egui,
kb_input: KbInput::default(),
debug: DebugState::default(),
})
}
pub fn do_game_loop(&mut self) {
while !self.should_quit {
self.do_event_handling();
self.do_update();
self.do_rendering();
self.kb_input.clear_pressed();
gamedebug_core::inc_frame();
}
}
fn do_event_handling(&mut self) {
while let Some(ev) = self.rw.poll_event() {
self.sf_egui.add_event(&ev);
self.kb_input.update_from_event(&ev);
match ev {
Event::Closed => self.should_quit = true,
_ => {}
}
}
}
fn do_update(&mut self) {
self.debug.update(&self.kb_input);
if self.debug.freecam {
self.do_freecam();
} else {
let spd = if self.kb_input.down(Key::LShift) {
16.0
} else if self.kb_input.down(Key::LControl) {
256.0
} else {
4.0
};
if self.kb_input.down(Key::Left) {
self.game.player.col_en.move_x(-spd, |_, _| false);
}
if self.kb_input.down(Key::Right) {
self.game.player.col_en.move_x(spd, |_, _| false);
}
if self.kb_input.down(Key::Up) {
self.game.player.col_en.move_y(-spd, |_, _| false);
}
if self.kb_input.down(Key::Down) {
self.game.player.col_en.move_y(spd, |_, _| false);
}
let (x, y, _w, _h) = self.game.player.col_en.en.xywh();
self.game.camera_offset.x = (x - NATIVE_RESOLUTION.w as i32 / 2) as u32;
self.game.camera_offset.y = (y - NATIVE_RESOLUTION.h as i32 / 2) as u32;
}
}
fn do_freecam(&mut self) {
let spd = if self.kb_input.down(Key::LShift) {
100
} else if self.kb_input.down(Key::LControl) {
1000
} else {
2
};
if self.kb_input.down(Key::Left) {
self.game.camera_offset.x = self.game.camera_offset.x.saturating_sub(spd);
}
if self.kb_input.down(Key::Right) {
self.game.camera_offset.x = self.game.camera_offset.x.saturating_add(spd);
}
if self.kb_input.down(Key::Up) {
self.game.camera_offset.y = self.game.camera_offset.y.saturating_sub(spd);
}
if self.kb_input.down(Key::Down) {
self.game.camera_offset.y = self.game.camera_offset.y.saturating_add(spd);
}
}
fn do_rendering(&mut self) {
self.rw.clear(Color::rgb(55, 221, 231));
self.game.draw_world(&mut self.rw, &self.res);
self.game.draw_entities(&mut self.rw);
self.sf_egui
.do_frame(|ctx| {
if self.debug.panel {
debug_panel_ui(&mut self.debug, &mut self.game, ctx);
}
})
.unwrap();
self.sf_egui.draw(&mut self.rw, None);
self.rw.display();
}
}
fn debug_panel_ui(debug: &mut DebugState, game: &mut GameState, ctx: &egui::Context) {
egui::Window::new("Debug (F12)").show(ctx, |ui| {
ui.label("Cam x");
ui.add(egui::DragValue::new(&mut game.camera_offset.x));
ui.label("Cam y");
ui.add(egui::DragValue::new(&mut game.camera_offset.y));
if debug.freecam {
let tp = game.camera_offset.tile_pos();
imm_dbg!(tp);
ui.label(format!(
"Cam Depth: {}",
LengthDisp(tp.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64)
));
ui.label(format!(
"Cam offset from center: {}",
LengthDisp(tp.x as i64 - wp_to_tp(WorldPos::CENTER) as i64)
));
} else {
let tp = game.player.center_tp();
imm_dbg!(tp);
ui.label(format!(
"Player Depth: {}",
LengthDisp(tp.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64)
));
ui.label(format!(
"Player offset from center: {}",
LengthDisp(tp.x as i64 - wp_to_tp(WorldPos::CENTER) as i64)
));
}
ui.separator();
egui::ScrollArea::vertical().show(ui, |ui| {
gamedebug_core::for_each_imm(|info| match info {
gamedebug_core::Info::Msg(msg) => {
ui.label(msg);
}
gamedebug_core::Info::Rect(_, _, _, _, _) => todo!(),
});
});
gamedebug_core::clear_immediates();
});
}
struct LengthDisp(i64);
impl fmt::Display for LengthDisp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let km = self.0 / 1000;
let m = self.0 % 1000;
write!(f, "{km} km, {m} m")
}
}