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};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_plugins(ShapePlugin);
|
||||
app.add_systems(Startup, setup_system);
|
||||
pub struct HexGrid;
|
||||
|
||||
impl Plugin for HexGrid {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins(ShapePlugin);
|
||||
app.add_systems(Startup, setup_system);
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_system(mut commands: Commands) {
|
||||
pub(super) fn setup_system(mut commands: Commands) {
|
||||
let radius = 5;
|
||||
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")]
|
||||
mod dev_tools;
|
||||
#[cfg(not(feature = "demo"))]
|
||||
mod grid;
|
||||
mod hex;
|
||||
mod hexgrid;
|
||||
mod screens;
|
||||
mod theme;
|
||||
|
||||
@ -64,8 +63,7 @@ impl Plugin for AppPlugin {
|
||||
#[cfg(feature = "demo")]
|
||||
demo::plugin,
|
||||
#[cfg(not(feature = "demo"))]
|
||||
// grid::plugin,
|
||||
hex::plugin,
|
||||
hexgrid::HexGrid,
|
||||
screens::plugin,
|
||||
theme::plugin,
|
||||
));
|
||||
|
||||
@ -5,7 +5,7 @@ use bevy::{input::common_conditions::input_just_pressed, prelude::*};
|
||||
#[cfg(feature = "demo")]
|
||||
use crate::demo::level::spawn_level as spawn_level_command;
|
||||
#[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};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user