mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
refactor(grid): make it a Plugin
This commit is contained in:
parent
f11b701ec3
commit
0ee94c826a
@ -1,98 +0,0 @@
|
|||||||
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) {
|
|
||||||
app.insert_resource(Msaa::Sample4);
|
|
||||||
app.add_plugins(ShapePlugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_grid(world: &mut World) {
|
|
||||||
world.init_resource::<Grid>();
|
|
||||||
world.init_resource::<RotationTimer>();
|
|
||||||
GridSettings::default().apply(world);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Reflect, Resource, Deref, DerefMut)]
|
|
||||||
#[reflect(Resource)]
|
|
||||||
struct RotationTimer(Timer);
|
|
||||||
|
|
||||||
impl Default for RotationTimer {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self(Timer::new(Duration::from_secs_f32(0.5), TimerMode::Once))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Reflect)]
|
|
||||||
pub struct GridSettings {
|
|
||||||
pub radius: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for GridSettings {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { radius: 10 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(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 {
|
|
||||||
pub layout: HexLayout,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Grid {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new(20., HexOrientation::Flat)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Grid {
|
|
||||||
pub fn new(hex_size: f32, orientation: HexOrientation) -> Self {
|
|
||||||
Self {
|
|
||||||
layout: HexLayout {
|
|
||||||
hex_size: Vec2::splat(hex_size),
|
|
||||||
orientation,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
use bevy::prelude::*;
|
|
||||||
pub mod direction;
|
|
||||||
pub mod grid;
|
|
||||||
pub mod tile;
|
|
||||||
|
|
||||||
pub(super) fn plugin(app: &mut App) {
|
|
||||||
app.add_plugins((direction::plugin, tile::plugin, grid::plugin));
|
|
||||||
}
|
|
||||||
128
src/grid/tile.rs
128
src/grid/tile.rs
@ -1,128 +0,0 @@
|
|||||||
use super::{
|
|
||||||
direction::HexDirection,
|
|
||||||
grid::{Grid, GridSettings},
|
|
||||||
};
|
|
||||||
use bevy::{
|
|
||||||
prelude::*,
|
|
||||||
render::{
|
|
||||||
mesh::{Indices, PrimitiveTopology},
|
|
||||||
render_asset::RenderAssetUsages,
|
|
||||||
},
|
|
||||||
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) {}
|
|
||||||
|
|
||||||
#[derive(Debug, Reflect, Component, Default)]
|
|
||||||
#[reflect(Component)]
|
|
||||||
pub struct Tile {
|
|
||||||
pub position: Hex,
|
|
||||||
pub walls: HashMap<HexDirection, bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_tiles(
|
|
||||||
config: In<GridSettings>,
|
|
||||||
mut commands: Commands,
|
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
||||||
grid: Res<Grid>,
|
|
||||||
) {
|
|
||||||
let default_material = materials.add(Color::WHITE);
|
|
||||||
|
|
||||||
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 {
|
|
||||||
mesh: mesh_handle.clone().into(),
|
|
||||||
transform: Transform::from_xyz(world_pos.x, world_pos.y, 0.),
|
|
||||||
material: default_material.clone(),
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
Tile {
|
|
||||||
position: hex_pos,
|
|
||||||
walls,
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hexagonal_plane(hex_layout: &HexLayout) -> Mesh {
|
|
||||||
let mesh_info = PlaneMeshBuilder::new(hex_layout)
|
|
||||||
.facing(Vec3::Z)
|
|
||||||
.center_aligned()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Mesh::new(
|
|
||||||
PrimitiveTopology::TriangleList,
|
|
||||||
RenderAssetUsages::RENDER_WORLD,
|
|
||||||
)
|
|
||||||
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, mesh_info.vertices)
|
|
||||||
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, mesh_info.normals)
|
|
||||||
.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<Assets<ColorMaterial>>,
|
|
||||||
grid: Res<Grid>,
|
|
||||||
) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -8,12 +8,16 @@ use bevy_prototype_lyon::{
|
|||||||
};
|
};
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
pub(super) fn plugin(app: &mut App) {
|
pub struct HexGrid;
|
||||||
|
|
||||||
|
impl Plugin for HexGrid {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
app.add_plugins(ShapePlugin);
|
app.add_plugins(ShapePlugin);
|
||||||
app.add_systems(Startup, setup_system);
|
app.add_systems(Startup, setup_system);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_system(mut commands: Commands) {
|
pub(super) fn setup_system(mut commands: Commands) {
|
||||||
let radius = 5;
|
let radius = 5;
|
||||||
let hex_positions = generate_hex_grix(radius);
|
let hex_positions = generate_hex_grix(radius);
|
||||||
|
|
||||||
25
src/hexgrid/mod.rs
Normal file
25
src/hexgrid/mod.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use bevy::{
|
||||||
|
ecs::{system::RunSystemOnce, world::Command},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
use bevy_prototype_lyon::plugin::ShapePlugin;
|
||||||
|
use grid::setup_system;
|
||||||
|
pub mod grid;
|
||||||
|
|
||||||
|
pub struct HexGrid;
|
||||||
|
|
||||||
|
impl Plugin for HexGrid {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_plugins(ShapePlugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for HexGrid {
|
||||||
|
fn apply(self, world: &mut World) {
|
||||||
|
world.run_system_once(setup_system);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_grid(world: &mut World) {
|
||||||
|
HexGrid.apply(world);
|
||||||
|
}
|
||||||
@ -5,8 +5,7 @@ mod demo;
|
|||||||
#[cfg(feature = "dev")]
|
#[cfg(feature = "dev")]
|
||||||
mod dev_tools;
|
mod dev_tools;
|
||||||
#[cfg(not(feature = "demo"))]
|
#[cfg(not(feature = "demo"))]
|
||||||
mod grid;
|
mod hexgrid;
|
||||||
mod hex;
|
|
||||||
mod screens;
|
mod screens;
|
||||||
mod theme;
|
mod theme;
|
||||||
|
|
||||||
@ -64,8 +63,7 @@ impl Plugin for AppPlugin {
|
|||||||
#[cfg(feature = "demo")]
|
#[cfg(feature = "demo")]
|
||||||
demo::plugin,
|
demo::plugin,
|
||||||
#[cfg(not(feature = "demo"))]
|
#[cfg(not(feature = "demo"))]
|
||||||
// grid::plugin,
|
hexgrid::HexGrid,
|
||||||
hex::plugin,
|
|
||||||
screens::plugin,
|
screens::plugin,
|
||||||
theme::plugin,
|
theme::plugin,
|
||||||
));
|
));
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use bevy::{input::common_conditions::input_just_pressed, prelude::*};
|
|||||||
#[cfg(feature = "demo")]
|
#[cfg(feature = "demo")]
|
||||||
use crate::demo::level::spawn_level as spawn_level_command;
|
use crate::demo::level::spawn_level as spawn_level_command;
|
||||||
#[cfg(not(feature = "demo"))]
|
#[cfg(not(feature = "demo"))]
|
||||||
use crate::grid::grid::spawn_grid as spawn_level_command;
|
use crate::hexgrid::spawn_grid as spawn_level_command;
|
||||||
use crate::{asset_tracking::LoadResource, audio::Music, screens::Screen};
|
use crate::{asset_tracking::LoadResource, audio::Music, screens::Screen};
|
||||||
|
|
||||||
pub(super) fn plugin(app: &mut App) {
|
pub(super) fn plugin(app: &mut App) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user