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",
|
"bevy",
|
||||||
"itertools 0.13.0",
|
"itertools 0.13.0",
|
||||||
"log",
|
"log",
|
||||||
|
"rand",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2984,6 +2985,12 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "presser"
|
name = "presser"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -3035,6 +3042,18 @@ version = "0.8.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
dependencies = [
|
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",
|
"rand_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3043,6 +3062,9 @@ name = "rand_core"
|
|||||||
version = "0.6.4"
|
version = "0.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "range-alloc"
|
name = "range-alloc"
|
||||||
|
|||||||
@ -10,6 +10,7 @@ anyhow = "1.0.86"
|
|||||||
bevy = { version = "0.14.0", features = ["dynamic_linking"] }
|
bevy = { version = "0.14.0", features = ["dynamic_linking"] }
|
||||||
itertools = "0.13.0"
|
itertools = "0.13.0"
|
||||||
log = { version = "*", features = ["max_level_debug", "release_max_level_warn"] }
|
log = { version = "*", features = ["max_level_debug", "release_max_level_warn"] }
|
||||||
|
rand = "0.8.5"
|
||||||
|
|
||||||
# Enable a small amount of optimization in debug mode.
|
# Enable a small amount of optimization in debug mode.
|
||||||
[profile.dev]
|
[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
|
use prelude::*;
|
||||||
#[derive(Resource, Deref, DerefMut)]
|
|
||||||
struct Score (usize);
|
|
||||||
|
|
||||||
#[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 {
|
impl Plugin for SqPlugin {
|
||||||
fn build (&self, app: &mut App) {
|
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
|
// add things to your app here
|
||||||
app
|
app
|
||||||
.insert_resource(Score(0))
|
.insert_resource(Score(0))
|
||||||
.insert_resource(ClearColor(BG_COLOR))
|
.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((
|
fn spawn_square_at (commands: &mut Commands, level: u32, position: usize) {
|
||||||
ScoreboardUi,
|
let Some(&(x, y)) = sq_origins.get(position) else {
|
||||||
TextBundle::from_sections([
|
return;
|
||||||
TextSection::new(
|
};
|
||||||
"Score: ",
|
|
||||||
TextStyle {
|
let text = 2i32.pow(level);
|
||||||
font_size: SCOREBOARD_FONT_SIZE,
|
let label = Text2dBundle {
|
||||||
color: TEXT_COLOR,
|
text: Text::from_section(text.to_string(), TextStyle {
|
||||||
..default()
|
font_size: 48.,
|
||||||
|
color: Color::WHITE,
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
transform: Transform {
|
||||||
|
translation: Vec3::new(x, y, 0.0),
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
),
|
..Default::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()
|
|
||||||
}),
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
|
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>>) {
|
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();
|
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 () {
|
fn main () {
|
||||||
App::new()
|
App::new()
|
||||||
@ -76,7 +88,8 @@ fn main () {
|
|||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}), SqPlugin))
|
}), SqPlugin))
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup::setup)
|
||||||
.add_systems(Update, update_scoreboard)
|
.add_systems(Update, update_scoreboard)
|
||||||
|
.add_systems(Update, render_field)
|
||||||
.run();
|
.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