Merge pull request #6 from kristoferssolo/feature/update-bevy

chore: update to bevy0.15
This commit is contained in:
Kristofers Solo 2024-12-11 18:01:40 +02:00 committed by GitHub
commit 80bc027477
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 1000 additions and 597 deletions

1347
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
[package] [package]
name = "maze-ascension" name = "maze-ascension"
authors = ["Kristofers Solo <dev@kristofers.xyz>"] authors = ["Kristofers Solo <dev@kristofers.xyz>"]
version = "0.0.6" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
bevy = { version = "0.14", features = ["wayland"] } bevy = { version = "0.15", features = ["wayland"] }
rand = "0.8" rand = "0.8"
# Compile low-severity logs out of native builds for performance. # Compile low-severity logs out of native builds for performance.
log = { version = "0.4", features = [ log = { version = "0.4", features = [
@ -17,10 +17,10 @@ tracing = { version = "0.1", features = [
"max_level_debug", "max_level_debug",
"release_max_level_warn", "release_max_level_warn",
] } ] }
hexx = { version = "0.18", features = ["bevy_reflect", "grid"] } hexx = { version = "0.19", features = ["bevy_reflect", "grid"] }
hexlab = { version = "0.1", features = ["bevy"] } hexlab = { version = "0.2", features = ["bevy"] }
bevy-inspector-egui = { version = "0.27", optional = true } bevy-inspector-egui = { version = "0.28", optional = true }
bevy_egui = { version = "0.30", optional = true } bevy_egui = { version = "0.31", optional = true }
thiserror = "2.0" thiserror = "2.0"

View File

@ -84,10 +84,8 @@ enum AppSet {
fn spawn_camera(mut commands: Commands) { fn spawn_camera(mut commands: Commands) {
commands.spawn(( commands.spawn((
Name::new("Camera"), Name::new("Camera"),
Camera3dBundle { Camera3d::default(),
transform: Transform::from_xyz(200., 200., 0.).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(200., 200., 0.).looking_at(Vec3::ZERO, Vec3::Y),
..default()
},
// Render all UI to this camera. // Render all UI to this camera.
// Not strictly necessary since we only use one camera, // Not strictly necessary since we only use one camera,
// but if we don't use this component, our UI will disappear as soon // but if we don't use this component, our UI will disappear as soon

View File

@ -3,7 +3,7 @@ use bevy::prelude::*;
use std::f32::consts::FRAC_PI_2; use std::f32::consts::FRAC_PI_2;
const WALL_OVERLAP_MODIFIER: f32 = 1.25; const WALL_OVERLAP_MODIFIER: f32 = 1.25;
const HEX_SIDES: usize = 6; const HEX_SIDES: u32 = 6;
const WHITE_EMISSION_INTENSITY: f32 = 10.; const WHITE_EMISSION_INTENSITY: f32 = 10.;
pub(crate) struct MazeAssets { pub(crate) struct MazeAssets {

View File

@ -23,6 +23,6 @@ impl Plugin for MazePlugin {
impl Command for MazePlugin { impl Command for MazePlugin {
fn apply(self, world: &mut World) { fn apply(self, 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);
} }
} }

View File

@ -32,10 +32,8 @@ pub(super) fn setup_maze(
.spawn(( .spawn((
Name::new("Floor"), Name::new("Floor"),
MazeFloor(1), MazeFloor(1),
SpatialBundle { Transform::from_translation(Vec3::ZERO),
transform: Transform::from_translation(Vec3::ZERO), Visibility::Visible,
..default()
},
)) ))
.with_children(|parent| { .with_children(|parent| {
for tile in maze.values() { for tile in maze.values() {

View File

@ -26,12 +26,9 @@ pub(super) fn spawn_single_hex_tile(
.spawn(( .spawn((
Name::new(format!("Hex {}", tile)), Name::new(format!("Hex {}", tile)),
MazeTile, MazeTile,
PbrBundle { Mesh3d(assets.hex_mesh.clone()),
mesh: assets.hex_mesh.clone(), MeshMaterial3d(assets.hex_material.clone()),
material: assets.hex_material.clone(), Transform::from_translation(world_pos).with_rotation(rotation),
transform: Transform::from_translation(world_pos).with_rotation(rotation),
..default()
},
)) ))
.with_children(|parent| spawn_walls(parent, assets, config, tile.walls())); .with_children(|parent| spawn_walls(parent, assets, config, tile.walls()));
} }
@ -58,20 +55,12 @@ fn spawn_walls(parent: &mut ChildBuilder, assets: &MazeAssets, config: &MazeConf
} }
} }
fn spawn_single_wall( fn spawn_single_wall(parent: &mut ChildBuilder, assets: &MazeAssets, rotation: Quat, offset: Vec3) {
parent: &mut ChildBuilder,
asstets: &MazeAssets,
rotation: Quat,
offset: Vec3,
) {
parent.spawn(( parent.spawn((
Name::new("Wall"), Name::new("Wall"),
MazeWall, MazeWall,
PbrBundle { Mesh3d(assets.wall_mesh.clone()),
mesh: asstets.wall_mesh.clone(), MeshMaterial3d(assets.wall_material.clone()),
material: asstets.wall_material.clone(), Transform::from_translation(offset).with_rotation(rotation),
transform: Transform::from_translation(offset).with_rotation(rotation),
..default()
},
)); ));
} }

View File

@ -56,10 +56,8 @@ fn play_credits_music(mut commands: Commands, mut music: ResMut<CreditsMusic>) {
music.entity = Some( music.entity = Some(
commands commands
.spawn(( .spawn((
AudioBundle { AudioPlayer::<AudioSource>(music.music.clone()),
source: music.music.clone(), PlaybackSettings::LOOP,
settings: PlaybackSettings::LOOP,
},
Music, Music,
)) ))
.id(), .id(),

View File

@ -15,12 +15,12 @@ pub(super) fn plugin(app: &mut App) {
app.add_systems( app.add_systems(
Update, Update,
return_to_title_screen return_to_title_screen
.run_if(in_state(Screen::Gameplay).and_then(input_just_pressed(KeyCode::Escape))), .run_if(in_state(Screen::Gameplay).and(input_just_pressed(KeyCode::Escape))),
); );
} }
fn spawn_level(mut commands: Commands) { fn spawn_level(mut commands: Commands) {
commands.add(spawn_level_command); commands.queue(spawn_level_command);
} }
#[derive(Resource, Asset, Reflect, Clone)] #[derive(Resource, Asset, Reflect, Clone)]
@ -44,10 +44,8 @@ fn play_gameplay_music(mut commands: Commands, mut music: ResMut<GameplayMusic>)
music.entity = Some( music.entity = Some(
commands commands
.spawn(( .spawn((
AudioBundle { AudioPlayer::<AudioSource>(music.handle.clone()),
source: music.handle.clone(), PlaybackSettings::LOOP,
settings: PlaybackSettings::LOOP,
},
Music, Music,
)) ))
.id(), .id(),

View File

@ -13,7 +13,7 @@ pub(super) fn plugin(app: &mut App) {
app.add_systems( app.add_systems(
Update, Update,
continue_to_title_screen.run_if(in_state(Screen::Loading).and_then(all_assets_loaded)), continue_to_title_screen.run_if(in_state(Screen::Loading).and(all_assets_loaded)),
); );
} }
@ -22,7 +22,7 @@ fn spawn_loading_screen(mut commands: Commands) {
.ui_root() .ui_root()
.insert(StateScoped(Screen::Loading)) .insert(StateScoped(Screen::Loading))
.with_children(|children| { .with_children(|children| {
children.label("Loading...").insert(Style { children.label("Loading...").insert(Node {
justify_content: JustifyContent::Center, justify_content: JustifyContent::Center,
..default() ..default()
}); });

View File

@ -1,9 +1,9 @@
//! A splash screen that plays briefly at startup. //! A splash screen that plays bdelta_secsriefly at startup.
use bevy::{ use bevy::{
image::{ImageLoaderSettings, ImageSampler},
input::common_conditions::input_just_pressed, input::common_conditions::input_just_pressed,
prelude::*, prelude::*,
render::texture::{ImageLoaderSettings, ImageSampler},
}; };
use crate::{screens::Screen, theme::prelude::*, AppSet}; use crate::{screens::Screen, theme::prelude::*, AppSet};
@ -40,7 +40,7 @@ pub(super) fn plugin(app: &mut App) {
app.add_systems( app.add_systems(
Update, Update,
continue_to_loading_screen continue_to_loading_screen
.run_if(input_just_pressed(KeyCode::Escape).and_then(in_state(Screen::Splash))), .run_if(input_just_pressed(KeyCode::Escape).and(in_state(Screen::Splash))),
); );
} }
@ -59,24 +59,21 @@ fn spawn_splash_screen(mut commands: Commands, asset_server: Res<AssetServer>) {
.with_children(|children| { .with_children(|children| {
children.spawn(( children.spawn((
Name::new("Splash image"), Name::new("Splash image"),
ImageBundle { Node {
style: Style { margin: UiRect::all(Val::Auto),
margin: UiRect::all(Val::Auto), width: Val::Percent(70.0),
width: Val::Percent(70.0),
..default()
},
image: UiImage::new(asset_server.load_with_settings(
// This should be an embedded asset for instant loading, but that is
// currently [broken on Windows Wasm builds](https://github.com/bevyengine/bevy/issues/14246).
"images/splash.png",
|settings: &mut ImageLoaderSettings| {
// Make an exception for the splash image in case
// `ImagePlugin::default_nearest()` is used for pixel art.
settings.sampler = ImageSampler::linear();
},
)),
..default() ..default()
}, },
ImageNode::new(asset_server.load_with_settings(
// This should be an embedded asset for instant loading, but that is
// currently [broken on Windows Wasm builds](https://github.com/bevyengine/bevy/issues/14246).
"images/splash.png",
|settings: &mut ImageLoaderSettings| {
// Make an exception for the splash image in case
// `ImagePlugin::default_nearest()` is used for pixel art.
settings.sampler = ImageSampler::linear();
},
)),
UiImageFadeInOut { UiImageFadeInOut {
total_duration: SPLASH_DURATION_SECS, total_duration: SPLASH_DURATION_SECS,
fade_duration: SPLASH_FADE_DURATION_SECS, fade_duration: SPLASH_FADE_DURATION_SECS,
@ -110,11 +107,11 @@ impl UiImageFadeInOut {
fn tick_fade_in_out(time: Res<Time>, mut animation_query: Query<&mut UiImageFadeInOut>) { fn tick_fade_in_out(time: Res<Time>, mut animation_query: Query<&mut UiImageFadeInOut>) {
for mut anim in &mut animation_query { for mut anim in &mut animation_query {
anim.t += time.delta_seconds(); anim.t += time.delta_secs();
} }
} }
fn apply_fade_in_out(mut animation_query: Query<(&UiImageFadeInOut, &mut UiImage)>) { fn apply_fade_in_out(mut animation_query: Query<(&UiImageFadeInOut, &mut ImageNode)>) {
for (anim, mut image) in &mut animation_query { for (anim, mut image) in &mut animation_query {
image.color.set_alpha(anim.alpha()) image.color.set_alpha(anim.alpha())
} }

View File

@ -94,10 +94,8 @@ fn trigger_interaction_sound_effect(
_ => continue, _ => continue,
}; };
commands.spawn(( commands.spawn((
AudioBundle { AudioPlayer::<AudioSource>(source),
source, PlaybackSettings::DESPAWN,
settings: PlaybackSettings::DESPAWN,
},
SoundEffect, SoundEffect,
)); ));
} }

View File

@ -16,19 +16,20 @@ pub trait Widgets {
fn label(&mut self, text: impl Into<String>) -> EntityCommands; fn label(&mut self, text: impl Into<String>) -> EntityCommands;
} }
impl<T: Spawn> Widgets for T { impl<T: SpawnUi> Widgets for T {
fn button(&mut self, text: impl Into<String>) -> EntityCommands { fn button(&mut self, text: impl Into<String>) -> EntityCommands {
let mut entity = self.spawn(( let mut entity = self.spawn_ui((
Name::new("Button"), Name::new("Button"),
ButtonBundle { Button,
style: Style { ImageNode {
width: Px(200.0), color: NODE_BACKGROUND,
height: Px(65.0), ..default()
justify_content: JustifyContent::Center, },
align_items: AlignItems::Center, Node {
..default() width: Px(200.0),
}, height: Px(65.0),
background_color: BackgroundColor(NODE_BACKGROUND), justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..default() ..default()
}, },
InteractionPalette { InteractionPalette {
@ -38,16 +39,14 @@ impl<T: Spawn> Widgets for T {
}, },
)); ));
entity.with_children(|children| { entity.with_children(|children| {
children.spawn(( children.spawn_ui((
Name::new("Button Text"), Name::new("Button Text"),
TextBundle::from_section( Text(text.into()),
text, TextFont {
TextStyle { font_size: 40.0,
font_size: 40.0, ..default()
color: BUTTON_TEXT, },
..default() TextColor(BUTTON_TEXT),
},
),
)); ));
}); });
@ -55,51 +54,47 @@ impl<T: Spawn> Widgets for T {
} }
fn header(&mut self, text: impl Into<String>) -> EntityCommands { fn header(&mut self, text: impl Into<String>) -> EntityCommands {
let mut entity = self.spawn(( let mut entity = self.spawn_ui((
Name::new("Header"), Name::new("Header"),
NodeBundle { Node {
style: Style { width: Px(500.0),
width: Px(500.0), height: Px(65.0),
height: Px(65.0), justify_content: JustifyContent::Center,
justify_content: JustifyContent::Center, align_items: AlignItems::Center,
align_items: AlignItems::Center,
..default()
},
background_color: BackgroundColor(NODE_BACKGROUND),
..default() ..default()
}, },
BackgroundColor(NODE_BACKGROUND),
)); ));
entity.with_children(|children| { entity.with_children(|children| {
children.spawn(( children.spawn_ui((
Name::new("Header Text"), Name::new("Header Text"),
TextBundle::from_section( Text(text.into()),
text, TextFont {
TextStyle { font_size: 40.0,
font_size: 40.0, ..default()
color: HEADER_TEXT, },
..default() TextColor(HEADER_TEXT),
},
),
)); ));
}); });
entity entity
} }
fn label(&mut self, text: impl Into<String>) -> EntityCommands { fn label(&mut self, _text: impl Into<String>) -> EntityCommands {
let entity = self.spawn(( let entity = self.spawn_ui((
Name::new("Label"), Name::new("Label"),
TextBundle::from_section( Text::default(),
text, // TextBundle::from_section(
TextStyle { // text,
font_size: 24.0, // TextStyle {
color: LABEL_TEXT, // font_size: 24.0,
..default() // color: LABEL_TEXT,
}, // ..default()
) // },
.with_style(Style { // )
width: Px(500.0), // .with_style(Style {
..default() // width: Px(500.0),
}), // ..default()
// }),
)); ));
entity entity
} }
@ -116,17 +111,14 @@ impl Containers for Commands<'_, '_> {
fn ui_root(&mut self) -> EntityCommands { fn ui_root(&mut self) -> EntityCommands {
self.spawn(( self.spawn((
Name::new("UI Root"), Name::new("UI Root"),
NodeBundle { Node {
style: Style { width: Percent(100.0),
width: Percent(100.0), height: Percent(100.0),
height: Percent(100.0), justify_content: JustifyContent::Center,
justify_content: JustifyContent::Center, align_items: AlignItems::Center,
align_items: AlignItems::Center, flex_direction: FlexDirection::Column,
flex_direction: FlexDirection::Column, row_gap: Px(10.0),
row_gap: Px(10.0), position_type: PositionType::Absolute,
position_type: PositionType::Absolute,
..default()
},
..default() ..default()
}, },
)) ))
@ -137,18 +129,18 @@ impl Containers for Commands<'_, '_> {
/// This is here so that [`Widgets`] can be implemented on all types that /// This is here so that [`Widgets`] can be implemented on all types that
/// are able to spawn entities. /// are able to spawn entities.
/// Ideally, this trait should be [part of Bevy itself](https://github.com/bevyengine/bevy/issues/14231). /// Ideally, this trait should be [part of Bevy itself](https://github.com/bevyengine/bevy/issues/14231).
trait Spawn { trait SpawnUi {
fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityCommands; fn spawn_ui<B: Bundle>(&mut self, bundle: B) -> EntityCommands;
} }
impl Spawn for Commands<'_, '_> { impl SpawnUi for Commands<'_, '_> {
fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityCommands { fn spawn_ui<B: Bundle>(&mut self, bundle: B) -> EntityCommands {
self.spawn(bundle) self.spawn(bundle)
} }
} }
impl Spawn for ChildBuilder<'_> { impl SpawnUi for ChildBuilder<'_> {
fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityCommands { fn spawn_ui<B: Bundle>(&mut self, bundle: B) -> EntityCommands {
self.spawn(bundle) self.spawn(bundle)
} }
} }