|
- // modules
- mod tile;
-
- // namespacing
- use crate::{util::*, MainState, Result};
- use ggez::{
- graphics::{self, DrawParam},
- Context,
- };
- use mint::{Point2, Vector2, Vector3};
- use std::{collections::HashMap, path::PathBuf};
- use tile::*;
-
- /// represent a whole rendered world
- pub struct World {
- width: isize,
- depth: isize,
- height: isize,
- data: HashMap<Vector3<isize>, Tile>,
- builder: TileBuilder,
- offset: Point2<f32>,
- zoom: Vector2<f32>,
- }
-
- impl World {
- /// create a new world instance
- pub fn new(
- ctx: &mut Context,
- tile_config: PathBuf,
- width: isize,
- depth: isize,
- height: isize,
- ) -> Result<World> {
- let builder = TileBuilder::new(ctx, tile_config)?;
- let mut data: HashMap<Vector3<isize>, Tile> = HashMap::new();
- let offset: Point2<f32> = [350.0f32, 100.0f32].into();
- let zoom: Vector2<f32> = [1.0f32, 1.0f32].into();
-
- for x in 0..width {
- for y in 0..depth {
- for z in 0..height {
- data.insert([x, y, z].into(), builder.build("nothing".to_owned())?);
- }
- }
- }
-
- Ok(World {
- width,
- height,
- depth,
- data,
- builder: builder,
- offset,
- zoom,
- })
- }
-
- /// renders the world to the window
- pub fn render(&self, ctx: &mut Context) -> Result<()> {
- for x in 0..self.width {
- for y in 0..self.depth {
- for z in 0..self.height {
- let tile = self.data.get(&[x, y, z].into()).unwrap();
- let iso_coord: IsometricVector2 = Point2::from([x as f32, y as f32]).into();
- let scale = [self.zoom.x, self.zoom.y];
- let dest = [
- iso_coord.x() * (self.builder.tile_width() / 2.0) * scale[0]
- + self.offset.x,
- iso_coord.y() * (self.builder.tile_height() / 2.0) * scale[1]
- + self.offset.y,
- ];
-
- let param = DrawParam::default()
- .dest(Point2::from_slice(&dest))
- .scale(Point2::from_slice(&scale));
-
- graphics::draw(ctx, tile.texture(), param)?;
- }
- }
- }
-
- Ok(())
- }
- }
-
- /// action struct for wrapping offsetting input
- #[derive(Debug)]
- pub struct OffsetAction(Vector2<f32>);
-
- impl OffsetAction {
- /// construct a new offset action
- pub fn new(offset: Vector2<f32>) -> 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<f32>);
-
- impl ZoomAction {
- /// construct a new scale action
- pub fn new(scale: Vector2<f32>) -> 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(())
- }
- }
|