|
@@ -7,9 +7,10 @@ mod world; |
|
|
// namespacing |
|
|
// namespacing |
|
|
use ggez::{ |
|
|
use ggez::{ |
|
|
conf::{WindowMode, WindowSetup}, |
|
|
conf::{WindowMode, WindowSetup}, |
|
|
event::{self, EventHandler}, |
|
|
|
|
|
|
|
|
event::{self, EventHandler, KeyCode, KeyMods}, |
|
|
graphics, Context, ContextBuilder, GameResult, |
|
|
graphics, Context, ContextBuilder, GameResult, |
|
|
}; |
|
|
}; |
|
|
|
|
|
use std::collections::VecDeque; |
|
|
use world::World; |
|
|
use world::World; |
|
|
|
|
|
|
|
|
/// lazy result type |
|
|
/// lazy result type |
|
@@ -31,25 +32,78 @@ pub enum Error { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// primary game state |
|
|
// primary game state |
|
|
struct MainState { |
|
|
|
|
|
|
|
|
pub struct MainState { |
|
|
world: World, |
|
|
world: World, |
|
|
|
|
|
action_buffer: Vec<Box<dyn Action>>, |
|
|
|
|
|
action_history: VecDeque<Box<dyn Action>>, |
|
|
|
|
|
action_history_max_length: usize, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
impl MainState { |
|
|
impl MainState { |
|
|
// create a new gamestate |
|
|
// create a new gamestate |
|
|
pub fn new(ctx: &mut Context) -> MainState { |
|
|
|
|
|
MainState { |
|
|
|
|
|
world: World::new(ctx, "/data/tile_conf.toml".into(), 20, 20, 1) |
|
|
|
|
|
.expect("failed init world"), |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
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 { |
|
|
impl EventHandler for MainState { |
|
|
fn update(&mut self, _ctx: &mut Context) -> GameResult<()> { |
|
|
|
|
|
|
|
|
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(()) |
|
|
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<()> { |
|
|
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> { |
|
|
// clear the screen |
|
|
// clear the screen |
|
|
graphics::clear(ctx, graphics::BLACK); |
|
|
graphics::clear(ctx, graphics::BLACK); |
|
@@ -61,24 +115,56 @@ impl EventHandler for MainState { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fn main() { |
|
|
|
|
|
|
|
|
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 { |
|
|
let win_mode = WindowMode { |
|
|
width: 1024.0, |
|
|
width: 1024.0, |
|
|
height: 768.0, |
|
|
height: 768.0, |
|
|
..Default::default() |
|
|
..Default::default() |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
let win_setup = WindowSetup { |
|
|
let win_setup = WindowSetup { |
|
|
title: "unnamed game thinger".to_owned(), |
|
|
title: "unnamed game thinger".to_owned(), |
|
|
..Default::default() |
|
|
..Default::default() |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
let cb = ContextBuilder::new("unnamed", "Isabelle L.") |
|
|
let cb = ContextBuilder::new("unnamed", "Isabelle L.") |
|
|
.add_resource_path("./") |
|
|
.add_resource_path("./") |
|
|
.window_mode(win_mode) |
|
|
.window_mode(win_mode) |
|
|
.window_setup(win_setup); |
|
|
.window_setup(win_setup); |
|
|
let (mut ctx, mut event_loop) = cb.build().expect("failed to start context"); |
|
|
|
|
|
let mut state = MainState::new(&mut ctx); |
|
|
|
|
|
|
|
|
let (mut ctx, mut event_loop) = cb.build()?; |
|
|
|
|
|
let mut state = MainState::new(&mut ctx)?; |
|
|
|
|
|
|
|
|
if let Err(err) = event::run(&mut ctx, &mut event_loop, &mut state) { |
|
|
|
|
|
eprintln!("an error occured: {:?}", err); |
|
|
|
|
|
|
|
|
event::run(&mut ctx, &mut event_loop, &mut state)?; |
|
|
|
|
|
Ok(()) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn main() { |
|
|
|
|
|
if let Err(err) = main_wrapper() { |
|
|
|
|
|
panic!("err occured: {:?}", err); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |