feat/refactor: draw full game field, randomized starting game state, basic code splitting
This commit is contained in:
parent
138476111c
commit
3436bcf98d
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -1804,6 +1804,7 @@ dependencies = [
|
||||
"bevy",
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2984,6 +2985,12 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "presser"
|
||||
version = "0.3.1"
|
||||
@ -3035,6 +3042,18 @@ version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
@ -3043,6 +3062,9 @@ name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "range-alloc"
|
||||
|
||||
@ -10,6 +10,7 @@ anyhow = "1.0.86"
|
||||
bevy = { version = "0.14.0", features = ["dynamic_linking"] }
|
||||
itertools = "0.13.0"
|
||||
log = { version = "*", features = ["max_level_debug", "release_max_level_warn"] }
|
||||
rand = "0.8.5"
|
||||
|
||||
# Enable a small amount of optimization in debug mode.
|
||||
[profile.dev]
|
||||
|
||||
103
src/main.rs
103
src/main.rs
@ -1,64 +1,64 @@
|
||||
use bevy::prelude::*;
|
||||
mod setup;
|
||||
mod prelude;
|
||||
|
||||
// This resource tracks the game's score
|
||||
#[derive(Resource, Deref, DerefMut)]
|
||||
struct Score (usize);
|
||||
use prelude::*;
|
||||
|
||||
#[derive(Component)]
|
||||
struct ScoreboardUi;
|
||||
|
||||
const BG_COLOR: Color = Color::srgb(0.949, 0.937, 0.769);
|
||||
const SCOREBOARD_FONT_SIZE: f32 = 44.0;
|
||||
const TEXT_COLOR: Color = Color::BLACK;
|
||||
const SCORE_COLOR: Color = Color::srgb(0.4, 0.05, 0.04);
|
||||
const SCOREBOARD_TEXT_PADDING: Val = Val::Px(22.0);
|
||||
|
||||
pub struct SqPlugin;
|
||||
|
||||
impl Plugin for SqPlugin {
|
||||
fn build (&self, app: &mut App) {
|
||||
|
||||
let thread = &mut thread_rng();
|
||||
|
||||
let mut start = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1];
|
||||
|
||||
start.shuffle(thread);
|
||||
|
||||
// add things to your app here
|
||||
app
|
||||
.insert_resource(Score(0))
|
||||
.insert_resource(ClearColor(BG_COLOR))
|
||||
.insert_resource(Field(start))
|
||||
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
fn setup (
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
commands.spawn(Camera2dBundle::default());
|
||||
|
||||
commands.spawn((
|
||||
ScoreboardUi,
|
||||
TextBundle::from_sections([
|
||||
TextSection::new(
|
||||
"Score: ",
|
||||
TextStyle {
|
||||
font_size: SCOREBOARD_FONT_SIZE,
|
||||
color: TEXT_COLOR,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::from_style(TextStyle {
|
||||
font_size: SCOREBOARD_FONT_SIZE,
|
||||
color: SCORE_COLOR,
|
||||
..default()
|
||||
}),
|
||||
])
|
||||
.with_style(Style {
|
||||
position_type: PositionType::Absolute,
|
||||
top: SCOREBOARD_TEXT_PADDING,
|
||||
left: SCOREBOARD_TEXT_PADDING,
|
||||
..default()
|
||||
fn spawn_square_at (commands: &mut Commands, level: u32, position: usize) {
|
||||
let Some(&(x, y)) = sq_origins.get(position) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let text = 2i32.pow(level);
|
||||
let label = Text2dBundle {
|
||||
text: Text::from_section(text.to_string(), TextStyle {
|
||||
font_size: 48.,
|
||||
color: Color::WHITE,
|
||||
..Default::default()
|
||||
}),
|
||||
));
|
||||
transform: Transform {
|
||||
translation: Vec3::new(x, y, 0.0),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
commands.spawn(SpriteBundle {
|
||||
sprite: Sprite {
|
||||
color: sq_colors[level as usize % sq_colors.len()],
|
||||
..Default::default()
|
||||
},
|
||||
transform: Transform {
|
||||
translation: Vec3::new(x, y, 0.0),
|
||||
scale: Vec3::new(148.0, 148.0, 1.0),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
commands.spawn(label);
|
||||
}
|
||||
|
||||
fn update_scoreboard (score: Res<Score>, mut query: Query<&mut Text, With<ScoreboardUi>>) {
|
||||
@ -66,6 +66,18 @@ fn update_scoreboard (score: Res<Score>, mut query: Query<&mut Text, With<Scoreb
|
||||
text.sections[1].value = score.to_string();
|
||||
}
|
||||
|
||||
fn render_field (
|
||||
mut commands: Commands,
|
||||
asset_server: Res<AssetServer>,
|
||||
field: Res<Field>,
|
||||
) {
|
||||
for (idx, &val) in field.iter().enumerate() {
|
||||
if val > 0 {
|
||||
spawn_square_at(&mut commands, val, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main () {
|
||||
App::new()
|
||||
@ -76,7 +88,8 @@ fn main () {
|
||||
}),
|
||||
..Default::default()
|
||||
}), SqPlugin))
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Startup, setup::setup)
|
||||
.add_systems(Update, update_scoreboard)
|
||||
.add_systems(Update, render_field)
|
||||
.run();
|
||||
}
|
||||
|
||||
47
src/prelude.rs
Normal file
47
src/prelude.rs
Normal file
@ -0,0 +1,47 @@
|
||||
pub use bevy::prelude::*;
|
||||
pub use rand::{ seq::SliceRandom, thread_rng, Rng };
|
||||
|
||||
#[derive(Resource, Deref, DerefMut)]
|
||||
pub struct Score (pub usize);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct ScoreboardUi;
|
||||
|
||||
|
||||
#[derive(Resource, Deref, DerefMut)]
|
||||
pub struct Field (pub Vec<u32>);
|
||||
|
||||
|
||||
pub const BG_COLOR: Color = Color::srgb(0.949, 0.937, 0.769);
|
||||
pub const SCOREBOARD_FONT_SIZE: f32 = 44.0;
|
||||
pub const TEXT_COLOR: Color = Color::BLACK;
|
||||
pub const SCORE_COLOR: Color = Color::srgb(0.4, 0.05, 0.04);
|
||||
pub const SCOREBOARD_TEXT_PADDING: Val = Val::Px(22.0);
|
||||
|
||||
pub struct SqPlugin;
|
||||
|
||||
pub const sq_origins: [(f32, f32); 16] = [
|
||||
(-225., 225.), (-75., 225.), (75., 225.), (225., 225.,),
|
||||
(-225., 75.), (-75., 75.), (75., 75.), (225., 75.,),
|
||||
(-225., -75.), (-75., -75.), (75., -75.), (225., -75.,),
|
||||
(-225., -225.), (-75., -225.), (75., -225.), (225., -225.,),
|
||||
];
|
||||
|
||||
pub const sq_colors: [Color; 16] = [
|
||||
Color::srgb(0.373, 0.851, 0.91),
|
||||
Color::srgb(0.373, 0.643, 0.91),
|
||||
Color::srgb(0.247, 0.161, 0.761),
|
||||
Color::srgb(0.451, 0.161, 0.761),
|
||||
Color::srgb(0.502, 0.047, 0.98),
|
||||
Color::srgb(0.663, 0.137, 0.91),
|
||||
Color::srgb(0.443, 0.102, 0.6),
|
||||
Color::srgb(0.851, 0.094, 0.773),
|
||||
Color::srgb(0.89, 0.086, 0.412),
|
||||
Color::srgb(0.91, 0.102, 0.102),
|
||||
Color::srgb(0.671, 0.039, 0.039),
|
||||
Color::srgb(0.82, 0.251, 0.059),
|
||||
Color::srgb(0.851, 0.71, 0.039),
|
||||
Color::srgb(0.569, 0.184, 0.051),
|
||||
Color::srgb(0.016, 0.055, 0.231),
|
||||
Color::srgb(0.02, 0.02, 0.02),
|
||||
];
|
||||
79
src/setup.rs
Normal file
79
src/setup.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn setup (
|
||||
mut commands: Commands,
|
||||
mut _meshes: ResMut<Assets<Mesh>>,
|
||||
mut _materials: ResMut<Assets<ColorMaterial>>,
|
||||
_asset_server: Res<AssetServer>,
|
||||
) {
|
||||
commands.spawn(Camera2dBundle::default());
|
||||
|
||||
commands.spawn((
|
||||
ScoreboardUi,
|
||||
TextBundle::from_sections([
|
||||
TextSection::new(
|
||||
"Score: ",
|
||||
TextStyle {
|
||||
font_size: SCOREBOARD_FONT_SIZE,
|
||||
color: TEXT_COLOR,
|
||||
..default()
|
||||
},
|
||||
),
|
||||
TextSection::from_style(TextStyle {
|
||||
font_size: SCOREBOARD_FONT_SIZE,
|
||||
color: SCORE_COLOR,
|
||||
..default()
|
||||
}),
|
||||
])
|
||||
.with_style(Style {
|
||||
position_type: PositionType::Absolute,
|
||||
top: SCOREBOARD_TEXT_PADDING,
|
||||
left: SCOREBOARD_TEXT_PADDING,
|
||||
..default()
|
||||
}),
|
||||
));
|
||||
|
||||
draw_board(&mut commands);
|
||||
}
|
||||
|
||||
|
||||
fn draw_board (commands: &mut Commands) {
|
||||
|
||||
let borders = [-305., 305.];
|
||||
let lines = [-150., 0., 150.];
|
||||
|
||||
let border_width = 10.;
|
||||
let line_width = 1.;
|
||||
let length = 620.;
|
||||
|
||||
let border_color = Color::BLACK;
|
||||
let line_color = Color::srgba(0., 0., 0., 0.667);
|
||||
let bg_color = Color::srgba(0.2, 0.01, 0.5, 0.632);
|
||||
|
||||
// bg
|
||||
commands.spawn(SpriteBundle {
|
||||
sprite: Sprite { color: bg_color, ..Default::default() },
|
||||
transform: Transform {
|
||||
scale: Vec3::new(length, length, 1.0),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let line = |color: Color, translation: Vec3, scale: Vec3| SpriteBundle {
|
||||
sprite: Sprite { color, ..Default::default() },
|
||||
transform: Transform { translation, scale, ..Default::default() },
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// @TODO variable grid size
|
||||
for border in 0..2 {
|
||||
commands.spawn(line(border_color, Vec3::new(borders[border], 0.0, 0.0), Vec3::new(border_width, length, 1.0)));
|
||||
commands.spawn(line(border_color, Vec3::new(0.0, borders[border], 0.0), Vec3::new(length, border_width, 1.0)));
|
||||
}
|
||||
|
||||
for mesh in 0..3 {
|
||||
commands.spawn(line(line_color, Vec3::new(lines[mesh], 0.0, 0.0), Vec3::new(line_width, length, 1.0)));
|
||||
commands.spawn(line(line_color, Vec3::new(0.0, lines[mesh], 0.0), Vec3::new(length, line_width, 1.0)));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user