add digit tool

This commit is contained in:
Crispy 2024-10-05 20:22:18 +02:00
parent 465b5c40d1
commit fc6c66ff31
5 changed files with 130 additions and 65 deletions

BIN
assets/digit_tool.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

After

Width:  |  Height:  |  Size: 116 B

View file

@ -1,7 +1,7 @@
use std::{fs::read_to_string, ops::Rem};
use marble_engine::{
board::Board,
board::{Board, Pos},
tile::{Direction, GateType, MathOp, MirrorType, PTile, Tile, WireType},
Machine,
};
@ -31,16 +31,16 @@ struct Game {
time_since_step: f32,
}
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone)]
enum Tool {
None,
SetTile(Tile),
Digits(Option<Pos>),
Math,
Gate,
Wire,
Arrow,
Mirror,
Number,
// SelectArea,
}
@ -149,7 +149,7 @@ impl Game {
}
Tool::None => (),
Tool::SetTile(_) => (),
Tool::Number => (),
Tool::Digits(_) => (),
}
}
@ -271,7 +271,7 @@ impl Game {
texture_button(
d,
Vector2 {
x: 300. + col as f32 * bound_offset - if col < 0 { 15. } else { 0. },
x: 320. + col as f32 * bound_offset - if col < 0 { 15. } else { 0. },
y: footer_top + 5. + row as f32 * bound_offset,
},
textures.get(texture),
@ -281,7 +281,8 @@ impl Game {
border,
);
};
tool_button((0, -1), "eraser", Tool::SetTile(Tile::from_char(' ')));
tool_button((0, -2), "eraser", Tool::SetTile(Tile::from_char(' ')));
tool_button((0, -1), "digit_tool", Tool::Digits(None));
tool_button((1, -1), "transparent", Tool::None);
tool_button((0, 0), "block", Tool::SetTile(Tile::from_char('#')));
@ -325,63 +326,110 @@ impl Game {
}
let mouse_pos = d.get_mouse_position();
if self.sim_state == SimState::Editing && mouse_pos.y < footer_top {
let tile_pos = (mouse_pos - self.view_offset) / (16 << self.zoom) as f32;
let tile_pos = Vector2::new(tile_pos.x.floor(), tile_pos.y.floor());
let tile_screen_pos = tile_pos * (16 << self.zoom) as f32 + self.view_offset;
if self.active_tool != Tool::None {
let tex = match self.active_tool {
Tool::None => unreachable!(),
Tool::SetTile(t) => {
if t == Tile::Blank {
"selection".into()
} else {
t.texture()
}
}
Tool::Math => format!("{}_off", self.tool_menu_math.texture_name()),
Tool::Gate => format!("{}_off", self.tool_menu_gate.texture_name()),
Tool::Wire => format!("{}_off", self.tool_menu_wire.texture_name()),
Tool::Arrow => self.tool_menu_arrow.arrow_texture_name().into(),
Tool::Mirror => self.tool_menu_mirror.texture_name().into(),
Tool::Number => todo!(),
};
if self.sim_state == SimState::Editing {
if let Tool::Digits(Some(pos)) = &mut self.active_tool {
let tile_screen_pos = pos.to_vec() * (16 << self.zoom) as f32 + self.view_offset;
d.draw_texture_ex(
textures.get(&tex),
textures.get("selection"),
tile_screen_pos,
0.,
(1 << self.zoom) as f32,
Color::new(255, 255, 255, 100),
Color::new(255, 180, 20, 255),
);
for n in 0..10 {
if d.is_key_pressed(unsafe { std::mem::transmute(KeyboardKey::KEY_ZERO as u32 + n) }) {
self.source_board.set(*pos, Tile::Digit(n as u8));
}
}
if d.is_key_pressed(KeyboardKey::KEY_LEFT) {
pos.x -= 1;
}
if d.is_key_pressed(KeyboardKey::KEY_RIGHT) {
pos.x += 1;
}
if d.is_key_pressed(KeyboardKey::KEY_UP) {
pos.y -= 1;
}
if d.is_key_pressed(KeyboardKey::KEY_DOWN) {
pos.y += 1;
}
}
if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) {
match self.active_tool {
Tool::None => (),
Tool::SetTile(tile) => self.source_board.set(tile_pos.into(), tile),
Tool::Math => self.source_board.set(
tile_pos.into(),
Tile::Powerable(PTile::Math(self.tool_menu_math), false),
),
Tool::Gate => self.source_board.set(
tile_pos.into(),
Tile::Powerable(PTile::Gate(self.tool_menu_gate), false),
),
Tool::Wire => self.source_board.set(
tile_pos.into(),
Tile::Powerable(PTile::Wire(self.tool_menu_wire), false),
),
Tool::Arrow => self
.source_board
.set(tile_pos.into(), Tile::Arrow(self.tool_menu_arrow)),
Tool::Mirror => self
.source_board
.set(tile_pos.into(), Tile::Mirror(self.tool_menu_mirror)),
Tool::Number => todo!(),
if mouse_pos.y < footer_top {
let tile_pos = (mouse_pos - self.view_offset) / (16 << self.zoom) as f32;
let tile_pos = Vector2::new(tile_pos.x.floor(), tile_pos.y.floor());
let tile_screen_pos = tile_pos * (16 << self.zoom) as f32 + self.view_offset;
if self.active_tool != Tool::None {
let tex = match self.active_tool {
Tool::None => unreachable!(),
Tool::SetTile(t) => {
if t == Tile::Blank {
"selection".into()
} else {
t.texture()
}
}
Tool::Math => format!("{}_off", self.tool_menu_math.texture_name()),
Tool::Gate => format!("{}_off", self.tool_menu_gate.texture_name()),
Tool::Wire => format!("{}_off", self.tool_menu_wire.texture_name()),
Tool::Arrow => self.tool_menu_arrow.arrow_texture_name().into(),
Tool::Mirror => self.tool_menu_mirror.texture_name().into(),
Tool::Digits(_) => "selection".into(),
};
d.draw_texture_ex(
textures.get(&tex),
tile_screen_pos,
0.,
(1 << self.zoom) as f32,
Color::new(255, 255, 255, 100),
);
}
if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) {
match self.active_tool {
Tool::None => (),
Tool::SetTile(tile) => self.source_board.set(tile_pos.into(), tile),
Tool::Math => self.source_board.set(
tile_pos.into(),
Tile::Powerable(PTile::Math(self.tool_menu_math), false),
),
Tool::Gate => self.source_board.set(
tile_pos.into(),
Tile::Powerable(PTile::Gate(self.tool_menu_gate), false),
),
Tool::Wire => self.source_board.set(
tile_pos.into(),
Tile::Powerable(PTile::Wire(self.tool_menu_wire), false),
),
Tool::Arrow => self
.source_board
.set(tile_pos.into(), Tile::Arrow(self.tool_menu_arrow)),
Tool::Mirror => self
.source_board
.set(tile_pos.into(), Tile::Mirror(self.tool_menu_mirror)),
Tool::Digits(_pos) => {
self.active_tool = Tool::Digits(Some(tile_pos.into()));
if let Some(tile) = self.source_board.get_mut(tile_pos.into()) {
if let Tile::Digit(_) = tile {
} else {
*tile = Tile::Digit(0);
}
}
}
}
}
}
}
}
}
impl PartialEq for Tool{
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::SetTile(l0), Self::SetTile(r0)) => l0 == r0,
(Self::Digits(_), Self::Digits(_)) => true,
_ => ::core::mem::discriminant(self) == ::core::mem::discriminant(other),
}
}
}

