Compare commits

...

7 Commits
main ... master

Author SHA1 Message Date
Tobias Wennberg
5c7307813d sdasd 2025-03-24 17:14:23 +01:00
Tobias Wennberg
30c7679af5 fix stopwatch 2025-03-13 19:22:53 +01:00
Tobias Wennberg
6e7313a509 Timer, refactor and more 2025-03-12 17:37:49 +01:00
Tobias Wennberg
9517b89479 Works pretty well now 2025-03-12 10:11:19 +01:00
Tobias Wennberg
efaad5c268 asdpok 2025-03-11 19:23:49 +01:00
Tobias Wennberg
6c84c3b3b3 kommer någon vart 2025-03-10 19:24:39 +01:00
Tobias Wennberg
531db5fa20 asdpok 2025-03-04 08:43:24 +01:00
4 changed files with 615 additions and 63 deletions

113
Cargo.lock generated
View File

@ -137,10 +137,10 @@ checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"const-random",
"getrandom",
"getrandom 0.2.15",
"once_cell",
"version_check",
"zerocopy",
"zerocopy 0.7.35",
]
[[package]]
@ -1206,7 +1206,7 @@ dependencies = [
"derive_more",
"glam 0.29.2",
"itertools",
"rand",
"rand 0.8.5",
"rand_distr",
"serde",
"smallvec",
@ -1768,7 +1768,7 @@ checksum = "7915222f4a08ccc782e08d10b751b42e5f9d786e697d0cb3fd09333cb7e8b6ea"
dependencies = [
"ahash",
"bevy_utils_proc_macros 0.12.1",
"getrandom",
"getrandom 0.2.15",
"hashbrown 0.14.5",
"instant",
"nonmax",
@ -1786,7 +1786,7 @@ checksum = "63c2174d43a0de99f863c98a472370047a2bfa7d1e5cec8d9d647fb500905d9d"
dependencies = [
"ahash",
"bevy_utils_proc_macros 0.15.3",
"getrandom",
"getrandom 0.2.15",
"hashbrown 0.14.5",
"thread_local",
"tracing",
@ -2218,7 +2218,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom",
"getrandom 0.2.15",
"once_cell",
"tiny-keccak",
]
@ -2871,10 +2871,22 @@ dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]]
name = "getrandom"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
dependencies = [
"cfg-if",
"libc",
"wasi 0.13.3+wasi-0.2.2",
"windows-targets 0.52.6",
]
[[package]]
name = "gilrs"
version = "0.11.0"
@ -2943,7 +2955,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677"
dependencies = [
"bytemuck",
"rand",
"rand 0.8.5",
"serde",
]
@ -3567,6 +3579,7 @@ dependencies = [
"bevy 0.15.3",
"bevy_pancam",
"bevy_touch_camera",
"rand 0.9.0",
]
[[package]]
@ -4334,7 +4347,7 @@ version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
"zerocopy 0.7.35",
]
[[package]]
@ -4409,8 +4422,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
"zerocopy 0.8.21",
]
[[package]]
@ -4420,7 +4444,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
]
[[package]]
@ -4429,7 +4463,16 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
"getrandom 0.2.15",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.1",
]
[[package]]
@ -4439,7 +4482,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
dependencies = [
"num-traits",
"rand",
"rand 0.8.5",
]
[[package]]
@ -5216,7 +5259,7 @@ version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
dependencies = [
"getrandom",
"getrandom 0.2.15",
"serde",
]
@ -5260,6 +5303,15 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.13.3+wasi-0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
@ -6209,6 +6261,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
dependencies = [
"bitflags 2.8.0",
]
[[package]]
name = "x11-dl"
version = "2.21.0"
@ -6285,7 +6346,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
"zerocopy-derive 0.7.35",
]
[[package]]
name = "zerocopy"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf01143b2dd5d134f11f545cf9f1431b13b749695cb33bcce051e7568f99478"
dependencies = [
"zerocopy-derive 0.8.21",
]
[[package]]
@ -6298,3 +6368,14 @@ dependencies = [
"quote",
"syn 2.0.98",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712c8386f4f4299382c9abee219bee7084f78fb939d88b6840fcc1320d5f6da2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]

