From 6be25370c4dfd735558e3989bc24143ae7eb5d6c Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Sat, 25 Feb 2023 11:24:10 +0100 Subject: [PATCH] Added ability to destroy blocks using mouse RightClick --- src/screens/build.rs | 178 ++++++++++++++++++++++----------------- src/screens/inventory.rs | 9 ++ 2 files changed, 112 insertions(+), 75 deletions(-) diff --git a/src/screens/build.rs b/src/screens/build.rs index dd00301..3c31893 100644 --- a/src/screens/build.rs +++ b/src/screens/build.rs @@ -43,7 +43,8 @@ const TEXTURE_DEPTH: f32 = 100.0; pub struct BuildScreen { grid: HashMap, 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) { diff --git a/src/screens/inventory.rs b/src/screens/inventory.rs index 3b0e900..af0a5ae 100644 --- a/src/screens/inventory.rs +++ b/src/screens/inventory.rs @@ -55,6 +55,15 @@ impl Inventory { is_mouse_down: false } } + /// adds a block to the players inventory + pub fn add(&mut self, block: Block) { + if !self.infinite_items { + *self.contents.get_mut(&block).unwrap_or(&mut 0)+=1; + } + } + /// removes the selected block (one) from the inventory + /// can be used to remove items + /// or place items pub fn place(&mut self) -> Option { if let Some(block) = &self.selected { -- 2.38.5