From f11b701ec35331d8e3c7ceb0ee29d2a26d4e3bf9 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 22 Sep 2024 14:25:08 +0300 Subject: [PATCH] feat(grid): generate grid with random walls --- src/grid/grid.rs | 37 +++++++++++++++-- src/grid/tile.rs | 1 - src/hex.rs | 106 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 +- 4 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 src/hex.rs diff --git a/src/grid/grid.rs b/src/grid/grid.rs index 8cf920b..6ad231e 100644 --- a/src/grid/grid.rs +++ b/src/grid/grid.rs @@ -1,12 +1,24 @@ use super::tile::{draw_walls, spawn_tiles}; use bevy::{ + color::palettes::css::{BLACK, DARK_CYAN}, ecs::{system::RunSystemOnce, world::Command}, prelude::*, }; +use bevy_prototype_lyon::{ + draw::{Fill, Stroke}, + entity::ShapeBundle, + geometry::GeometryBuilder, + plugin::ShapePlugin, + prelude::RegularPolygon, + shapes::RegularPolygonFeature, +}; use hexx::{HexLayout, HexOrientation}; use std::time::Duration; -pub(super) fn plugin(_app: &mut App) {} +pub(super) fn plugin(app: &mut App) { + app.insert_resource(Msaa::Sample4); + app.add_plugins(ShapePlugin); +} pub fn spawn_grid(world: &mut World) { world.init_resource::(); @@ -37,11 +49,30 @@ impl Default for GridSettings { impl Command for GridSettings { fn apply(self, world: &mut World) { - world.run_system_once_with(self, spawn_tiles); - world.run_system_once(draw_walls); + // world.run_system_once_with(self, spawn_tiles); + // world.run_system_once(draw_walls); + world.run_system_once(draw); } } +fn draw(mut commands: Commands) { + let shape = RegularPolygon { + sides: 6, + feature: RegularPolygonFeature::Radius(200.), + ..default() + }; + + commands.spawn(( + Name::new("Hexagon"), + ShapeBundle { + path: GeometryBuilder::build_as(&shape), + ..default() + }, + Fill::color(DARK_CYAN), + Stroke::new(BLACK, 10.), + )); +} + #[derive(Debug, Reflect, Resource)] #[reflect(Resource)] pub struct Grid { diff --git a/src/grid/tile.rs b/src/grid/tile.rs index af7def6..8d537d5 100644 --- a/src/grid/tile.rs +++ b/src/grid/tile.rs @@ -64,7 +64,6 @@ pub fn spawn_tiles( fn hexagonal_plane(hex_layout: &HexLayout) -> Mesh { let mesh_info = PlaneMeshBuilder::new(hex_layout) .facing(Vec3::Z) - // .with_scale(Vec3::splat(0.9)) // border .center_aligned() .build(); diff --git a/src/hex.rs b/src/hex.rs new file mode 100644 index 0000000..e6a4c75 --- /dev/null +++ b/src/hex.rs @@ -0,0 +1,106 @@ +use bevy::{color::palettes::css::BLACK, prelude::*}; + +use bevy_prototype_lyon::{ + draw::{Fill, Stroke}, + entity::ShapeBundle, + path::PathBuilder, + plugin::ShapePlugin, +}; +use rand::{thread_rng, Rng}; + +pub(super) fn plugin(app: &mut App) { + app.add_plugins(ShapePlugin); + app.add_systems(Startup, setup_system); +} + +fn setup_system(mut commands: Commands) { + let radius = 5; + let hex_positions = generate_hex_grix(radius); + + let hex_size = 30.; + let hex_height = hex_size * 2.; + let hex_width = (3.0_f32).sqrt() * hex_size; + + for (q, r) in hex_positions { + let x = hex_width * (q as f32 + r as f32 / 2.); + let y = hex_height * (r as f32 * 3. / 4.); + let mut rng = thread_rng(); + let walls: [bool; 6] = [ + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + ]; + + add_hex_tile(&mut commands, Vec2::new(x, y), hex_size, walls); + } +} + +fn generate_hex_grix(radius: i32) -> Vec<(i32, i32)> { + let mut positions = Vec::new(); + + for q in -radius..=radius { + let r1 = (-radius).max(-q - radius); + let r2 = radius.min(-q + radius); + + for r in r1..=r2 { + positions.push((q, r)); + } + } + positions +} + +fn add_hex_tile(commands: &mut Commands, position: Vec2, size: f32, walls: [bool; 6]) { + let hex_points = (0..6) + .map(|i| { + let angle_deg = 60. * i as f32 - 30.; + let angle_rad = angle_deg.to_radians(); + Vec2::new(size * angle_rad.cos(), size * angle_rad.sin()) + }) + .collect::>(); + + let mut path_builder = PathBuilder::new(); + path_builder.move_to(hex_points[0]); + for point in &hex_points[1..] { + path_builder.line_to(*point); + } + path_builder.close(); + let hexagon = path_builder.build(); + + commands.spawn(( + ShapeBundle { + path: hexagon, + spatial: SpatialBundle { + transform: Transform::from_xyz(position.x, position.y, 0.), + ..default() + }, + ..default() + }, + Fill::color(Color::srgb(0.8, 0.8, 0.8)), + )); + + for i in 0..6 { + if walls[i] { + let start = hex_points[i]; + let end = hex_points[(i + 1) % 6]; + let mut line_builder = PathBuilder::new(); + line_builder.move_to(start); + line_builder.line_to(end); + let line = line_builder.build(); + + commands.spawn(( + ShapeBundle { + path: line, + spatial: SpatialBundle { + transform: Transform::from_xyz(position.x, position.y, 1.), + ..default() + }, + ..default() + }, + Stroke::new(BLACK, 2.), + )); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 95b3b56..6e3dc65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ mod demo; mod dev_tools; #[cfg(not(feature = "demo"))] mod grid; +mod hex; mod screens; mod theme; @@ -63,7 +64,8 @@ impl Plugin for AppPlugin { #[cfg(feature = "demo")] demo::plugin, #[cfg(not(feature = "demo"))] - grid::plugin, + // grid::plugin, + hex::plugin, screens::plugin, theme::plugin, ));