|
- #![allow(unused_imports)]
-
- // mods
- mod util;
- mod world;
-
- // namespacing
- use ggez::{
- conf::{WindowMode, WindowSetup},
- event::{self, EventHandler, KeyCode, KeyMods},
- graphics, Context, ContextBuilder, GameResult,
- };
- use std::collections::VecDeque;
- use world::World;
-
- /// lazy result type
- pub type Result<T> = std::result::Result<T, Error>;
-
- // error types
- #[derive(Debug, thiserror::Error)]
- pub enum Error {
- // external errors
- #[error(transparent)]
- Stdio(#[from] std::io::Error),
- #[error(transparent)]
- Toml(#[from] toml::de::Error),
- #[error(transparent)]
- Ggez(#[from] ggez::error::GameError),
- // internal errors
- #[error("could not find {expected} MasterTile on TileBuilder")]
- NoMasterTile { expected: String },
- }
-
- // primary game state
- pub struct MainState {
- world: World,
- action_buffer: Vec<Box<dyn Action>>,
- action_history: VecDeque<Box<dyn Action>>,
- action_history_max_length: usize,
- }
-
- impl MainState {
- // create a new gamestate
- pub fn new(ctx: &mut Context) -> Result<MainState> {
- let world = World::new(ctx, "/data/tile_conf.toml".into(), 20, 20, 1)?;
- Ok(MainState {
- world,
- action_history_max_length: 100,
- action_history: VecDeque::new(),
- action_buffer: Vec::new(),
- })
- }
- }
-
- impl EventHandler for MainState {
- fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
- // check through the input buffer
- while let Some(action) = self.action_buffer.pop() {
- action.execute(ctx, self).expect("failed to execute action");
-
- if self.action_history.len() < self.action_history_max_length {
- self.action_history.push_back(action);
- } else {
- self.action_history.pop_front();
- self.action_history.push_back(action);
- }
- }
-
- Ok(())
- }
-
- fn key_down_event(
- &mut self,
- _ctx: &mut Context,
- key_code: KeyCode,
- _keymods: KeyMods,
- repeat: bool,
- ) {
- use world::{OffsetAction, ZoomAction};
-
- if !repeat {
- let action_maybe: Option<Box<dyn Action>> = match key_code {
- // movement key codes
- KeyCode::Up => Some(Box::new(OffsetAction::new([0.0, 1.0].into()))),
- KeyCode::Down => Some(Box::new(OffsetAction::new([0.0, -1.0].into()))),
- KeyCode::Left => Some(Box::new(OffsetAction::new([1.0, 0.0].into()))),
- KeyCode::Right => Some(Box::new(OffsetAction::new([-1.0, 0.0].into()))),
-
- // zoom key codes
- KeyCode::Equals => Some(Box::new(ZoomAction::new([0.1, 0.1].into()))),
- KeyCode::Minus => Some(Box::new(ZoomAction::new([-0.1, -0.1].into()))),
-
- // if escape, quit program (for now)
- // !! isabelle please remove this eventually
- KeyCode::Escape => Some(Box::new(QuitAction::new())),
-
- // ignore all other key codes
- _ => None,
- };
-
- if let Some(action) = action_maybe {
- self.action_buffer.push(action);
- }
- }
- }
-
- fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
- // clear the screen
- graphics::clear(ctx, graphics::BLACK);
-
- self.world.render(ctx).expect("failed to render");
-
- // render the context
- graphics::present(ctx)
- }
- }
-
- trait Action: std::fmt::Debug {
- fn execute(&self, ctx: &mut Context, state: &mut MainState) -> Result<()>;
- fn undo(&self, ctx: &mut Context, state: &mut MainState) -> Result<()>;
- }
-
- /// struct to wrap quitting the game
- #[derive(Debug)]
- struct QuitAction;
-
- impl QuitAction {
- fn new() -> QuitAction {
- QuitAction
- }
- }
-
- impl Action for QuitAction {
- fn execute(&self, ctx: &mut Context, _state: &mut MainState) -> Result<()> {
- event::quit(ctx);
- Ok(())
- }
- fn undo(&self, _ctx: &mut Context, _state: &mut MainState) -> Result<()> {
- unreachable!()
- }
- }
-
- fn main_wrapper() -> Result<()> {
- let win_mode = WindowMode {
- width: 1024.0,
- height: 768.0,
- ..Default::default()
- };
-
- let win_setup = WindowSetup {
- title: "unnamed game thinger".to_owned(),
- ..Default::default()
- };
-
- let cb = ContextBuilder::new("unnamed", "Isabelle L.")
- .add_resource_path("./")
- .window_mode(win_mode)
- .window_setup(win_setup);
- let (mut ctx, mut event_loop) = cb.build()?;
- let mut state = MainState::new(&mut ctx)?;
-
- event::run(&mut ctx, &mut event_loop, &mut state)?;
- Ok(())
- }
-
- fn main() {
- if let Err(err) = main_wrapper() {
- panic!("err occured: {:?}", err);
- }
- }
|