mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
refactor(maze): reorganize maze module code
This commit is contained in:
parent
34f85be4ef
commit
0ca94082a9
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -2673,10 +2673,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maze-ascension"
|
name = "maze-ascension"
|
||||||
version = "0.1.0"
|
version = "0.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy",
|
"bevy",
|
||||||
"bevy-inspector-egui",
|
"bevy-inspector-egui",
|
||||||
|
"bevy_egui",
|
||||||
"hexlab",
|
"hexlab",
|
||||||
"hexx",
|
"hexx",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "maze-ascension"
|
name = "maze-ascension"
|
||||||
authors = ["Kristofers Solo <dev@kristofers.xyz>"]
|
authors = ["Kristofers Solo <dev@kristofers.xyz>"]
|
||||||
version = "0.1.0"
|
version = "0.0.6"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -20,6 +20,7 @@ tracing = { version = "0.1", features = [
|
|||||||
hexx = { version = "0.18", features = ["bevy_reflect", "grid"] }
|
hexx = { version = "0.18", features = ["bevy_reflect", "grid"] }
|
||||||
hexlab = { version = "0.1", features = ["bevy"] }
|
hexlab = { version = "0.1", features = ["bevy"] }
|
||||||
bevy-inspector-egui = { version = "0.27", optional = true }
|
bevy-inspector-egui = { version = "0.27", optional = true }
|
||||||
|
bevy_egui = { version = "0.30", optional = true }
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@ -32,6 +33,7 @@ dev = [
|
|||||||
"bevy/dynamic_linking",
|
"bevy/dynamic_linking",
|
||||||
"bevy/bevy_dev_tools",
|
"bevy/bevy_dev_tools",
|
||||||
"dep:bevy-inspector-egui",
|
"dep:bevy-inspector-egui",
|
||||||
|
"dep:bevy_egui",
|
||||||
]
|
]
|
||||||
dev_native = [
|
dev_native = [
|
||||||
"dev",
|
"dev",
|
||||||
|
|||||||
56
src/maze/assets.rs
Normal file
56
src/maze/assets.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
use std::f32::consts::FRAC_PI_2;
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
resources::{HEX_SIZE, WALL_SIZE},
|
||||||
|
MazeConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) struct MazeAssets {
|
||||||
|
pub(crate) hex_mesh: Handle<Mesh>,
|
||||||
|
pub(crate) wall_mesh: Handle<Mesh>,
|
||||||
|
pub(crate) hex_material: Handle<StandardMaterial>,
|
||||||
|
pub(crate) wall_material: Handle<StandardMaterial>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_base_assets(
|
||||||
|
meshes: &mut ResMut<Assets<Mesh>>,
|
||||||
|
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||||
|
config: &Res<MazeConfig>,
|
||||||
|
) -> MazeAssets {
|
||||||
|
MazeAssets {
|
||||||
|
hex_mesh: meshes.add(generate_hex_mesh(HEX_SIZE, config.height)),
|
||||||
|
wall_mesh: meshes.add(generate_square_mesh(HEX_SIZE)),
|
||||||
|
hex_material: materials.add(white_material()),
|
||||||
|
wall_material: materials.add(Color::BLACK),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_hex_mesh(radius: f32, depth: f32) -> Mesh {
|
||||||
|
let hexagon = RegularPolygon {
|
||||||
|
sides: 6,
|
||||||
|
circumcircle: Circle::new(radius),
|
||||||
|
};
|
||||||
|
let prism_shape = Extrusion::new(hexagon, depth);
|
||||||
|
let rotation = Quat::from_rotation_x(FRAC_PI_2);
|
||||||
|
|
||||||
|
Mesh::from(prism_shape).rotated_by(rotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_square_mesh(depth: f32) -> Mesh {
|
||||||
|
let square = Rectangle::new(WALL_SIZE, WALL_SIZE);
|
||||||
|
let rectangular_prism = Extrusion::new(square, depth);
|
||||||
|
let rotation = Quat::from_rotation_x(FRAC_PI_2);
|
||||||
|
|
||||||
|
Mesh::from(rectangular_prism).rotated_by(rotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn white_material() -> StandardMaterial {
|
||||||
|
let val = 10.;
|
||||||
|
StandardMaterial {
|
||||||
|
base_color: Color::WHITE,
|
||||||
|
emissive: LinearRgba::new(val, val, val, val),
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/maze/components.rs
Normal file
9
src/maze/components.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Reflect, Component)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub(crate) struct MazeWall;
|
||||||
|
|
||||||
|
#[derive(Debug, Reflect, Component)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub(crate) struct MazeTile;
|
||||||
@ -1,8 +1,12 @@
|
|||||||
use bevy::{ecs::world::Command, prelude::*};
|
use bevy::{ecs::world::Command, prelude::*};
|
||||||
use plugin::MazePlugin;
|
use plugin::MazePlugin;
|
||||||
|
mod assets;
|
||||||
|
mod components;
|
||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
pub mod prism;
|
mod resources;
|
||||||
pub mod resource;
|
mod systems;
|
||||||
|
|
||||||
|
pub use resources::MazeConfig;
|
||||||
|
|
||||||
pub fn spawn_grid(world: &mut World) {
|
pub fn spawn_grid(world: &mut World) {
|
||||||
MazePlugin.apply(world);
|
MazePlugin.apply(world);
|
||||||
|
|||||||
@ -3,27 +3,19 @@ use bevy::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::prism;
|
use super::{resources::Layout, systems, MazeConfig};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct MazePlugin;
|
pub(crate) struct MazePlugin;
|
||||||
|
|
||||||
impl Plugin for MazePlugin {
|
impl Plugin for MazePlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_plugins(prism::plugin);
|
app.init_resource::<MazeConfig>().init_resource::<Layout>();
|
||||||
// app.add_plugins(grid::plugin);
|
|
||||||
// app.insert_resource(AmbientLight {
|
|
||||||
// brightness: f32::MAX,
|
|
||||||
// color: Color::WHITE,
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command for MazePlugin {
|
impl Command for MazePlugin {
|
||||||
fn apply(self, world: &mut World) {
|
fn apply(self, world: &mut World) {
|
||||||
// world.run_system_once(spawn_hex_grid);
|
world.run_system_once(systems::setup::setup);
|
||||||
// world.run_system_once(generate_maze);
|
|
||||||
// world.run_system_once(render_maze);
|
|
||||||
world.run_system_once(prism::setup);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,154 +0,0 @@
|
|||||||
use super::resource::{Layout, MazeConfig, HEX_SIZE};
|
|
||||||
use bevy::prelude::*;
|
|
||||||
use core::f32;
|
|
||||||
use hexlab::prelude::*;
|
|
||||||
use hexx::{HexLayout, HexOrientation};
|
|
||||||
use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6};
|
|
||||||
|
|
||||||
pub(super) fn plugin(app: &mut App) {
|
|
||||||
app.init_resource::<MazeConfig>();
|
|
||||||
app.init_resource::<Layout>();
|
|
||||||
}
|
|
||||||
const WALL_SIZE: f32 = 1.0;
|
|
||||||
|
|
||||||
pub(super) fn setup(
|
|
||||||
mut commands: Commands,
|
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
||||||
config: Res<MazeConfig>,
|
|
||||||
layout: Res<Layout>,
|
|
||||||
) {
|
|
||||||
let maze = MazeBuilder::new()
|
|
||||||
.with_radius(config.radius)
|
|
||||||
// .with_seed(0)
|
|
||||||
.with_generator(GeneratorType::RecursiveBacktracking)
|
|
||||||
.build()
|
|
||||||
.expect("Something went wrong while creating maze");
|
|
||||||
|
|
||||||
let assets = create_base_assets(&mut meshes, &mut materials, &config);
|
|
||||||
commands
|
|
||||||
.spawn((
|
|
||||||
Name::new("Floor"),
|
|
||||||
SpatialBundle {
|
|
||||||
transform: Transform::from_translation(Vec3::ZERO),
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|parent| {
|
|
||||||
for tile in maze.values() {
|
|
||||||
spawn_single_hex_tile(parent, &assets, tile, &layout.0, config.height)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spawn_single_hex_tile(
|
|
||||||
parent: &mut ChildBuilder,
|
|
||||||
assets: &MazeAssets,
|
|
||||||
tile: &HexTile,
|
|
||||||
layout: &HexLayout,
|
|
||||||
hex_height: f32,
|
|
||||||
) {
|
|
||||||
let world_pos = tile.to_vec3(layout);
|
|
||||||
let rotation = match layout.orientation {
|
|
||||||
HexOrientation::Pointy => Quat::from_rotation_y(0.0),
|
|
||||||
HexOrientation::Flat => Quat::from_rotation_y(FRAC_PI_6), // 30 degrees rotation
|
|
||||||
};
|
|
||||||
|
|
||||||
parent
|
|
||||||
.spawn((
|
|
||||||
Name::new(format!("Hex {}", tile.to_string())),
|
|
||||||
PbrBundle {
|
|
||||||
mesh: assets.hex_mesh.clone(),
|
|
||||||
material: assets.hex_material.clone(),
|
|
||||||
transform: Transform::from_translation(world_pos).with_rotation(rotation),
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|parent| spawn_walls(parent, assets, hex_height / 2., &tile.walls()));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spawn_walls(parent: &mut ChildBuilder, assets: &MazeAssets, y_offset: f32, walls: &Walls) {
|
|
||||||
let z_rotation = Quat::from_rotation_z(-FRAC_PI_2);
|
|
||||||
|
|
||||||
for i in 0..6 {
|
|
||||||
if !walls.contains(i) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let wall_angle = -FRAC_PI_3 * i as f32;
|
|
||||||
|
|
||||||
let x_offset = (HEX_SIZE - WALL_SIZE) * f32::cos(wall_angle);
|
|
||||||
let z_offset = (HEX_SIZE - WALL_SIZE) * f32::sin(wall_angle);
|
|
||||||
let pos = Vec3::new(x_offset, y_offset, z_offset);
|
|
||||||
|
|
||||||
let x_rotation = Quat::from_rotation_x(wall_angle + FRAC_PI_2);
|
|
||||||
let final_rotation = z_rotation * x_rotation;
|
|
||||||
|
|
||||||
spawn_single_wall(parent, assets, final_rotation, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spawn_single_wall(
|
|
||||||
parent: &mut ChildBuilder,
|
|
||||||
asstets: &MazeAssets,
|
|
||||||
rotation: Quat,
|
|
||||||
offset: Vec3,
|
|
||||||
) {
|
|
||||||
parent.spawn((
|
|
||||||
Name::new("Wall"),
|
|
||||||
PbrBundle {
|
|
||||||
mesh: asstets.wall_mesh.clone(),
|
|
||||||
material: asstets.wall_material.clone(),
|
|
||||||
transform: Transform::from_translation(offset).with_rotation(rotation),
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_base_assets(
|
|
||||||
meshes: &mut ResMut<Assets<Mesh>>,
|
|
||||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
|
||||||
config: &Res<MazeConfig>,
|
|
||||||
) -> MazeAssets {
|
|
||||||
MazeAssets {
|
|
||||||
hex_mesh: meshes.add(generate_hex_mesh(HEX_SIZE, config.height)),
|
|
||||||
wall_mesh: meshes.add(generate_square_mesh(HEX_SIZE)),
|
|
||||||
hex_material: materials.add(white_material()),
|
|
||||||
wall_material: materials.add(Color::BLACK),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_hex_mesh(radius: f32, depth: f32) -> Mesh {
|
|
||||||
let hexagon = RegularPolygon {
|
|
||||||
sides: 6,
|
|
||||||
circumcircle: Circle::new(radius),
|
|
||||||
};
|
|
||||||
let prism_shape = Extrusion::new(hexagon, depth);
|
|
||||||
let rotation = Quat::from_rotation_x(FRAC_PI_2);
|
|
||||||
|
|
||||||
Mesh::from(prism_shape).rotated_by(rotation)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_square_mesh(depth: f32) -> Mesh {
|
|
||||||
let square = Rectangle::new(WALL_SIZE, WALL_SIZE);
|
|
||||||
let rectangular_prism = Extrusion::new(square, depth);
|
|
||||||
let rotation = Quat::from_rotation_x(FRAC_PI_2);
|
|
||||||
|
|
||||||
Mesh::from(rectangular_prism).rotated_by(rotation)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn white_material() -> StandardMaterial {
|
|
||||||
let val = 10.;
|
|
||||||
StandardMaterial {
|
|
||||||
base_color: Color::WHITE,
|
|
||||||
emissive: LinearRgba::new(val, val, val, val),
|
|
||||||
..default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MazeAssets {
|
|
||||||
hex_mesh: Handle<Mesh>,
|
|
||||||
wall_mesh: Handle<Mesh>,
|
|
||||||
hex_material: Handle<StandardMaterial>,
|
|
||||||
wall_material: Handle<StandardMaterial>,
|
|
||||||
}
|
|
||||||
@ -3,6 +3,7 @@ use hexx::{Hex, HexLayout, HexOrientation};
|
|||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
pub(crate) const HEX_SIZE: f32 = 6.;
|
pub(crate) const HEX_SIZE: f32 = 6.;
|
||||||
|
pub(crate) const WALL_SIZE: f32 = 1.0;
|
||||||
|
|
||||||
#[derive(Debug, Reflect, Resource)]
|
#[derive(Debug, Reflect, Resource)]
|
||||||
#[reflect(Resource)]
|
#[reflect(Resource)]
|
||||||
2
src/maze/systems/mod.rs
Normal file
2
src/maze/systems/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod setup;
|
||||||
|
mod spawn;
|
||||||
36
src/maze/systems/setup.rs
Normal file
36
src/maze/systems/setup.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use hexlab::{GeneratorType, MazeBuilder};
|
||||||
|
|
||||||
|
use crate::maze::{assets::create_base_assets, resources::Layout, MazeConfig};
|
||||||
|
|
||||||
|
use super::spawn::spawn_single_hex_tile;
|
||||||
|
|
||||||
|
pub(crate) fn setup(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
|
config: Res<MazeConfig>,
|
||||||
|
layout: Res<Layout>,
|
||||||
|
) {
|
||||||
|
let maze = MazeBuilder::new()
|
||||||
|
.with_radius(config.radius)
|
||||||
|
// .with_seed(0)
|
||||||
|
.with_generator(GeneratorType::RecursiveBacktracking)
|
||||||
|
.build()
|
||||||
|
.expect("Something went wrong while creating maze");
|
||||||
|
|
||||||
|
let assets = create_base_assets(&mut meshes, &mut materials, &config);
|
||||||
|
commands
|
||||||
|
.spawn((
|
||||||
|
Name::new("Floor"),
|
||||||
|
SpatialBundle {
|
||||||
|
transform: Transform::from_translation(Vec3::ZERO),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.with_children(|parent| {
|
||||||
|
for tile in maze.values() {
|
||||||
|
spawn_single_hex_tile(parent, &assets, tile, &layout.0, config.height)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
74
src/maze/systems/spawn.rs
Normal file
74
src/maze/systems/spawn.rs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6};
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use hexlab::prelude::*;
|
||||||
|
use hexx::HexOrientation;
|
||||||
|
|
||||||
|
use crate::maze::{
|
||||||
|
assets::MazeAssets,
|
||||||
|
resources::{HEX_SIZE, WALL_SIZE},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(super) fn spawn_single_hex_tile(
|
||||||
|
parent: &mut ChildBuilder,
|
||||||
|
assets: &MazeAssets,
|
||||||
|
tile: &HexTile,
|
||||||
|
layout: &HexLayout,
|
||||||
|
hex_height: f32,
|
||||||
|
) {
|
||||||
|
let world_pos = tile.to_vec3(layout);
|
||||||
|
let rotation = match layout.orientation {
|
||||||
|
HexOrientation::Pointy => Quat::from_rotation_y(0.0),
|
||||||
|
HexOrientation::Flat => Quat::from_rotation_y(FRAC_PI_6), // 30 degrees rotation
|
||||||
|
};
|
||||||
|
|
||||||
|
parent
|
||||||
|
.spawn((
|
||||||
|
Name::new(format!("Hex {}", tile.to_string())),
|
||||||
|
PbrBundle {
|
||||||
|
mesh: assets.hex_mesh.clone(),
|
||||||
|
material: assets.hex_material.clone(),
|
||||||
|
transform: Transform::from_translation(world_pos).with_rotation(rotation),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.with_children(|parent| spawn_walls(parent, assets, hex_height / 2., &tile.walls()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_walls(parent: &mut ChildBuilder, assets: &MazeAssets, y_offset: f32, walls: &Walls) {
|
||||||
|
let z_rotation = Quat::from_rotation_z(-FRAC_PI_2);
|
||||||
|
|
||||||
|
for i in 0..6 {
|
||||||
|
if !walls.contains(i) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let wall_angle = -FRAC_PI_3 * i as f32;
|
||||||
|
|
||||||
|
let x_offset = (HEX_SIZE - WALL_SIZE) * f32::cos(wall_angle);
|
||||||
|
let z_offset = (HEX_SIZE - WALL_SIZE) * f32::sin(wall_angle);
|
||||||
|
let pos = Vec3::new(x_offset, y_offset, z_offset);
|
||||||
|
|
||||||
|
let x_rotation = Quat::from_rotation_x(wall_angle + FRAC_PI_2);
|
||||||
|
let final_rotation = z_rotation * x_rotation;
|
||||||
|
|
||||||
|
spawn_single_wall(parent, assets, final_rotation, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_single_wall(
|
||||||
|
parent: &mut ChildBuilder,
|
||||||
|
asstets: &MazeAssets,
|
||||||
|
rotation: Quat,
|
||||||
|
offset: Vec3,
|
||||||
|
) {
|
||||||
|
parent.spawn((
|
||||||
|
Name::new("Wall"),
|
||||||
|
PbrBundle {
|
||||||
|
mesh: asstets.wall_mesh.clone(),
|
||||||
|
material: asstets.wall_material.clone(),
|
||||||
|
transform: Transform::from_translation(offset).with_rotation(rotation),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user