Timer, refactor and more
This commit is contained in:
parent
9517b89479
commit
6e7313a509
171
src/helpers.rs
171
src/helpers.rs
@ -6,13 +6,6 @@ pub struct RelatedMineIterator<'a> {
|
||||
inner: std::slice::Iter<'a, Option<Entity>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub enum BoxTypeBin {
|
||||
Safe,
|
||||
Mine,
|
||||
Other,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for RelatedMineIterator<'a> {
|
||||
type Item = &'a Option<Entity>;
|
||||
|
||||
@ -34,30 +27,6 @@ impl RelatedBoxes {
|
||||
self.dr.clone(),
|
||||
]
|
||||
}
|
||||
// recursive function to add open event to related boxes if it is zero
|
||||
pub fn iterate_rel_mines(
|
||||
&self,
|
||||
commands: &mut Commands,
|
||||
boxes: &mut Query<&mut Box>,
|
||||
related_boxes: &Query<&RelatedBoxes>,
|
||||
) {
|
||||
for related_box in self.iter() {
|
||||
let box_entity = match related_box {
|
||||
Some(b) => {b},
|
||||
None => {continue},
|
||||
};
|
||||
let mut r#box_val = boxes.get_mut(box_entity).unwrap();
|
||||
if box_val.0 != BoxType::Open {
|
||||
continue
|
||||
}
|
||||
r#box_val.0 = BoxType::Open;
|
||||
commands.entity(related_box.unwrap()).insert(BoxToOpen);
|
||||
let related_box = related_boxes.get(box_entity).unwrap();
|
||||
if related_box.nearby_mines_count_box_mut(boxes) == 0 {
|
||||
// related_box.iterate_rel_mines(draw_event, boxes, related_boxes)
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn relates_with(&self, entity: Entity) -> bool {
|
||||
for rel_entity in self.iter() {
|
||||
if let Some(e) = rel_entity {
|
||||
@ -70,12 +39,12 @@ impl RelatedBoxes {
|
||||
}
|
||||
pub fn nearby_box_unopened_count(
|
||||
&self,
|
||||
boxes: &Query<&Box>,
|
||||
opened_boxes: &Query<&OpenedBox>,
|
||||
) -> usize {
|
||||
let mut i = 0;
|
||||
for ent in self.iter() {
|
||||
if let Some(e) = ent {
|
||||
if !boxes.get(e).unwrap().is_opened() {
|
||||
if !opened_boxes.contains(e) {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
@ -84,156 +53,30 @@ impl RelatedBoxes {
|
||||
}
|
||||
pub fn nearby_box_marked_count(
|
||||
&self,
|
||||
boxes: &Query<&Box>,
|
||||
boxes: &Query<&MarkedBox>,
|
||||
) -> usize {
|
||||
let mut i = 0;
|
||||
for ent in self.iter() {
|
||||
if let Some(e) = ent {
|
||||
if boxes.get(e).unwrap().is_marked() {
|
||||
if boxes.contains(e) {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
pub fn nearby_mines_count_box(
|
||||
pub fn nearby_mines_count(
|
||||
&self,
|
||||
boxes: &Query<&Box>,
|
||||
mine_boxes: &Query<&MineBox>,
|
||||
) -> usize {
|
||||
let mut i = 0;
|
||||
for ent in self.iter() {
|
||||
if let Some(e) = ent {
|
||||
if boxes.get(e).unwrap().0.is_mine() {
|
||||
if mine_boxes.contains(e) {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
pub fn nearby_mines_count_box_mut(
|
||||
&self,
|
||||
boxes: &Query<&mut Box>,
|
||||
) -> usize {
|
||||
let mut i = 0;
|
||||
for ent in self.iter() {
|
||||
if let Some(e) = ent {
|
||||
if boxes.get(e).unwrap().0.is_mine() {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
pub fn nearby_mines_count_no_hovered(
|
||||
&self,
|
||||
boxes: Query<&Box, Without<Hovered>>,
|
||||
) -> usize {
|
||||
let mut i = 0;
|
||||
for ent in self.iter() {
|
||||
if let Some(e) = ent {
|
||||
if boxes.get(e).unwrap().0.is_mine() {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
}
|
||||
impl BoxType {
|
||||
pub fn is_opened(&self) -> bool {
|
||||
match self {
|
||||
BoxType::Open => true,
|
||||
BoxType::Safe => false,
|
||||
BoxType::MarkedSafe => false,
|
||||
BoxType::Mine => false,
|
||||
BoxType::MarkedMine => false,
|
||||
BoxType::OpenMine => true,
|
||||
}
|
||||
}
|
||||
pub fn box_type_bin(&self) -> BoxTypeBin {
|
||||
match self {
|
||||
BoxType::Open => BoxTypeBin::Other,
|
||||
BoxType::Safe => BoxTypeBin::Safe,
|
||||
BoxType::MarkedSafe => BoxTypeBin::Other,
|
||||
BoxType::Mine => BoxTypeBin::Mine,
|
||||
BoxType::MarkedMine => BoxTypeBin::Other,
|
||||
BoxType::OpenMine => BoxTypeBin::Other,
|
||||
}
|
||||
}
|
||||
pub fn can_open(&self) -> bool {
|
||||
match self {
|
||||
BoxType::Open => false,
|
||||
BoxType::Safe => true,
|
||||
BoxType::MarkedSafe => false,
|
||||
BoxType::Mine => true,
|
||||
BoxType::MarkedMine => false,
|
||||
BoxType::OpenMine => false,
|
||||
}
|
||||
}
|
||||
pub fn is_mine(&self) -> bool {
|
||||
match self {
|
||||
BoxType::Open => false,
|
||||
BoxType::Safe => false,
|
||||
BoxType::MarkedSafe => false,
|
||||
BoxType::Mine => true,
|
||||
BoxType::MarkedMine => true,
|
||||
BoxType::OpenMine => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Box {
|
||||
pub fn is_opened(&self) -> bool {
|
||||
match &self.0 {
|
||||
BoxType::Open => true,
|
||||
BoxType::Safe => false,
|
||||
BoxType::MarkedSafe => false,
|
||||
BoxType::Mine => false,
|
||||
BoxType::MarkedMine => false,
|
||||
BoxType::OpenMine => true,
|
||||
}
|
||||
|
||||
}
|
||||
pub fn is_marked(&self) -> bool {
|
||||
match &self.0 {
|
||||
BoxType::Open => false,
|
||||
BoxType::Safe => false,
|
||||
BoxType::MarkedSafe => true,
|
||||
BoxType::Mine => false,
|
||||
BoxType::MarkedMine => true,
|
||||
BoxType::OpenMine => false,
|
||||
}
|
||||
|
||||
}
|
||||
pub fn open(&self) -> Self {
|
||||
match &self.0 {
|
||||
BoxType::Open => Box(BoxType::Open),
|
||||
BoxType::Safe => Box(BoxType::Open),
|
||||
BoxType::MarkedSafe => Box(BoxType::MarkedSafe),
|
||||
BoxType::Mine => Box(BoxType::OpenMine),
|
||||
BoxType::MarkedMine =>Box(BoxType::MarkedMine),
|
||||
BoxType::OpenMine => Box(BoxType::OpenMine),
|
||||
}
|
||||
}
|
||||
pub fn mark(&self) -> Self {
|
||||
match &self.0 {
|
||||
BoxType::Open => (*self).clone(),
|
||||
BoxType::Safe => Box(BoxType::MarkedSafe),
|
||||
BoxType::MarkedSafe => Box(BoxType::MarkedSafe),
|
||||
BoxType::Mine => Box(BoxType::MarkedMine),
|
||||
BoxType::MarkedMine =>Box(BoxType::MarkedMine),
|
||||
BoxType::OpenMine => Box(BoxType::OpenMine),
|
||||
}
|
||||
}
|
||||
pub fn mark_flip(&self) -> Self {
|
||||
match &self.0 {
|
||||
BoxType::Open => (*self).clone(),
|
||||
BoxType::Safe => Box(BoxType::MarkedSafe),
|
||||
BoxType::MarkedSafe => Box(BoxType::Safe),
|
||||
BoxType::Mine => Box(BoxType::MarkedMine),
|
||||
BoxType::MarkedMine =>Box(BoxType::Mine),
|
||||
BoxType::OpenMine => Box(BoxType::Mine),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
293
src/main.rs
293
src/main.rs
@ -1,6 +1,6 @@
|
||||
mod helpers;
|
||||
use rand::{rng, Rng};
|
||||
use bevy::prelude::*;
|
||||
use bevy::{prelude::*, text::FontSmoothing, time::Stopwatch};
|
||||
use bevy_pancam::*;
|
||||
|
||||
const COLOR_OPEN_BOX: Color = Color::srgb(0.749, 0.749, 0.635);
|
||||
@ -8,10 +8,14 @@ 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.);
|
||||
|
||||
const BOARD_WIDTH :usize = 16;
|
||||
const BOARD_HEIGHT :usize = 30;
|
||||
const NUMER_OF_MINES :usize = 99;
|
||||
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)]
|
||||
@ -19,14 +23,23 @@ struct BoxToMark;
|
||||
#[derive(Component)]
|
||||
struct BoxToOpen;
|
||||
|
||||
// Box States
|
||||
#[derive(Component)]
|
||||
struct SafeUnopenedBox;
|
||||
struct OpenedBox;
|
||||
#[derive(Component)]
|
||||
struct MineBox;
|
||||
#[derive(Component)]
|
||||
struct MarkedBox;
|
||||
|
||||
#[derive(Component)]
|
||||
struct Hovered;
|
||||
struct Box;
|
||||
|
||||
#[derive(Component)]
|
||||
struct HoveredBox;
|
||||
|
||||
#[derive(States, Default, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
enum GameState {
|
||||
StartUi,
|
||||
#[default]
|
||||
Start,
|
||||
Playing,
|
||||
@ -34,19 +47,6 @@ enum GameState {
|
||||
Fail,
|
||||
}
|
||||
|
||||
#[derive(Default, Reflect, Clone, PartialEq, Eq)]
|
||||
enum BoxType {
|
||||
Open,
|
||||
#[default]
|
||||
Safe,
|
||||
MarkedSafe,
|
||||
Mine,
|
||||
MarkedMine,
|
||||
OpenMine,
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Component, Clone, Copy)]
|
||||
struct RelatedBoxes {
|
||||
ul: Option<Entity>,
|
||||
@ -60,8 +60,6 @@ struct RelatedBoxes {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Default, Reflect, Component, Clone)]
|
||||
struct Box(BoxType);
|
||||
|
||||
|
||||
#[derive(Resource)]
|
||||
@ -78,93 +76,168 @@ fn main() {
|
||||
.insert_resource(MouseWorldCoordinate(None))
|
||||
.insert_resource(BoxMatrix([[None; BOARD_WIDTH]; BOARD_HEIGHT]))
|
||||
.insert_state(GameState::Start)
|
||||
.add_systems(Startup, (draw_boxes, init_camera))
|
||||
.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::<Hovered>))
|
||||
.add_systems(Update, (init_mines).run_if(in_state(GameState::Start)).run_if(any_with_component::<HoveredBox>))
|
||||
.add_systems(Update, (
|
||||
(handle_box).run_if(in_state(GameState::Playing)).run_if(any_with_component::<Hovered>),
|
||||
(
|
||||
handle_box,
|
||||
game_stopwatch,
|
||||
switch_to_win,
|
||||
).run_if(in_state(GameState::Playing)).run_if(any_with_component::<HoveredBox>),
|
||||
open_box,
|
||||
mark_box,
|
||||
markflip_box,
|
||||
switch_to_win,
|
||||
))
|
||||
.add_systems(OnEnter(GameState::Start), (despawn_boxes.before(draw_boxes), draw_boxes))
|
||||
.add_systems(OnEnter(GameState::Fail), draw_fail)
|
||||
.add_systems(OnEnter(GameState::Win), draw_win)
|
||||
.run();
|
||||
}
|
||||
|
||||
fn despawn_boxes(
|
||||
mut commands: Commands,
|
||||
boxes: Query<Entity, With<Box>>,
|
||||
) {
|
||||
for e in boxes.iter() {
|
||||
commands.entity(e).despawn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn load_initial_entities(
|
||||
mut commands: Commands,
|
||||
) {
|
||||
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::new()),
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
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>>,
|
||||
unopened_safes: Query<&SafeUnopenedBox>
|
||||
opened_safes: Query<&OpenedBox, Without<MineBox>>,
|
||||
) {
|
||||
if !unopened_safes.is_empty() {
|
||||
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 commands: Commands,
|
||||
mut game_stopwatch: Query<&mut GameStopwatch>,
|
||||
) {
|
||||
commands.spawn(Text2d::new("WIN!!"));
|
||||
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()
|
||||
},
|
||||
));
|
||||
}
|
||||
fn draw_fail(
|
||||
mut commands: Commands
|
||||
mut commands: Commands,
|
||||
mut game_stopwatch: Query<&mut GameStopwatch>,
|
||||
mut next_state: ResMut<NextState<GameState>>,
|
||||
) {
|
||||
commands.spawn(Text2d::new("FAIL!!"));
|
||||
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>>,
|
||||
mut boxes: Query<&mut Box>,
|
||||
box_marked: Query<&MarkedBox>,
|
||||
mut color_material: Query<&mut MeshMaterial2d<ColorMaterial>>,
|
||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
) {
|
||||
for entity in box_entity_to_open.iter() {
|
||||
println!("FLIP");
|
||||
commands.entity(entity).remove::<BoxToMarkFlip>();
|
||||
let mut r#box = boxes.get_mut(entity).unwrap();
|
||||
*r#box = r#box.mark_flip();
|
||||
let mut r#material = color_material.get_mut(entity).unwrap();
|
||||
*r#material = match r#box.0 {
|
||||
BoxType::Open => MeshMaterial2d(materials.add(COLOR_OPEN_BOX)),
|
||||
BoxType::Safe => MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX)),
|
||||
BoxType::MarkedSafe => MeshMaterial2d(materials.add(COLOR_MARKED_BOX)),
|
||||
BoxType::Mine => MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX)),
|
||||
BoxType::MarkedMine => MeshMaterial2d(materials.add(COLOR_MARKED_BOX)),
|
||||
BoxType::OpenMine => MeshMaterial2d(materials.add(COLOR_OPEN_MINE)),
|
||||
};
|
||||
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>>,
|
||||
mut boxes: Query<&mut Box>,
|
||||
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>();
|
||||
let mut r#box = boxes.get_mut(entity).unwrap();
|
||||
*r#box = r#box.mark();
|
||||
let mut r#material = color_material.get_mut(entity).unwrap();
|
||||
*r#material = match r#box.0 {
|
||||
BoxType::Open => MeshMaterial2d(materials.add(COLOR_OPEN_BOX)),
|
||||
BoxType::Safe => MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX)),
|
||||
BoxType::MarkedSafe => MeshMaterial2d(materials.add(COLOR_MARKED_BOX)),
|
||||
BoxType::Mine => MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX)),
|
||||
BoxType::MarkedMine => MeshMaterial2d(materials.add(COLOR_MARKED_BOX)),
|
||||
BoxType::OpenMine => MeshMaterial2d(materials.add(COLOR_OPEN_MINE)),
|
||||
};
|
||||
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>>,
|
||||
mut boxes: Query<&mut Box>,
|
||||
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>,
|
||||
transforms: Query<&Transform>,
|
||||
mut color_material: Query<&mut MeshMaterial2d<ColorMaterial>>,
|
||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
mut next_state: ResMut<NextState<GameState>>,
|
||||
@ -181,49 +254,39 @@ fn open_box(
|
||||
let entity = boxes_to_open[counter];
|
||||
counter += 1;
|
||||
commands.entity(entity).remove::<BoxToOpen>();
|
||||
let mut r#box = boxes.get_mut(entity).unwrap();
|
||||
if !r#box.0.can_open() {
|
||||
if marked_boxes.contains(entity) {
|
||||
continue
|
||||
}
|
||||
*r#box = r#box.open();
|
||||
commands.entity(entity).remove::<SafeUnopenedBox>();
|
||||
if r#box.0 == BoxType::OpenMine {
|
||||
next_state.set(GameState::Fail);
|
||||
}
|
||||
commands.entity(entity).insert(OpenedBox);
|
||||
let mut r#material = color_material.get_mut(entity).unwrap();
|
||||
*r#material = match r#box.0 {
|
||||
BoxType::Open => MeshMaterial2d(materials.add(COLOR_OPEN_BOX)),
|
||||
BoxType::Safe => MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX)),
|
||||
BoxType::MarkedSafe => MeshMaterial2d(materials.add(COLOR_MARKED_BOX)),
|
||||
BoxType::Mine => MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX)),
|
||||
BoxType::MarkedMine => MeshMaterial2d(materials.add(COLOR_MARKED_BOX)),
|
||||
BoxType::OpenMine => MeshMaterial2d(materials.add(COLOR_OPEN_MINE)),
|
||||
};
|
||||
let rel_mine = related_boxes.get(entity).unwrap();
|
||||
let rel_mine_count = rel_mine.nearby_mines_count_box_mut(&boxes);
|
||||
let transform = transforms.get(entity).unwrap();
|
||||
commands.spawn((
|
||||
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()}),
|
||||
TextLayout::new_with_justify(JustifyText::Center),
|
||||
transform.clone().with_scale(Vec3::new(0.3,0.3,0.)),
|
||||
));
|
||||
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 rel_mine.iter() {
|
||||
for related_box in related_boxes.iter() {
|
||||
let box_entity = match related_box {
|
||||
Some(b) => {b},
|
||||
None => {continue},
|
||||
};
|
||||
let box_val = boxes.get(box_entity).unwrap();
|
||||
if box_val.0 == BoxType::Open {
|
||||
if safe_opened_boxes.contains(box_entity) {
|
||||
continue
|
||||
}
|
||||
if boxes_to_open.contains(&related_box.unwrap()) {
|
||||
continue
|
||||
}
|
||||
boxes_to_open.push(related_box.unwrap());
|
||||
//commands.entity(related_box.unwrap()).insert(BoxToOpen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -231,33 +294,38 @@ fn open_box(
|
||||
fn init_mines(
|
||||
mut commands: Commands,
|
||||
mouse_button_input: Res<ButtonInput<MouseButton>>,
|
||||
mut boxes: Query<(Entity, &mut Box)>,
|
||||
mut hovered_box: Query<(Entity, &RelatedBoxes), With<Hovered>>,
|
||||
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) { MouseButton::Left }
|
||||
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;
|
||||
while number_of_mines <= NUMER_OF_MINES {
|
||||
'main: loop {
|
||||
for i in 0..box_matrix.0.len() {
|
||||
for j in 0..box_matrix.0[i].len() {
|
||||
let (entity, mut r#box) = boxes.get_mut(box_matrix.0[i][j].unwrap()).unwrap();
|
||||
let entity = box_matrix.0[i][j].unwrap();
|
||||
if entity == hovered_entity || rel_mine.relates_with(entity) {
|
||||
continue;
|
||||
}
|
||||
if r#box.0 != BoxType::Mine {
|
||||
r#box.0 = match random_bool(NUMER_OF_MINES as f64 / (BOARD_WIDTH*BOARD_HEIGHT) as f64) {
|
||||
true => { number_of_mines += 1; commands.entity(entity).remove::<SafeUnopenedBox>(); BoxType::Mine},
|
||||
false => BoxType::Safe,
|
||||
}
|
||||
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();
|
||||
next_state.set(GameState::Playing);
|
||||
}
|
||||
|
||||
@ -268,8 +336,8 @@ fn draw_boxes(
|
||||
mut box_matrix: ResMut<BoxMatrix>,
|
||||
) {
|
||||
let rec = meshes.add(Rectangle::new(5., 5.));
|
||||
let offset_x = 6.;
|
||||
let offset_y = 6.;
|
||||
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 {
|
||||
@ -280,8 +348,7 @@ fn draw_boxes(
|
||||
Mesh2d(rec.clone()),
|
||||
MeshMaterial2d(materials.add(COLOR_HIDDEN_BOX)),
|
||||
Transform::from_xyz(x, y, 0.),
|
||||
Box::default(),
|
||||
SafeUnopenedBox
|
||||
Box,
|
||||
)
|
||||
).id());
|
||||
}
|
||||
@ -332,8 +399,11 @@ fn mark_hovered_box(
|
||||
mut commands: Commands,
|
||||
mouse_world: Res<MouseWorldCoordinate>,
|
||||
mut boxes: Query<(Entity, &Transform), With<Box>>,
|
||||
prev_hovered: Query<Entity, With<Hovered>>,
|
||||
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,
|
||||
@ -347,25 +417,24 @@ fn mark_hovered_box(
|
||||
Some(s) => {s},
|
||||
None => {return},
|
||||
};
|
||||
for e in prev_hovered.iter() {
|
||||
commands.entity(e).remove::<Hovered>();
|
||||
}
|
||||
commands.entity(entity).insert(Hovered);
|
||||
commands.entity(entity).insert(HoveredBox);
|
||||
}
|
||||
|
||||
fn handle_box(
|
||||
mut commands: Commands,
|
||||
mouse_button_input: Res<ButtonInput<MouseButton>>,
|
||||
hovered_boxes: Query<(Entity, &Box), With<Hovered>>,
|
||||
boxes: Query<&Box>,
|
||||
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, r#box) = hovered_boxes.get_single().unwrap();
|
||||
if !r#box.0.is_opened() {
|
||||
let entity = hovered_boxes.get_single().unwrap();
|
||||
if !opened_boxes.contains(entity) {
|
||||
match mouse_key {
|
||||
MouseButton::Left => {
|
||||
commands.entity(entity).insert(BoxToOpen);
|
||||
@ -377,9 +446,9 @@ fn handle_box(
|
||||
};
|
||||
} else {
|
||||
let rel_box = related_boxes.get(entity).unwrap();
|
||||
let box_count = rel_box.nearby_mines_count_box(&boxes);
|
||||
let rel_box_marked_count = rel_box.nearby_box_marked_count(&boxes);
|
||||
let rel_box_unopened_count = rel_box.nearby_box_unopened_count(&boxes);
|
||||
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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user