@@ 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<Pos2, Block>,
- cam: Camera
+ grid: HashMap<Pos3, Block>,
+ 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
@@ 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
}
}
}