View File

@ -7,10 +7,12 @@ edition = "2024"
bevy = "0.15.3"
bevy_pancam = "0.17.0"
bevy_touch_camera = "0.1.2"
rand = "0.9.0"
# Enable a small amount of optimization in the dev profile.
[profile.dev]
opt-level = 1
debug = true
# Enable a large amount of optimization in the dev profile for dependencies.
[profile.dev.package."*"]

82
src/helpers.rs Executable file
View File

@ -0,0 +1,82 @@
use crate::*;
use bevy::prelude::*;
pub struct RelatedMineIterator<'a> {
inner: std::slice::Iter<'a, Option<Entity>>,
}
impl<'a> Iterator for RelatedMineIterator<'a> {
type Item = &'a Option<Entity>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl RelatedBoxes {
pub fn iter(&self) -> Vec<Option<Entity>> {
vec![
self.ul.clone(),
self.u.clone(),
self.ur.clone(),
self.l.clone(),
self.r.clone(),
self.dl.clone(),
self.d.clone(),
self.dr.clone(),
]
}
pub fn relates_with(&self, entity: Entity) -> bool {
for rel_entity in self.iter() {
if let Some(e) = rel_entity {
if e == entity {
return true;
}
}
}
return false;
}
pub fn nearby_box_unopened_count(
&self,
opened_boxes: &Query<&OpenedBox>,
) -> usize {
let mut i = 0;
for ent in self.iter() {
if let Some(e) = ent {
if !opened_boxes.contains(e) {
i += 1;
}
}
}
return i;
}
pub fn nearby_box_marked_count(
&self,
boxes: &Query<&MarkedBox>,
) -> usize {
let mut i = 0;
for ent in self.iter() {
if let Some(e) = ent {
if boxes.contains(e) {
i += 1;
}
}
}
return i;
}
pub fn nearby_mines_count(
&self,
mine_boxes: &Query<&MineBox>,
) -> usize {
let mut i = 0;
for ent in self.iter() {
if let Some(e) = ent {
if mine_boxes.contains(e) {
i += 1;
}
}
}
return i;
}
}

View File

