mirror of
https://github.com/kristoferssolo/Qualification-Thesis.git
synced 2026-03-22 00:26:32 +00:00
feat(examples): add code snippets
This commit is contained in:
35
assets/code/hexlab/generation.rs
Normal file
35
assets/code/hexlab/generation.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
pub fn generate_backtracking(
|
||||
maze: &mut HexMaze,
|
||||
start_pos: Option<Hex>,
|
||||
seed: Option<u64>,
|
||||
) {
|
||||
if maze.is_empty() {
|
||||
return;
|
||||
}
|
||||
let start = start_pos.unwrap_or(Hex::ZERO);
|
||||
let mut visited = HashSet::new();
|
||||
let mut rng: Box<dyn RngCore> = seed.map_or_else(
|
||||
|| Box::new(thread_rng()) as Box<dyn RngCore>,
|
||||
|seed| Box::new(ChaCha8Rng::seed_from_u64(seed)) as Box<dyn RngCore>,
|
||||
);
|
||||
recursive_backtrack(maze, start, &mut visited, &mut rng);
|
||||
}
|
||||
|
||||
fn recursive_backtrack<R: Rng>(
|
||||
maze: &mut HexMaze,
|
||||
current: Hex,
|
||||
visited: &mut HashSet<Hex>,
|
||||
rng: &mut R,
|
||||
) {
|
||||
visited.insert(current);
|
||||
let mut directions = EdgeDirection::ALL_DIRECTIONS;
|
||||
directions.shuffle(rng);
|
||||
for direction in directions {
|
||||
let neighbor = current + direction;
|
||||
if maze.get_tile(&neighbor).is_some() && !visited.contains(&neighbor) {
|
||||
maze.remove_tile_wall(¤t, direction);
|
||||
maze.remove_tile_wall(&neighbor, direction.const_neg());
|
||||
recursive_backtrack(maze, neighbor, visited, rng);
|
||||
}
|
||||
}
|
||||
}
|
||||
32
assets/code/hexlab/structs.rs
Normal file
32
assets/code/hexlab/structs.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
#[derive(Default)]
|
||||
pub struct MazeBuilder {
|
||||
radius: Option<u32>,
|
||||
seed: Option<u64>,
|
||||
generator_type: GeneratorType,
|
||||
start_position: Option<Hex>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub enum GeneratorType {
|
||||
#[default]
|
||||
RecursiveBacktracking,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||
pub struct HexMaze(HashMap<Hex, HexTile>);
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "bevy", derive(Reflect, Component))]
|
||||
#[cfg_attr(feature = "bevy", reflect(Component))]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||
pub struct HexTile {
|
||||
pub(crate) pos: Hex,
|
||||
pub(crate) walls: Walls,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "bevy", derive(Reflect, Component))]
|
||||
#[cfg_attr(feature = "bevy", reflect(Component))]
|
||||
pub struct Walls(u8);
|
||||
32
assets/code/maze-ascension/components.rs
Normal file
32
assets/code/maze-ascension/components.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
#[derive(Component, Default)]
|
||||
pub struct Music;
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct SoundEffect;
|
||||
|
||||
#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Default, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct Player;
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct MovementController {
|
||||
pub intent: Vec2,
|
||||
pub max_speed: f32,
|
||||
}
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct PlayerAnimation {
|
||||
timer: Timer,
|
||||
frame: usize,
|
||||
state: PlayerAnimationState,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct InteractionPalette {
|
||||
pub none: Color,
|
||||
pub hovered: Color,
|
||||
pub pressed: Color,
|
||||
}
|
||||
141
assets/code/maze-ascension/maze_generation.rs
Normal file
141
assets/code/maze-ascension/maze_generation.rs
Normal file
@@ -0,0 +1,141 @@
|
||||
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,
|
||||
) {
|
||||
dbg!(tile);
|
||||
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)
|
||||
}
|
||||
1
assets/code/rustfmt.toml
Normal file
1
assets/code/rustfmt.toml
Normal file
@@ -0,0 +1 @@
|
||||
max_width = 80
|
||||
Reference in New Issue
Block a user