From ff0208fd1815ba330b1a59e05e44dd2bda4c880c Mon Sep 17 00:00:00 2001 From: Isabelle L Date: Fri, 10 Jul 2020 21:06:55 -0500 Subject: [PATCH] some refactor shit --- src/main.rs | 54 +++++++++++++++++++++++++---------------- src/util.rs | 17 +++++++++++++ src/world.rs | 58 +++----------------------------------------- src/world/actions.rs | 57 +++++++++++++++++++++++++++++++++++++++++++ src/world/tile.rs | 13 +++++++--- 5 files changed, 121 insertions(+), 78 deletions(-) create mode 100644 src/world/actions.rs diff --git a/src/main.rs b/src/main.rs index 2df705b..36aced3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,28 +11,12 @@ use ggez::{ graphics, Context, ContextBuilder, GameResult, }; use std::collections::VecDeque; +pub use util::{Error, Result}; use world::World; -/// lazy result type -pub type Result = std::result::Result; - -// 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 { +struct MainState { + debug_mode: bool, world: World, action_buffer: Vec>, action_history: VecDeque>, @@ -45,6 +29,7 @@ impl MainState { let world = World::new(ctx, "/data/tile_conf.toml".into(), 20, 20, 1)?; Ok(MainState { world, + debug_mode: true, action_history_max_length: 100, action_history: VecDeque::new(), action_buffer: Vec::new(), @@ -56,7 +41,13 @@ 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.debug_mode { + action + .execute_debug(ctx, self) + .expect("fialed to execute action"); + } else { + 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); @@ -69,6 +60,17 @@ impl EventHandler for MainState { Ok(()) } + fn mouse_wheel_event(&mut self, _ctx: &mut Context, _x: f32, y: f32) { + use world::ZoomAction; + if y > 0.0 { + self.action_buffer + .push(Box::new(ZoomAction::new([0.1, 0.1].into()))); + } else if y < 0.0 { + self.action_buffer + .push(Box::new(ZoomAction::new([-0.1, -0.1].into()))); + } + } + fn key_down_event( &mut self, _ctx: &mut Context, @@ -88,7 +90,7 @@ impl EventHandler for MainState { // 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()))), + KeyCode::Subtract => Some(Box::new(ZoomAction::new([-0.1, -0.1].into()))), // if escape, quit program (for now) // !! isabelle please remove this eventually @@ -118,6 +120,16 @@ impl EventHandler for MainState { 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<()>; + + fn execute_debug(&self, ctx: &mut Context, state: &mut MainState) -> Result<()> { + println!("executing: {:?}", self); + self.execute(ctx, state) + } + + fn undo_debug(&self, ctx: &mut Context, state: &mut MainState) -> Result<()> { + println!("undoing: {:?}", self); + self.execute(ctx, state) + } } /// struct to wrap quitting the game diff --git a/src/util.rs b/src/util.rs index 0781d21..788115d 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,22 @@ use mint::Point2; +/// lazy result type +pub type Result = std::result::Result; + +// 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 }, +} pub struct IsometricVector2(Point2); impl IsometricVector2 { diff --git a/src/world.rs b/src/world.rs index 6ec70ba..38fcb91 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,8 +1,10 @@ // modules +mod actions; mod tile; // namespacing use crate::{util::*, MainState, Result}; +pub use actions::*; use ggez::{ graphics::{self, DrawParam}, Context, @@ -34,7 +36,7 @@ impl World { let builder = TileBuilder::new(ctx, tile_config)?; let mut data: HashMap, Tile> = HashMap::new(); let offset: Point2 = [350.0f32, 100.0f32].into(); - let zoom: Vector2 = [1.0f32, 1.0f32].into(); + let zoom: Vector2 = [2.0f32, 2.0f32].into(); for x in 0..width { for y in 0..depth { @@ -49,7 +51,7 @@ impl World { height, depth, data, - builder: builder, + builder, offset, zoom, }) @@ -82,55 +84,3 @@ impl World { Ok(()) } } - -/// action struct for wrapping offsetting input -#[derive(Debug)] -pub struct OffsetAction(Vector2); - -impl OffsetAction { - /// construct a new offset action - pub fn new(offset: Vector2) -> OffsetAction { - OffsetAction(offset) - } -} - -impl crate::Action for OffsetAction { - fn execute(&self, _ctx: &mut Context, state: &mut MainState) -> Result<()> { - state.world.offset.x = - self.0.x * (state.world.builder.tile_width() / 2.0) + state.world.offset.x; - state.world.offset.y = - self.0.y * (state.world.builder.tile_height() / 2.0) + state.world.offset.y; - Ok(()) - } - - fn undo(&self, _ctx: &mut Context, state: &mut MainState) -> Result<()> { - state.world.offset.x = state.world.offset.x - self.0.x; - state.world.offset.y = state.world.offset.y - self.0.y; - Ok(()) - } -} - -/// action struct for wrapping zoom input -#[derive(Debug)] -pub struct ZoomAction(Vector2); - -impl ZoomAction { - /// construct a new scale action - pub fn new(scale: Vector2) -> ZoomAction { - ZoomAction(scale) - } -} - -impl crate::Action for ZoomAction { - fn execute(&self, _ctx: &mut Context, state: &mut MainState) -> Result<()> { - state.world.zoom.x = self.0.x + state.world.zoom.x; - state.world.zoom.y = self.0.y + state.world.zoom.y; - Ok(()) - } - - fn undo(&self, _ctx: &mut Context, state: &mut MainState) -> Result<()> { - state.world.zoom.x = state.world.zoom.x - self.0.x; - state.world.zoom.y = state.world.zoom.y - self.0.y; - Ok(()) - } -} diff --git a/src/world/actions.rs b/src/world/actions.rs new file mode 100644 index 0000000..5a4ac50 --- /dev/null +++ b/src/world/actions.rs @@ -0,0 +1,57 @@ +use crate::{MainState, Result}; +use ggez::Context; +use mint::Vector2; + +/// action struct for wrapping offsetting input +#[derive(Debug)] +pub struct OffsetAction(Vector2); + +impl OffsetAction { + /// construct a new offset action + pub fn new(offset: Vector2) -> OffsetAction { + OffsetAction(offset) + } +} + +impl crate::Action for OffsetAction { + fn execute(&self, _ctx: &mut Context, state: &mut MainState) -> Result<()> { + let x: f32 = self.0.x * (state.world.builder.tile_width() / 2.0) + state.world.offset.x; + let y: f32 = self.0.y * (state.world.builder.tile_height() / 2.0) + state.world.offset.y; + state.world.offset = [x, y].into(); + Ok(()) + } + + fn undo(&self, _ctx: &mut Context, state: &mut MainState) -> Result<()> { + let x: f32 = state.world.offset.x - self.0.x * (state.world.builder.tile_width() / 2.0); + let y: f32 = state.world.offset.y - self.0.y * (state.world.builder.tile_height() / 2.0); + state.world.offset = [x, y].into(); + Ok(()) + } +} + +/// action struct for wrapping zoom input +#[derive(Debug)] +pub struct ZoomAction(Vector2); + +impl ZoomAction { + /// construct a new scale action + pub fn new(scale: Vector2) -> ZoomAction { + ZoomAction(scale) + } +} + +impl crate::Action for ZoomAction { + fn execute(&self, _ctx: &mut Context, state: &mut MainState) -> Result<()> { + let x: f32 = state.world.zoom.x + (self.0.x * (state.world.builder.tile_width() / 2.0)); + let y: f32 = state.world.zoom.y + (self.0.y * (state.world.builder.tile_height() / 2.0)); + state.world.zoom = [x, y].into(); + Ok(()) + } + + fn undo(&self, _ctx: &mut Context, state: &mut MainState) -> Result<()> { + let x: f32 = state.world.zoom.x - self.0.x * (state.world.builder.tile_width() / 2.0); + let y: f32 = state.world.zoom.y - self.0.y * (state.world.builder.tile_height() / 2.0); + state.world.zoom = [x, y].into(); + Ok(()) + } +} diff --git a/src/world/tile.rs b/src/world/tile.rs index e73e24b..cada39c 100644 --- a/src/world/tile.rs +++ b/src/world/tile.rs @@ -1,5 +1,8 @@ use crate::{Error, Result}; -use ggez::{graphics::Image, Context}; +use ggez::{ + graphics::{FilterMode, Image}, + Context, +}; use mint::Vector2; use serde::Deserialize; use std::io::Read; @@ -34,7 +37,11 @@ impl TileBuilder { raw_map.iter().for_each(|(kind, raw_tile)| { let tile = MasterTile { - texture: Rc::new(Image::new(ctx, &raw_tile.path).expect("failed to load image")), + texture: Rc::new({ + let mut image = Image::new(ctx, &raw_tile.path).expect("failed to load image"); + image.set_filter(FilterMode::Nearest); + image + }), kind: kind.to_owned(), blocking: raw_tile.blocking, }; @@ -42,7 +49,7 @@ impl TileBuilder { }); Ok(TileBuilder { - textures: textures, + textures, tile_dimensions, }) }