@ -1,20 +1,69 @@
use bevy::{ecs::system::SystemParam, input::mouse::MouseButtonInput, prelude::*, state::commands};
mod helpers;
use rand::{rng, Rng};
use bevy::{prelude::*, text::FontSmoothing, time::Stopwatch};
use bevy_pancam::*;
const BOARD_WIDTH :usize = 50;
const BOARD_HEIGHT :usize = 50;
const NUMER_OF_MINES :usize = 50;
const COLOR_OPEN_BOX: Color = Color::srgb(0.749, 0.749, 0.635);
const COLOR_HIDDEN_BOX: Color = Color::srgb(0.459, 0.459, 0.408);
const COLOR_MARKED_BOX: Color = Color::srgb(0.769, 0.435, 0.043);
const COLOR_OPEN_MINE: Color = Color::srgb(1., 0., 0.);
#[derive(Default, Reflect)]
enum BoxType {
Open,
const BOARD_WIDTH :usize = 9;
const BOARD_HEIGHT :usize = 9;
const NUMER_OF_MINES :usize = 10;
#[derive(Component)]
struct GameStopwatch(Stopwatch);
// Actions
#[derive(Component)]
struct BoxToMarkFlip;
#[derive(Component)]
struct BoxToMark;
#[derive(Component)]
struct BoxToOpen;
// Box States
#[derive(Component)]
struct OpenedBox;
#[derive(Component)]
struct MineBox;
#[derive(Component)]
struct MarkedBox;
#[derive(Component)]
struct Box;
#[derive(Component)]
struct HoveredBox;
#[derive(States, Default, Clone, PartialEq, Eq, Hash, Debug)]
enum GameState {
StartUi,
#[default]
Closed,
Mine
Start,
Playing,
Win,
Fail,
}
#[derive(Default, Reflect, Component)]
struct Box(BoxType);
#[derive(Component, Clone, Copy)]
struct RelatedBoxes {
ul: Option<Entity>,
u: Option<Entity>,
ur: Option<Entity>,
l: Option<Entity>,
r: Option<Entity>,
dl: Option<Entity>,
d: Option<Entity>,
dr: Option<Entity>,
}
#[derive(Resource)]
struct BoxMatrix([[Option<Entity>; BOARD_WIDTH]; BOARD_HEIGHT]);
#[derive(Resource)]
struct MouseWorldCoordinate(Option<Vec2>);
@ -25,66 +74,400 @@ fn main() {
.add_plugins(DefaultPlugins)
.add_plugins(PanCamPlugin)
.insert_resource(MouseWorldCoordinate(None))
.add_systems(Startup, (draw_mines, init_camera))
.add_systems(PreUpdate, mouse_world_pos)
.add_systems(Update, handle_box)
.insert_resource(BoxMatrix([[None; BOARD_WIDTH]; BOARD_HEIGHT]))
.insert_state(GameState::Start)
.add_systems(Startup, (
load_initial_entities,
init_camera
))
.add_systems(PreUpdate, (mouse_world_pos, mark_hovered_box))
.add_systems(Update, (init_mines).run_if(in_state(GameState::Start)).run_if(any_with_component::<HoveredBox>))
.add_systems(Update, (
(
handle_box,
switch_to_win,
).run_if(in_state(GameState::Playing)).run_if(any_with_component::<HoveredBox>),
game_stopwatch,
open_box,
mark_box,
markflip_box,
))
.add_systems(OnEnter(GameState::Start), (despawn_boxes, draw_boxes).chain())
.add_systems(OnEnter(GameState::Fail), draw_fail)
.add_systems(OnEnter(GameState::Win), draw_win)
.run();
}
fn draw_mines(
fn despawn_boxes(
mut commands: Commands,
boxes: Query<Entity, With<Box>>,
) {
for e in boxes.iter() {
commands.entity(e).despawn_recursive();
}
}
fn load_initial_entities(
mut commands: Commands,
) {
let mut stopwatch = Stopwatch::new();
stopwatch.pause();
commands.spawn((
// Accepts a `String` or any type that converts into a `String`, such as `&str`
Text::new("0"),
TextFont {
font_size: 20.,
..default()
},
TextColor(Color::srgb(0.,1.,1.)),
Node {
position_type: PositionType::Absolute,
top: Val::Percent(0.),
right: Val::Percent(50.),
..default()
},
GameStopwatch(stopwatch),
));
}
fn game_stopwatch(
mut game_stopwatch: Query<(&mut GameStopwatch, &mut Text)>,
time: Res<Time>,
) {
let (mut stopwatch, mut text) = game_stopwatch.single_mut();
stopwatch.0.tick(time.delta());
let seconds = stopwatch.0.elapsed().as_secs_f64();
text.0 = format!("T: {:.3}s", seconds);
}
fn switch_to_win(
mut next_state: ResMut<NextState<GameState>>,
opened_safes: Query<&OpenedBox, Without<MineBox>>,
) {
if opened_safes.iter().count() != (BOARD_WIDTH*BOARD_HEIGHT - NUMER_OF_MINES) {
return
}
next_state.set(GameState::Win);
}
fn draw_win(
mut commands: Commands,
mut game_stopwatch: Query<&mut GameStopwatch>,
mut next_state: ResMut<NextState<GameState>>,
) {
let mut stopwatch = game_stopwatch.single_mut();
stopwatch.0.pause();
commands.spawn((
// Accepts a `String` or any type that converts into a `String`, such as `&str`
Text::new("WIN!!"),
TextFont {
font_size: 200.,
..default()
},
TextColor(Color::srgb(0.,1.,1.)),
Node {
position_type: PositionType::Absolute,
bottom: Val::Percent(50.),
right: Val::Percent(50.),
..default()
},
));
next_state.set(GameState::Start);
}
fn draw_fail(
mut commands: Commands,
mut game_stopwatch: Query<&mut GameStopwatch>,
mut next_state: ResMut<NextState<GameState>>,
) {
let mut stopwatch = game_stopwatch.single_mut();
stopwatch.0.pause();
commands.spawn((
// Accepts a `String` or any type that converts into a `String`, such as `&str`
Text::new("FAIL!"),
TextFont {
font_size: 200.,
..default()
},
TextColor(Color::srgb(1.,0.,0.)),
Node {
position_type: PositionType::Absolute,
bottom: Val::Percent(50.),
right: Val::Percent(50.),
..default()
},
));
next_state.set(GameState::Start);
}
fn markflip_box(
mut commands: Commands,
box_entity_to_open: Query<Entity, With<BoxToMarkFlip>>,
box_marked: Query<&MarkedBox>,
mut color_material: Query<&mut MeshMaterial2d<ColorMaterial>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
for entity in box_entity_to_open.iter() {
commands.entity(entity).remove::<BoxToMarkFlip>();
let is_marked = box_marked.contains(entity);
*color_material.get_mut(entity).unwrap() = match is_marked {
true => {
commands.entity(entity).remove::<(BoxToMarkFlip, MarkedBox)>();
MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX))
},
false => {
commands.entity(entity).remove::<BoxToMarkFlip>().insert(MarkedBox);
MeshMaterial2d(materials.add(COLOR_MARKED_BOX))
},
}
}
}
fn mark_box(
mut commands: Commands,
box_entity_to_open: Query<Entity, (With<BoxToMark>, Without<OpenedBox>)>,
mut color_material: Query<&mut MeshMaterial2d<ColorMaterial>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
for entity in box_entity_to_open.iter() {
commands.entity(entity).remove::<BoxToMark>();
commands.entity(entity).insert(MarkedBox);
*color_material.get_mut(entity).unwrap() = MeshMaterial2d(materials.add(COLOR_MARKED_BOX));
}
}
fn open_box(
mut commands: Commands,
box_entity_to_open: Query<Entity, (With<BoxToOpen>, Without<OpenedBox>)>,
marked_boxes: Query<&MarkedBox>,
mine_boxes: Query<&MineBox>,
safe_opened_boxes: Query<&OpenedBox, Without<MineBox>>,
related_boxes: Query<&RelatedBoxes>,
mut color_material: Query<&mut MeshMaterial2d<ColorMaterial>>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut next_state: ResMut<NextState<GameState>>,
) {
let mut boxes_to_open: Vec<Entity> = box_entity_to_open.iter().collect();
if boxes_to_open.len() == 0 {
return
}
let mut counter: usize = 0;
loop {
if counter >= boxes_to_open.len() {
break
}
let entity = boxes_to_open[counter];
counter += 1;
commands.entity(entity).remove::<BoxToOpen>();
if marked_boxes.contains(entity) {
continue
}
commands.entity(entity).insert(OpenedBox);
let mut r#material = color_material.get_mut(entity).unwrap();
if mine_boxes.contains(entity) {
next_state.set(GameState::Fail);
*r#material = MeshMaterial2d(materials.add(COLOR_OPEN_MINE));
return
}
*r#material = MeshMaterial2d(materials.add(COLOR_OPEN_BOX));
let related_boxes = related_boxes.get(entity).unwrap();
let rel_mine_count = related_boxes.nearby_mines_count(&mine_boxes);
let text_entity = commands.spawn((
Text2d::new( if rel_mine_count != 0 { rel_mine_count.to_string() } else {"".to_string()}),
Transform::default().with_scale(Vec3::new(0.3,0.3,0.)),
)).id();
commands.entity(entity).add_child(text_entity);
if rel_mine_count != 0 {
continue
}
for related_box in related_boxes.iter() {
let box_entity = match related_box {
Some(b) => {b},
None => {continue},
};
if safe_opened_boxes.contains(box_entity) {
continue
}
if boxes_to_open.contains(&related_box.unwrap()) {
continue
}
boxes_to_open.push(related_box.unwrap());
}
}
}
fn init_mines(
mut commands: Commands,
mouse_button_input: Res<ButtonInput<MouseButton>>,
mine_boxes: Query<&MineBox>,
mut hovered_box: Query<(Entity, &RelatedBoxes), With<HoveredBox>>,
mut next_state: ResMut<NextState<GameState>>,
box_matrix: Res<BoxMatrix>,
mut game_stopwatch: Query<&mut GameStopwatch>,
) {
let _mouse_key = if mouse_button_input.just_pressed(MouseButton::Left) || mouse_button_input.just_pressed(MouseButton::Right) { MouseButton::Left }
else {return};
let (hovered_entity, rel_mine) = hovered_box.single_mut();
commands.entity(hovered_entity).insert(BoxToOpen);
let mut number_of_mines = 0;
'main: loop {
for i in 0..box_matrix.0.len() {
for j in 0..box_matrix.0[i].len() {
let entity = box_matrix.0[i][j].unwrap();
if entity == hovered_entity || rel_mine.relates_with(entity) {
continue;
}
if !mine_boxes.contains(entity) {
if random_bool(NUMER_OF_MINES as f64 / (BOARD_WIDTH*BOARD_HEIGHT) as f64) {
number_of_mines += 1;
commands.entity(entity).insert(MineBox);
}
}
if number_of_mines >= NUMER_OF_MINES {
break 'main
}
}
}
}
game_stopwatch.single_mut().0.reset();
game_stopwatch.single_mut().0.unpause();
next_state.set(GameState::Playing);
}
fn draw_boxes(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut box_matrix: ResMut<BoxMatrix>,
) {
let rec = meshes.add(Rectangle::new(5., 5.));
let offset_x = 8.;
let offset_y = 8.;
for i in 0..BOARD_WIDTH {
for j in 0..BOARD_HEIGHT {
commands.spawn((
Mesh2d(rec.clone()),
MeshMaterial2d(materials.add(Color::hsl(10.,10.,10.))),
Transform::from_xyz(offset_x*(i as f32)+0., offset_y*(j as f32)+0., 0.),
Box::default(),
))
;
let offset_x = 5.9;
let offset_y = 5.9;
let mut matrix: [[Option<Entity>; BOARD_WIDTH]; BOARD_HEIGHT] = [[None; BOARD_WIDTH]; BOARD_HEIGHT];
for i in 0..BOARD_HEIGHT {
for j in 0..BOARD_WIDTH {
let x = offset_x*(i as f32);
let y = offset_y*(j as f32);
matrix[i][j] = Some(commands.spawn((
Mesh2d(rec.clone()),
MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX)),
Transform::from_xyz(x, y, 0.),
Box,
)
).id());
}
}
let get_cell = |i: isize, j: isize| -> Option<Entity> {
match matrix.get(i as usize).and_then(|row| row.get(j as usize)).copied() {
Some(s) => {s},
None => {None},
}
};
for i in 0..BOARD_HEIGHT {
commands.entity(matrix[i][0].unwrap()).insert(
RelatedBoxes {
ul: None,
u: get_cell(i as isize -1, 0),
ur: get_cell(i as isize -1, 1),
l: None,
r: get_cell(i as isize , 1),
dl: None,
d: get_cell(i as isize +1, 0),
dr: get_cell(i as isize +1, 1),
}
);
for j in 0..BOARD_WIDTH {
commands.entity(matrix[i][j].unwrap()).insert(
RelatedBoxes {
ul: get_cell(i as isize - 1, j as isize - 1),
u: get_cell(i as isize - 1, j as isize),
ur: get_cell(i as isize - 1, j as isize + 1),
l: get_cell(i as isize, j as isize - 1),
r: get_cell(i as isize, j as isize + 1),
dl: get_cell(i as isize + 1, j as isize - 1),
d: get_cell(i as isize + 1, j as isize),
dr: get_cell(i as isize + 1, j as isize + 1),
}
);
}
}
box_matrix.0 = matrix;
}
fn init_camera(mut commands: Commands) {
commands.spawn((Camera2d, PanCam::default()));
}
fn handle_box(
mouse_button_input: Res<ButtonInput<MouseButton>>,
fn mark_hovered_box(
mut commands: Commands,
mouse_world: Res<MouseWorldCoordinate>,
mut boxes: Query<(&mut Box, &Transform, &MeshMaterial2d<ColorMaterial>)>
) {
if !mouse_button_input.just_pressed(MouseButton::Left){
return
mut boxes: Query<(Entity, &Transform), With<Box>>,
prev_hovered: Query<Entity, With<HoveredBox>>,
) {
for e in prev_hovered.iter() {
commands.entity(e).remove::<HoveredBox>();
}
let mouse = match mouse_world.0 {
Some(x) => {x},
None => return,
};
for (mut r#box, transform, material) in boxes.iter() {
let lcl_x = transform.local_x().x;
let lcl_y = transform.local_y().y;
if lcl_x <= mouse.x &&
lcl_x+BOARD_WIDTH as f32 >= mouse.x &&
lcl_y <= mouse.y &&
lcl_y+BOARD_HEIGHT as f32 >= mouse.y
{
println!("TRUE");
let (entity, _) = match boxes.iter_mut().find(|(_, transform)| {
let min = transform.translation.truncate() - 5. / 2.0;
let max = transform.translation.truncate() + 5. / 2.0;
mouse.x >= min.x && mouse.x <= max.x &&
mouse.y >= min.y && mouse.y <= max.y
}) {
Some(s) => {s},
None => {return},
};
commands.entity(entity).insert(HoveredBox);
}
fn handle_box(
mut commands: Commands,
mouse_button_input: Res<ButtonInput<MouseButton>>,
hovered_boxes: Query<Entity, With<HoveredBox>>,
opened_boxes: Query<&OpenedBox>,
mine_boxes: Query<&MineBox>,
marked_boxes: Query<&MarkedBox>,
related_boxes: Query<&RelatedBoxes>,
) {
let mouse_key = if mouse_button_input.just_pressed(MouseButton::Left) { MouseButton::Left }
else if mouse_button_input.just_pressed(MouseButton::Right) {MouseButton::Right}
else {return};
let entity = hovered_boxes.get_single().unwrap();
if !opened_boxes.contains(entity) {
match mouse_key {
MouseButton::Left => {
commands.entity(entity).insert(BoxToOpen);
},
MouseButton::Right => {
commands.entity(entity).insert(BoxToMarkFlip);
},
_ => return
};
} else {
let rel_box = related_boxes.get(entity).unwrap();
let box_count = rel_box.nearby_mines_count(&mine_boxes);
let rel_box_marked_count = rel_box.nearby_box_marked_count(&marked_boxes);
let rel_box_unopened_count = rel_box.nearby_box_unopened_count(&opened_boxes);
if rel_box_marked_count == box_count {
for rel_box in rel_box.iter() {
if let Some(e) = rel_box {
commands.entity(e).insert(BoxToOpen);
}
}
} else if rel_box_unopened_count == box_count {
for rel_box in rel_box.iter() {
if let Some(e) = rel_box {
commands.entity(e).insert(BoxToMark);
}
}
}
}
println!("Open box");
//if pointers.button != PointerButton::Primary {
// return;
//}
// gizmos.circle_2d(Isometry2d::IDENTITY, 5., Color::WHITE);
}
fn mouse_world_pos(
@ -100,3 +483,7 @@ fn mouse_world_pos(
);
}
fn random_bool(probability: f64) -> bool {
let mut rnd = rng();
rnd.random::<f64>() < probability
}