From d27cbceb9933be29aa46a442b08b79a54caaecbc Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 24 Feb 2023 16:57:36 +0100 Subject: [PATCH] Updated render engine to use a 3D grid --- src/screens/build.rs | 133 +++++++++++++++++++++++++++++-------------- src/types.rs | 19 +++++-- 2 files changed, 105 insertions(+), 47 deletions(-) diff --git a/src/screens/build.rs b/src/screens/build.rs index 28d81b1..02fa2b0 100644 --- a/src/screens/build.rs +++ b/src/screens/build.rs @@ -4,7 +4,7 @@ use crate::textures::AssetStore; use crate::types::{ GameComponent, GameEvent, - Pos2 + Pos3 }; use crate::blocks::Block; @@ -21,72 +21,121 @@ impl Camera { } } +const TARGET_RENDER_SIZE:f32 = 128.0; + +/// image width +const TEXTURE_WIDTH: f32 = 256.0; +/// actual width inside ob cube +const TEXTURE_INNER_WIDTH: f32 = 223.0; // 216 +/// height of image +const TEXTURE_HEIGHT: f32 = 352.0; +/// actual height of cube +const TEXTURE_INNER_HEIGHT: f32 = 108.0; // 110 + pub struct BuildScreen { - grid: HashMap, - cam: Camera + grid: HashMap, + cam: Camera, + mouse_down: bool } impl BuildScreen { pub fn new() -> Self { let mut this = Self { grid: HashMap::new(), - cam: Camera::new() + cam: Camera::new(), + mouse_down: false }; - this.grid.insert(Pos2::new(0, 0), Block::Dirt(crate::types::Direction::North)); - this.grid.insert(Pos2::new(0, 1), Block::Dirt(crate::types::Direction::North)); + this.grid.insert(Pos3::new(0, 0, 0), Block::Dirt(crate::types::Direction::North)); this } } + impl GameComponent for BuildScreen { fn draw(&self, assets: &AssetStore) { - for (pos, block) in self.grid.iter() { + // order: x (inc) -> y (inc) -> z (inc) + let mut render_order: Vec<(&Pos3, &Block)> = self.grid.iter().collect(); + render_order.sort_by_key(|(pos, _)| pos.x + pos.y*2 + pos.z*3 ); + + for (pos, block) in render_order.iter() { let texture = block.get_texture(&assets); - let size = 128.0 * self.cam.scale; + let w_i = TEXTURE_INNER_WIDTH * self.cam.scale; + let width = TEXTURE_WIDTH * self.cam.scale; + let height = TEXTURE_HEIGHT * self.cam.scale; + let h_i = TEXTURE_INNER_HEIGHT * self.cam.scale; + + let dx = pos.y - pos.x; + let dy = pos.y + pos.x; + let x = screen_width() / 2.0 - + pos.x as f32 * size - + self.cam.center.x * size; + + dx as f32 * w_i / 2.0 + + self.cam.center.x + - width / 2.0; let y = screen_height() / 2.0 - + pos.y as f32 * (size / 3.0) - + self.cam.center.y * size; - - if x >= -size && x <= screen_width() - && y >= -size && y <= screen_height() { - // render block - // TODO: render blocks in order: - // - from front to back - // - from bottom to top - draw_texture_ex( - texture, - x, - y, - WHITE, - DrawTextureParams { - dest_size: Some(Vec2::new(size, size)), - source: None, - rotation: 0.0, - flip_x: false, - flip_y: false, - pivot: None - }); + + dy as f32 * h_i / 2.0 + - pos.z as f32 * h_i + + self.cam.center.y + - height / 2.0; - } - } + if x >= -width && x <= screen_width() + && y >= -width && y <= screen_height() { + // render block + draw_texture_ex( + texture, + x, + y, + WHITE, + DrawTextureParams { + dest_size: Some(Vec2::new(width, height)), + source: None, + rotation: 0.0, + flip_x: false, + flip_y: false, + pivot: None + }); + + } + } } fn ev_loop(&mut self) -> GameEvent { + // mouse input + if is_mouse_button_down(MouseButton::Left) { + // currently holding button down + self.mouse_down = true; + } else if self.mouse_down { + // button was released + self.mouse_down = false; + // TODO: determine which block / side was clicked + let (mx, my) = mouse_position(); - if is_key_down(KeyCode::Up) { - self.cam.center.y -= 0.1; + let size = TARGET_RENDER_SIZE * self.cam.scale; } -if is_key_down(KeyCode::Down) { - self.cam.center.y += 0.1; + + // zoom with Ctrl-MouseWheel + if is_key_down(KeyCode::LeftControl) { + let mut scale = self.cam.scale; + let (_, wy) = mouse_wheel(); + + scale += wy as f32 * 1.0/10.0; + + if scale > 0.05 && scale < 6.0 { + self.cam.scale = scale; + } + } + + // keyboard control + if is_key_down(KeyCode::Down) { + self.cam.center.y += 1.0 * (1.0/self.cam.scale); + } + if is_key_down(KeyCode::Up) { + self.cam.center.y -= 1.0 * (1.0/self.cam.scale); } -if is_key_down(KeyCode::Left) { - self.cam.center.x -= 0.1; + if is_key_down(KeyCode::Left) { + self.cam.center.x -= 1.0 * (1.0/self.cam.scale); } -if is_key_down(KeyCode::Right) { - self.cam.center.x += 0.1; + if is_key_down(KeyCode::Right) { + self.cam.center.x += 1.0 * (1.0/self.cam.scale); } GameEvent::None diff --git a/src/types.rs b/src/types.rs index cbfea56..423d742 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,16 +1,25 @@ use crate::textures::AssetStore; use crate::Screen; +/// three dimensional coordinate +/// z +/// | +/// |__ y +/// / +/// / +/// x #[derive(Debug,Eq,Hash,PartialEq)] -pub struct Pos2 { +pub struct Pos3 { pub x: isize, - pub y: isize + pub y: isize, + pub z: isize } -impl Pos2 { - pub fn new(x: isize, y: isize) -> Self { +impl Pos3 { + pub fn new(x: isize, y: isize, z: isize) -> Self { Self { x, - y + y, + z } } } -- 2.38.5