diff --git a/Cargo.lock b/Cargo.lock index aa2a063..9013d1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -818,6 +818,18 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "bevy_prototype_lyon" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66a59b46da5bccc6d86c6047cfc81b8e9027f5b98e24b8721e8e1453c1d05371" +dependencies = [ + "bevy", + "lyon_algorithms", + "lyon_tessellation", + "svgtypes", +] + [[package]] name = "bevy_ptr" version = "0.14.1" @@ -1801,6 +1813,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float_next_after" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" + [[package]] name = "fnv" version = "1.0.7" @@ -2327,6 +2345,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "kurbo" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b" +dependencies = [ + "arrayvec", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -2376,6 +2403,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libredox" version = "0.0.2" @@ -2425,6 +2458,48 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lyon_algorithms" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3bca95f9a4955b3e4a821fbbcd5edfbd9be2a9a50bb5758173e5358bfb4c623" +dependencies = [ + "lyon_path", + "num-traits", +] + +[[package]] +name = "lyon_geom" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edecfb8d234a2b0be031ab02ebcdd9f3b9ee418fb35e265f7a540a48d197bff9" +dependencies = [ + "arrayvec", + "euclid", + "num-traits", +] + +[[package]] +name = "lyon_path" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c08a606c7a59638d6c6aa18ac91a06aa9fb5f765a7efb27e6a4da58700740d7" +dependencies = [ + "lyon_geom", + "num-traits", +] + +[[package]] +name = "lyon_tessellation" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579d42360a4b09846eff2feef28f538696c7d6c7439bfa65874ff3cbe0951b2c" +dependencies = [ + "float_next_after", + "lyon_path", + "num-traits", +] + [[package]] name = "mach2" version = "0.4.2" @@ -2703,6 +2778,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -3463,6 +3539,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -3548,6 +3630,16 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20e16a0f46cf5fd675563ef54f26e83e20f2366bcf027bcb3cc3ed2b98aaf2ca" +[[package]] +name = "svgtypes" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71499ff2d42f59d26edb21369a308ede691421f79ebc0f001e2b1fd3a7c9e52" +dependencies = [ + "kurbo", + "siphasher", +] + [[package]] name = "syn" version = "1.0.109" @@ -3611,6 +3703,7 @@ name = "the-labyrinth-of-echoes" version = "0.0.3" dependencies = [ "bevy", + "bevy_prototype_lyon", "hexx", "log", "rand", diff --git a/Cargo.toml b/Cargo.toml index 322c41b..939ba28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ tracing = { version = "0.1", features = [ "release_max_level_warn", ] } hexx = { version = "0.18", features = ["bevy_reflect"] } +bevy_prototype_lyon = "0.12" [features] default = [ diff --git a/src/grid/grid.rs b/src/grid/grid.rs index 69c4563..8cf920b 100644 --- a/src/grid/grid.rs +++ b/src/grid/grid.rs @@ -1,4 +1,4 @@ -use super::tile::spawn_tiles; +use super::tile::{draw_walls, spawn_tiles}; use bevy::{ ecs::{system::RunSystemOnce, world::Command}, prelude::*, @@ -14,12 +14,6 @@ pub fn spawn_grid(world: &mut World) { GridSettings::default().apply(world); } -#[derive(Debug, Reflect, Resource)] -#[reflect(Resource)] -pub struct Grid { - pub layout: HexLayout, -} - #[derive(Debug, Reflect, Resource, Deref, DerefMut)] #[reflect(Resource)] struct RotationTimer(Timer); @@ -43,10 +37,17 @@ 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_with(self, spawn_tiles); + world.run_system_once(draw_walls); } } +#[derive(Debug, Reflect, Resource)] +#[reflect(Resource)] +pub struct Grid { + pub layout: HexLayout, +} + impl Default for Grid { fn default() -> Self { Self::new(20., HexOrientation::Flat) diff --git a/src/grid/tile.rs b/src/grid/tile.rs index 7699604..af7def6 100644 --- a/src/grid/tile.rs +++ b/src/grid/tile.rs @@ -10,7 +10,9 @@ use bevy::{ }, utils::hashbrown::HashMap, }; +use bevy_prototype_lyon::{entity::ShapeBundle, geometry::GeometryBuilder, shapes::Line}; use hexx::{Hex, HexLayout, PlaneMeshBuilder}; +use rand::{thread_rng, Rng}; pub(super) fn plugin(_app: &mut App) {} @@ -33,8 +35,16 @@ pub fn spawn_tiles( let mesh = hexagonal_plane(&grid.layout); let mesh_handle = meshes.add(mesh); + let mut rng = thread_rng(); + for hex_pos in Hex::ZERO.range(config.radius) { let world_pos = grid.layout.hex_to_world_pos(hex_pos); + let mut walls = HashMap::new(); + + for dir in HexDirection::ALL { + walls.insert(dir, rng.gen_bool(0.5)); + } + commands.spawn(( Name::new(format!("Tile: ({}, {})", world_pos.x, world_pos.y)), ColorMesh2dBundle { @@ -45,7 +55,7 @@ pub fn spawn_tiles( }, Tile { position: hex_pos, - ..default() + walls, }, )); } @@ -54,7 +64,7 @@ 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 + // .with_scale(Vec3::splat(0.9)) // border .center_aligned() .build(); @@ -67,3 +77,53 @@ fn hexagonal_plane(hex_layout: &HexLayout) -> Mesh { .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, mesh_info.uvs) .with_inserted_indices(Indices::U16(mesh_info.indices)) } + +fn hex_corner_positions(layout: &HexLayout, hex: Hex) -> [Vec2; 6] { + let center = layout.hex_to_world_pos(hex); + let mut corners = [Vec2::ZERO; 6]; + for (idx, corner) in corners.iter_mut().enumerate() { + let andgle_deg = 60. * idx as f32; // FIX: + let andgle_rad = andgle_deg.to_radians(); + let size = layout.hex_size; + *corner = center + Vec2::new(size.x * andgle_rad.cos(), size.y * andgle_rad.sin()); + } + corners +} + +pub fn draw_walls( + mut commands: Commands, + tile_query: Query<(Entity, &Tile)>, + + mut materials: ResMut>, + grid: Res, +) { + let default_material = materials.add(Color::BLACK); + + for (entity, tile) in tile_query.iter() { + let corners = hex_corner_positions(&grid.layout, tile.position); + + for (dir, has_wall) in &tile.walls { + if *has_wall { + let direction_idx = *dir as usize; + let cornder1 = direction_idx; + let cornder2 = (direction_idx + 1) % 6; + + let start_pos = corners[cornder1]; + let end_pos = corners[cornder2]; + + let line = Line(start_pos, end_pos); + let wall_entity = commands + .spawn(( + Name::new("Wall"), + ShapeBundle { + path: GeometryBuilder::build_as(&line), + material: default_material.clone(), + ..default() + }, + )) + .id(); + commands.entity(entity).add_child(wall_entity); + } + } + } +}