@@ 43,7 43,8 @@ const TEXTURE_DEPTH: f32 = 100.0;
pub struct BuildScreen {
grid: HashMap<Pos3, (Block, Direction)>,
cam: Camera,
- mouse_down: bool,
+ mouse_left_down: bool,
+ mouse_right_down: bool,
show_inv: bool,
inv: Inventory
}
@@ 52,7 53,8 @@ impl BuildScreen {
let mut this = Self {
grid: HashMap::new(),
cam: Camera::new(),
- mouse_down: false,
+ mouse_left_down: false,
+ mouse_right_down: false,
show_inv: false,
inv: Inventory::new()
};
@@ 65,22 67,22 @@ impl BuildScreen {
fn get_screen_coords(pos: &Pos3, scale: f32, center: Vec2) -> (f32, f32) {
let w_i = TEXTURE_INNER_WIDTH * scale;
- let width = TEXTURE_WIDTH * scale;
- let height = TEXTURE_HEIGHT * scale;
- let h_i = TEXTURE_INNER_HEIGHT * scale;
-
- let dx = pos.y - pos.x;
- let dy = pos.y + pos.x;
-
- let x = screen_width() / 2.0
- + dx as f32 * w_i / 2.0
- + center.x
- - width / 2.0;
- let y = screen_height() / 2.0
- + dy as f32 * h_i / 2.0
- - pos.z as f32 * h_i
- + center.y
- - height / 2.0;
+ let width = TEXTURE_WIDTH * scale;
+ let height = TEXTURE_HEIGHT * scale;
+ let h_i = TEXTURE_INNER_HEIGHT * scale;
+
+ let dx = pos.y - pos.x;
+ let dy = pos.y + pos.x;
+
+ let x = screen_width() / 2.0
+ + dx as f32 * w_i / 2.0
+ + center.x
+ - width / 2.0;
+ let y = screen_height() / 2.0
+ + dy as f32 * h_i / 2.0
+ - pos.z as f32 * h_i
+ + center.y
+ - height / 2.0;
return (x,y);
}
@@ 207,68 209,94 @@ impl GameComponent for BuildScreen {
// 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;
- // determine which block / side was clicked
- let (mx, my) = mouse_position();
-
- // virtual render cycle
- let render_order: Vec<(&Pos3, &(Block, Direction))> = self.grid.iter().collect();
-
- // list of positions in render que for given pixel
- // (mx, my)
- let mut in_path:Vec<&Pos3> = Vec::new();
-
- for (pos, _) in render_order.iter() {
- let (x,y) = get_screen_coords(pos, self.cam.scale, self.cam.center);
-
- if mx >= x
- && mx <= x + TEXTURE_WIDTH * self.cam.scale
- && my >= y + TEXTURE_Y_WHITESPACE * self.cam.scale
- && my <= y + TEXTURE_HEIGHT * self.cam.scale {
-
- // check if mouse is above transparent area
- // and skip block if necessary
- if Face::from_xy(mx-x, my-y, self.cam.scale).is_none() {
- println!("skipping");
- continue;
- }
+ self.mouse_left_down = true;
+ }
+ if is_mouse_button_down(MouseButton::Right) {
+ self.mouse_right_down = true;
+ }
- // block in mouse path
- in_path.push(pos);
- }
- }
- // weight axis
- in_path.sort_by_key(|pos| pos.x + pos.y*2 + pos.z*3 );
- if let Some(pos) = in_path.last() {
- // position of clicked block
- // because it is the last block in de render queue
- // for a given pixel
- let mut pos = Pos3::new(pos.x, pos.y, pos.z);
- let (x,y) = get_screen_coords(&pos, self.cam.scale, self.cam.center);
- let face = Face::from_xy(mx-x, my-y, self.cam.scale);
-
- match face.unwrap() {
- Face::Top => {
- pos.z+=1;
- },
- Face::Left => {
- pos.x+=1;
- },
- Face::Right => {
- pos.y+=1;
- }
- }
+ if (self.mouse_left_down && !is_mouse_button_down(MouseButton::Left))
+ || (self.mouse_right_down && !is_mouse_button_down(MouseButton::Right)) {
+
+ // determine which block / side was clicked
+ let (mx, my) = mouse_position();
+
+ // virtual render cycle
+ let render_order: Vec<(&Pos3, &(Block, Direction))> = self.grid.iter().collect();
+
+ // list of positions in render que for given pixel
+ // (mx, my)
+ let mut in_path:Vec<&Pos3> = Vec::new();
+
+ for (pos, _) in render_order.iter() {
+ let (x,y) = get_screen_coords(pos, self.cam.scale, self.cam.center);
- if let Some(block) = self.inv.place() {
- self.grid.insert(pos, (block, self.inv.direction.clone()));
+ if mx >= x
+ && mx <= x + TEXTURE_WIDTH * self.cam.scale
+ && my >= y + TEXTURE_Y_WHITESPACE * self.cam.scale
+ && my <= y + TEXTURE_HEIGHT * self.cam.scale {
+
+ // check if mouse is above transparent area
+ // and skip block if necessary
+ if Face::from_xy(mx-x, my-y, self.cam.scale).is_none() {
+ continue;
+ }
+
+ // block in mouse path
+ in_path.push(pos);
+ }
}
+ // weight axis
+ in_path.sort_by_key(|pos| pos.x + pos.y*2 + pos.z*3 );
+ if let Some(pos) = in_path.last() {
+ // position of clicked block
+ // because it is the last block in de render queue
+ // for a given pixel
+ let mut pos = Pos3::new(pos.x, pos.y, pos.z);
+
+ if self.mouse_right_down && !is_mouse_button_down(MouseButton::Right) {
+ // released right click
+ self.mouse_right_down = false;
+
+ // if grid has only one block
+ // the block can not be removed
+ // because the palyer would not be able to place
+ // new blocks if no block exists
+ if self.grid.len() > 1 {
+
+ // destroy block
+ if let Some((block, _)) = self.grid.remove(&pos) {
+ self.inv.add(block);
+ }
+ }
+ }
+ if self.mouse_left_down && !is_mouse_button_down(MouseButton::Left) {
+ // released left click
+ self.mouse_left_down = false;
+
+ // place block
+ let (x,y) = get_screen_coords(&pos, self.cam.scale, self.cam.center);
+ let face = Face::from_xy(mx-x, my-y, self.cam.scale);
+
+ match face.unwrap() {
+ Face::Top => {
+ pos.z+=1;
+ },
+ Face::Left => {
+ pos.x+=1;
+ },
+ Face::Right => {
+ pos.y+=1;
+ }
+ }
+
+ if let Some(block) = self.inv.place() {
+ self.grid.insert(pos, (block, self.inv.direction.clone()));
+ }
+ }
+ }
}
- }
// zoom with Ctrl-MouseWheel
if is_key_down(KeyCode::LeftControl) {