View file

@ -89,7 +89,7 @@ impl Machine {
// reset wires
for y in 0..self.board.height() {
for x in 0..self.board.width() {
if let Tile::Powerable(_, state) = self.board.get_mut((x, y).into()) {
if let Tile::Powerable(_, state) = self.board.get_mut_unchecked((x, y).into()) {
*state = false;
}
}
@ -106,7 +106,7 @@ impl Machine {
continue;
}
let mut new_tile = None;
let target = self.board.get_mut(next_pos);
let target = self.board.get_mut_unchecked(next_pos);
match target {
Tile::Blank => {
*target = tile;
@ -175,7 +175,7 @@ impl Machine {
Tile::Mirror(mirror) => {
let new_dir = mirror.new_dir(dir);
let far_pos = new_dir.step(next_pos);
let far_target = self.board.get_mut(far_pos);
let far_target = self.board.get_mut_unchecked(far_pos);
if let Tile::Blank = far_target {
*far_target = Tile::Marble {
value,
@ -189,7 +189,7 @@ impl Machine {
}
if let Some(t) = new_tile {
*self.board.get_mut(marble_pos) = t;
*self.board.get_mut_unchecked(marble_pos) = t;
}
}
}
@ -209,7 +209,7 @@ impl Machine {
if !self.board.in_bounds(pos) {
return;
}
let tile = self.board.get_mut(pos);
let tile = self.board.get_mut_unchecked(pos);
let front_pos = dir.step(pos);
if let Tile::Powerable(tile, state) = tile {
if let PTile::Trigger = tile {
@ -234,7 +234,7 @@ impl Machine {
}
PTile::Bag => {
if let Some(Tile::Blank) = self.board.get(front_pos) {
*self.board.get_mut(front_pos) = Tile::Marble { value: 0, dir };
*self.board.get_mut_unchecked(front_pos) = Tile::Marble { value: 0, dir };
self.marbles.push(front_pos);
}
}
@ -243,7 +243,7 @@ impl Machine {
&& self.board.get_or_blank(front_pos).is_blank()
{
let value = self.input[self.input_index] as MarbleValue;
*self.board.get_mut(front_pos) = Tile::Marble { value, dir };
*self.board.get_mut_unchecked(front_pos) = Tile::Marble { value, dir };
self.marbles.push(front_pos);
self.input_index += 1;
}
@ -266,12 +266,12 @@ impl Machine {
MathOp::Rem => val_a.checked_rem(val_b).unwrap_or_default(),
};
// println!("{op:?} a:{val_a} b:{val_b}");
*self.board.get_mut(front_pos) = Tile::Marble { value: result, dir };
*self.board.get_mut_unchecked(front_pos) = Tile::Marble { value: result, dir };
self.marbles.push(front_pos);
}
}
PTile::Flipper => {
let m = self.board.get_mut(front_pos);
let m = self.board.get_mut_unchecked(front_pos);
match m {
Tile::Powerable(PTile::Wire(wire_type), _) => {
*wire_type = match *wire_type {

View file

@ -9,6 +9,15 @@ pub struct Pos {
pub y: isize,
}
impl Pos {
pub const fn to_vec(&self) -> Vector2 {
Vector2 {
x: self.x as f32,
y: self.y as f32,
}
}
}
impl From<(usize, usize)> for Pos {
fn from(value: (usize, usize)) -> Self {
Self {
@ -91,7 +100,15 @@ impl Board {
}
}
pub fn get_mut(&mut self, p: Pos) -> &mut Tile {
pub fn get_mut(&mut self, p: Pos) -> Option<&mut Tile> {
if self.in_bounds(p) {
Some(&mut self.rows[p.y as usize][p.x as usize])
} else {
None
}
}
pub fn get_mut_unchecked(&mut self, p: Pos) -> &mut Tile {
if self.in_bounds(p) {
&mut self.rows[p.y as usize][p.x as usize]
} else {