mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
feat(player): add collision check
This commit is contained in:
parent
6bdfc2f672
commit
30d6cf5fba
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2590,8 +2590,6 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "hexlab"
|
name = "hexlab"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9414db96618050e085e36c92ed9e87f0140d3a611914764ee73c7c0e4ebaa2de"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy",
|
"bevy",
|
||||||
"hexx",
|
"hexx",
|
||||||
|
|||||||
@ -18,7 +18,7 @@ tracing = { version = "0.1", features = [
|
|||||||
"release_max_level_warn",
|
"release_max_level_warn",
|
||||||
] }
|
] }
|
||||||
hexx = { version = "0.19", features = ["bevy_reflect", "grid"] }
|
hexx = { version = "0.19", features = ["bevy_reflect", "grid"] }
|
||||||
hexlab = { version = "0.2", features = ["bevy"] }
|
hexlab = { path = "../hexlab", features = ["bevy"] }
|
||||||
bevy-inspector-egui = { version = "0.28", optional = true }
|
bevy-inspector-egui = { version = "0.28", optional = true }
|
||||||
bevy_egui = { version = "0.31", optional = true }
|
bevy_egui = { version = "0.31", optional = true }
|
||||||
thiserror = "2.0"
|
thiserror = "2.0"
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use hexlab::HexMaze;
|
||||||
|
|
||||||
#[derive(Debug, Reflect, Component)]
|
#[derive(Debug, Reflect, Component)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub(crate) struct MazeFloor(pub(crate) u8);
|
pub(crate) struct Maze(pub(crate) HexMaze);
|
||||||
|
|
||||||
#[derive(Debug, Reflect, Component)]
|
#[derive(Debug, Reflect, Component)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub(crate) struct MazeTile;
|
pub(crate) struct Floor(pub(crate) u8);
|
||||||
|
|
||||||
#[derive(Debug, Reflect, Component)]
|
#[derive(Debug, Reflect, Component)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub(crate) struct MazeWall;
|
pub(crate) struct Tile;
|
||||||
|
|
||||||
|
#[derive(Debug, Reflect, Component)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub(crate) struct Wall;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use bevy::{ecs::system::RunSystemOnce, prelude::*};
|
use bevy::{ecs::system::RunSystemOnce, prelude::*};
|
||||||
use events::RecreateMazeEvent;
|
use events::RecreateMazeEvent;
|
||||||
mod assets;
|
mod assets;
|
||||||
mod components;
|
pub mod components;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
mod resources;
|
mod resources;
|
||||||
mod systems;
|
mod systems;
|
||||||
@ -17,5 +17,5 @@ pub(super) fn plugin(app: &mut App) {
|
|||||||
|
|
||||||
pub fn spawn_level_command(world: &mut World) {
|
pub fn spawn_level_command(world: &mut World) {
|
||||||
world.insert_resource(MazePluginLoaded);
|
world.insert_resource(MazePluginLoaded);
|
||||||
world.run_system_once(systems::setup::setup);
|
let _ = world.run_system_once(systems::setup::setup);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::maze::{components::MazeFloor, events::RecreateMazeEvent, MazeConfig};
|
use crate::maze::{components::Floor, events::RecreateMazeEvent, MazeConfig};
|
||||||
|
|
||||||
use super::setup::setup_maze;
|
use super::setup::setup_maze;
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ pub(crate) fn handle_maze_recreation_event(
|
|||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
config: Res<MazeConfig>,
|
config: Res<MazeConfig>,
|
||||||
query: Query<(Entity, &MazeFloor)>,
|
query: Query<(Entity, &Floor)>,
|
||||||
mut event_reader: EventReader<RecreateMazeEvent>,
|
mut event_reader: EventReader<RecreateMazeEvent>,
|
||||||
) {
|
) {
|
||||||
for event in event_reader.read() {
|
for event in event_reader.read() {
|
||||||
@ -18,9 +18,9 @@ pub(crate) fn handle_maze_recreation_event(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn despawn_floor(commands: &mut Commands, query: &Query<(Entity, &MazeFloor)>, floor_num: u8) {
|
fn despawn_floor(commands: &mut Commands, query: &Query<(Entity, &Floor)>, floor_num: u8) {
|
||||||
for (entity, maze_floor) in query.iter() {
|
for (entity, floor) in query.iter() {
|
||||||
if maze_floor.0 == floor_num {
|
if floor.0 == floor_num {
|
||||||
commands.entity(entity).despawn_recursive();
|
commands.entity(entity).despawn_recursive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use hexlab::{GeneratorType, MazeBuilder};
|
use hexlab::{GeneratorType, MazeBuilder};
|
||||||
|
|
||||||
use crate::maze::{assets::MazeAssets, components::MazeFloor, MazeConfig};
|
use crate::maze::{
|
||||||
|
assets::MazeAssets,
|
||||||
|
components::{Floor, Maze},
|
||||||
|
MazeConfig,
|
||||||
|
};
|
||||||
|
|
||||||
use super::spawn::spawn_single_hex_tile;
|
use super::spawn::spawn_single_hex_tile;
|
||||||
|
|
||||||
@ -31,7 +35,8 @@ pub(super) fn setup_maze(
|
|||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Name::new("Floor"),
|
Name::new("Floor"),
|
||||||
MazeFloor(1),
|
Maze(maze.clone()),
|
||||||
|
Floor(1),
|
||||||
Transform::from_translation(Vec3::ZERO),
|
Transform::from_translation(Vec3::ZERO),
|
||||||
Visibility::Visible,
|
Visibility::Visible,
|
||||||
))
|
))
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use hexx::HexOrientation;
|
|||||||
|
|
||||||
use crate::maze::{
|
use crate::maze::{
|
||||||
assets::MazeAssets,
|
assets::MazeAssets,
|
||||||
components::{MazeTile, MazeWall},
|
components::{Tile, Wall},
|
||||||
MazeConfig,
|
MazeConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ pub(super) fn spawn_single_hex_tile(
|
|||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Name::new(format!("Hex {}", tile)),
|
Name::new(format!("Hex {}", tile)),
|
||||||
MazeTile,
|
Tile,
|
||||||
Mesh3d(assets.hex_mesh.clone()),
|
Mesh3d(assets.hex_mesh.clone()),
|
||||||
MeshMaterial3d(assets.hex_material.clone()),
|
MeshMaterial3d(assets.hex_material.clone()),
|
||||||
Transform::from_translation(world_pos).with_rotation(rotation),
|
Transform::from_translation(world_pos).with_rotation(rotation),
|
||||||
@ -58,7 +58,7 @@ fn spawn_walls(parent: &mut ChildBuilder, assets: &MazeAssets, config: &MazeConf
|
|||||||
fn spawn_single_wall(parent: &mut ChildBuilder, assets: &MazeAssets, rotation: Quat, offset: Vec3) {
|
fn spawn_single_wall(parent: &mut ChildBuilder, assets: &MazeAssets, rotation: Quat, offset: Vec3) {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Name::new("Wall"),
|
Name::new("Wall"),
|
||||||
MazeWall,
|
Wall,
|
||||||
Mesh3d(assets.wall_mesh.clone()),
|
Mesh3d(assets.wall_mesh.clone()),
|
||||||
MeshMaterial3d(assets.wall_material.clone()),
|
MeshMaterial3d(assets.wall_material.clone()),
|
||||||
Transform::from_translation(offset).with_rotation(rotation),
|
Transform::from_translation(offset).with_rotation(rotation),
|
||||||
|
|||||||
@ -1,20 +1,25 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use hexx::Hex;
|
use hexx::Hex;
|
||||||
|
|
||||||
#[derive(Component, Debug, Clone, Copy, PartialEq, Reflect)]
|
#[derive(Debug, Reflect, Component)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct Player {
|
#[require(CurrentPosition, MovementSpeed, MovementTarget)]
|
||||||
pub speed: f32,
|
pub struct Player;
|
||||||
pub current_hex: Hex,
|
|
||||||
pub target_hex: Option<Hex>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Player {
|
#[derive(Debug, Reflect, Component, Deref, DerefMut, Default)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct CurrentPosition(pub Hex);
|
||||||
|
|
||||||
|
#[derive(Debug, Reflect, Component, Deref, DerefMut)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct MovementSpeed(pub f32);
|
||||||
|
|
||||||
|
impl Default for MovementSpeed {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self(50.)
|
||||||
speed: 50.,
|
|
||||||
current_hex: Hex::ZERO,
|
|
||||||
target_hex: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Reflect, Component, Deref, DerefMut, Default)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct MovementTarget(pub Option<Hex>);
|
||||||
|
|||||||
@ -10,5 +10,5 @@ pub(super) fn plugin(app: &mut App) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_player_command(world: &mut World) {
|
pub fn spawn_player_command(world: &mut World) {
|
||||||
world.run_system_once(systems::spawn::spawn_player);
|
let _ = world.run_system_once(systems::spawn::spawn_player);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,28 +1,77 @@
|
|||||||
use crate::player::components::Player;
|
use crate::{
|
||||||
|
maze::{
|
||||||
|
components::{Floor, Maze},
|
||||||
|
MazeConfig,
|
||||||
|
},
|
||||||
|
player::components::{CurrentPosition, MovementTarget, Player},
|
||||||
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use hexx::EdgeDirection;
|
use hexx::{EdgeDirection, HexOrientation};
|
||||||
|
|
||||||
const fn create_direction(key: &KeyCode) -> Option<EdgeDirection> {
|
fn create_direction(
|
||||||
match key {
|
input: &ButtonInput<KeyCode>,
|
||||||
KeyCode::KeyD => Some(EdgeDirection::FLAT_SOUTH),
|
orientation: &HexOrientation,
|
||||||
KeyCode::KeyS => Some(EdgeDirection::FLAT_NORTH_EAST),
|
) -> Option<EdgeDirection> {
|
||||||
KeyCode::KeyA => Some(EdgeDirection::FLAT_NORTH),
|
let w = input.pressed(KeyCode::KeyW);
|
||||||
KeyCode::KeyQ => Some(EdgeDirection::FLAT_NORTH_WEST),
|
let a = input.pressed(KeyCode::KeyA);
|
||||||
KeyCode::KeyW => Some(EdgeDirection::FLAT_SOUTH_WEST),
|
let s = input.pressed(KeyCode::KeyS);
|
||||||
KeyCode::KeyE => Some(EdgeDirection::FLAT_SOUTH_EAST),
|
let d = input.pressed(KeyCode::KeyD);
|
||||||
_ => None,
|
|
||||||
}
|
let direction = match orientation {
|
||||||
|
HexOrientation::Pointy => {
|
||||||
|
match (w, a, s, d) {
|
||||||
|
(true, false, false, false) => Some(EdgeDirection::POINTY_WEST), // W
|
||||||
|
(false, false, true, false) => Some(EdgeDirection::POINTY_EAST), // S
|
||||||
|
(false, true, true, false) => Some(EdgeDirection::POINTY_NORTH_EAST), // A+S
|
||||||
|
(false, false, true, true) => Some(EdgeDirection::POINTY_SOUTH_EAST), // S+D
|
||||||
|
(true, true, false, false) => Some(EdgeDirection::POINTY_NORTH_WEST), // W+A
|
||||||
|
(true, false, false, true) => Some(EdgeDirection::POINTY_SOUTH_WEST), // W+D
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HexOrientation::Flat => {
|
||||||
|
match (w, a, s, d) {
|
||||||
|
(false, true, false, false) => Some(EdgeDirection::FLAT_NORTH), // A
|
||||||
|
(false, false, false, true) => Some(EdgeDirection::FLAT_SOUTH), // D
|
||||||
|
(false, true, true, false) => Some(EdgeDirection::FLAT_NORTH_EAST), // A+S
|
||||||
|
(false, false, true, true) => Some(EdgeDirection::FLAT_SOUTH_EAST), // S+D
|
||||||
|
(true, true, false, false) => Some(EdgeDirection::FLAT_NORTH_WEST), // W+A
|
||||||
|
(true, false, false, true) => Some(EdgeDirection::FLAT_SOUTH_WEST), // W+D
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}?;
|
||||||
|
Some(direction.rotate_cw(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn player_input(input: Res<ButtonInput<KeyCode>>, mut player_query: Query<&mut Player>) {
|
pub(super) fn player_input(
|
||||||
for mut player in player_query.iter_mut() {
|
input: Res<ButtonInput<KeyCode>>,
|
||||||
if player.target_hex.is_some() {
|
mut player_query: Query<(&mut MovementTarget, &CurrentPosition), With<Player>>,
|
||||||
|
maze_query: Query<(&Maze, &Floor)>,
|
||||||
|
maze_config: Res<MazeConfig>,
|
||||||
|
) {
|
||||||
|
let Ok((maze, _floor)) = maze_query.get_single() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (mut target_pos, current_pos) in player_query.iter_mut() {
|
||||||
|
if target_pos.is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(direction) = input.get_pressed().find_map(|key| create_direction(key)) {
|
let Some(direction) = create_direction(&input, &maze_config.layout.orientation) else {
|
||||||
let next_hex = player.current_hex + direction.into_hex();
|
continue;
|
||||||
player.target_hex = Some(next_hex);
|
};
|
||||||
|
|
||||||
|
let Some(tile) = maze.0.get_tile(¤t_pos) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if tile.walls().contains(direction) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let next_hex = current_pos.0.neighbor(direction);
|
||||||
|
target_pos.0 = Some(next_hex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,32 @@
|
|||||||
use crate::{maze::MazeConfig, player::components::Player};
|
use crate::{
|
||||||
|
maze::MazeConfig,
|
||||||
|
player::components::{CurrentPosition, MovementSpeed, MovementTarget, Player},
|
||||||
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use hexx::Hex;
|
use hexx::Hex;
|
||||||
|
|
||||||
pub(super) fn player_movement(
|
pub(super) fn player_movement(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
mut player_query: Query<(&mut Player, &mut Transform)>,
|
mut query: Query<
|
||||||
|
(
|
||||||
|
&mut MovementTarget,
|
||||||
|
&MovementSpeed,
|
||||||
|
&mut CurrentPosition,
|
||||||
|
&mut Transform,
|
||||||
|
),
|
||||||
|
With<Player>,
|
||||||
|
>,
|
||||||
maze_config: Res<MazeConfig>,
|
maze_config: Res<MazeConfig>,
|
||||||
) {
|
) {
|
||||||
for (mut player, mut transform) in player_query.iter_mut() {
|
for (mut target, speed, mut current_hex, mut transform) in query.iter_mut() {
|
||||||
if let Some(target_hex) = player.target_hex {
|
if let Some(target_hex) = target.0 {
|
||||||
let current_pos = transform.translation;
|
let current_pos = transform.translation;
|
||||||
let target_pos = calculate_target_position(&maze_config, target_hex, current_pos.y);
|
let target_pos = calculate_target_position(&maze_config, target_hex, current_pos.y);
|
||||||
|
|
||||||
if should_complete_movement(current_pos, target_pos) {
|
if should_complete_movement(current_pos, target_pos) {
|
||||||
complete_movement(&mut player, &mut transform, target_pos, target_hex);
|
transform.translation = target_pos;
|
||||||
|
current_hex.0 = target_hex;
|
||||||
|
target.0 = None;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,33 +34,17 @@ pub(super) fn player_movement(
|
|||||||
&mut transform,
|
&mut transform,
|
||||||
current_pos,
|
current_pos,
|
||||||
target_pos,
|
target_pos,
|
||||||
player.speed,
|
speed.0,
|
||||||
time.delta_seconds(),
|
time.delta_secs(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_target_position(maze_config: &MazeConfig, target_hex: Hex, y: f32) -> Vec3 {
|
|
||||||
let world_pos = maze_config.layout.hex_to_world_pos(target_hex);
|
|
||||||
Vec3::new(world_pos.x, y, world_pos.y)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn should_complete_movement(current_pos: Vec3, target_pos: Vec3) -> bool {
|
fn should_complete_movement(current_pos: Vec3, target_pos: Vec3) -> bool {
|
||||||
(target_pos - current_pos).length() < 0.1
|
(target_pos - current_pos).length() < 0.1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn complete_movement(
|
|
||||||
player: &mut Player,
|
|
||||||
transform: &mut Transform,
|
|
||||||
target_pos: Vec3,
|
|
||||||
target_hex: Hex,
|
|
||||||
) {
|
|
||||||
transform.translation = target_pos;
|
|
||||||
player.current_hex = target_hex;
|
|
||||||
player.target_hex = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_position(
|
fn update_position(
|
||||||
transform: &mut Transform,
|
transform: &mut Transform,
|
||||||
current_pos: Vec3,
|
current_pos: Vec3,
|
||||||
@ -64,3 +61,8 @@ fn update_position(
|
|||||||
}
|
}
|
||||||
transform.translation += movement;
|
transform.translation += movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_target_position(maze_config: &MazeConfig, target_hex: Hex, y: f32) -> Vec3 {
|
||||||
|
let world_pos = maze_config.layout.hex_to_world_pos(target_hex);
|
||||||
|
Vec3::new(world_pos.x, y, world_pos.y)
|
||||||
|
}
|
||||||
|
|||||||
@ -2,10 +2,11 @@ use crate::{
|
|||||||
maze::MazeConfig,
|
maze::MazeConfig,
|
||||||
player::{
|
player::{
|
||||||
assets::{blue_material, generate_pill_mesh},
|
assets::{blue_material, generate_pill_mesh},
|
||||||
components::Player,
|
components::{CurrentPosition, Player},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use hexx::Hex;
|
||||||
|
|
||||||
pub fn spawn_player(
|
pub fn spawn_player(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
@ -18,12 +19,10 @@ pub fn spawn_player(
|
|||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Name::new("Player"),
|
Name::new("Player"),
|
||||||
Player::default(),
|
Player,
|
||||||
PbrBundle {
|
CurrentPosition(Hex::new(1, 1)),
|
||||||
mesh: meshes.add(generate_pill_mesh(player_radius, player_height / 2.)),
|
Mesh3d(meshes.add(generate_pill_mesh(player_radius, player_height / 2.))),
|
||||||
material: materials.add(blue_material()),
|
MeshMaterial3d(materials.add(blue_material())),
|
||||||
transform: Transform::from_xyz(0., player_height * 2., 0.),
|
Transform::from_xyz(0., player_height * 2., 0.),
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,13 @@ use crate::player::spawn_player_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) {
|
||||||
app.add_systems(OnEnter(Screen::Gameplay), spawn_level);
|
app.add_systems(
|
||||||
|
OnEnter(Screen::Gameplay),
|
||||||
|
(
|
||||||
|
spawn_level_command,
|
||||||
|
spawn_player_command.after(spawn_level_command),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
app.load_resource::<GameplayMusic>();
|
app.load_resource::<GameplayMusic>();
|
||||||
app.add_systems(OnEnter(Screen::Gameplay), play_gameplay_music);
|
app.add_systems(OnEnter(Screen::Gameplay), play_gameplay_music);
|
||||||
@ -20,11 +26,6 @@ pub(super) fn plugin(app: &mut App) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_level(mut commands: Commands) {
|
|
||||||
commands.queue(spawn_level_command);
|
|
||||||
commands.queue(spawn_player_command);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Resource, Asset, Reflect, Clone)]
|
#[derive(Resource, Asset, Reflect, Clone)]
|
||||||
pub struct GameplayMusic {
|
pub struct GameplayMusic {
|
||||||
#[dependency]
|
#[dependency]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user