Skip to content
Snippets Groups Projects
Verified Commit b7575f11 authored by Louis's avatar Louis :fire:
Browse files

Pull configs into hot-reload assets

parent 670a5667
No related branches found
No related tags found
No related merge requests found
...@@ -1639,6 +1639,7 @@ dependencies = [ ...@@ -1639,6 +1639,7 @@ dependencies = [
name = "game_core" name = "game_core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow",
"bevy", "bevy",
"bevy_embedded_assets", "bevy_embedded_assets",
"bevy_rapier2d", "bevy_rapier2d",
......
...@@ -22,6 +22,7 @@ serde = "1.0.164" ...@@ -22,6 +22,7 @@ serde = "1.0.164"
serde_json = "1.0.96" serde_json = "1.0.96"
num-traits = "0.2.15" num-traits = "0.2.15"
paste = "1.0.12" paste = "1.0.12"
anyhow = "1.0.71"
bevy_rapier2d = { version = "0.22.0", features = ["simd-stable", "wasm-bindgen"]} bevy_rapier2d = { version = "0.22.0", features = ["simd-stable", "wasm-bindgen"]}
bevy_embedded_assets = "0.8.0" bevy_embedded_assets = "0.8.0"
......
{
"gravity": -123.0,
"jump": 200.0,
"speed": 150.0
}
\ No newline at end of file
...@@ -21,4 +21,5 @@ bevy_rapier2d.workspace = true ...@@ -21,4 +21,5 @@ bevy_rapier2d.workspace = true
serde.workspace = true serde.workspace = true
serde_json.workspace = true serde_json.workspace = true
num-traits.workspace = true num-traits.workspace = true
paste.workspace = true paste.workspace = true
\ No newline at end of file anyhow.workspace = true
\ No newline at end of file
use crate::system::AppState;
use bevy::asset::{AddAsset, AssetLoader, AssetServer, BoxedFuture, LoadContext, LoadedAsset};
use bevy::ecs::system::SystemParam;
use bevy::prelude::*;
use bevy::reflect::{TypePath, TypeUuid};
use paste::paste;
use serde::{Deserialize, Serialize};
macro_rules! impl_config_lifecycle {
($(($struct: ident, $ext: literal)),*) => {
paste! {
#[allow(dead_code)]
mod _inner {
use super::*;
$(
struct [<$struct Loader>];
impl AssetLoader for [<$struct Loader>] {
fn load<'a>(
&'a self,
bytes: &'a [u8],
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, anyhow::Result<()>> {
Box::pin(async move {
let value: $struct = serde_json::from_slice(bytes)?;
load_context.set_default_asset(LoadedAsset::new(value));
Ok(())
})
}
fn extensions(&self) -> &[&str] {
&[$ext]
}
}
#[derive(Resource)]
struct [<$struct Wrapper>] {
handle: Handle<$struct>,
}
#[derive(SystemParam)]
pub struct [<Fetch $struct>]<'w> {
wrapper: Res<'w, [<$struct Wrapper>]>,
asset: Res<'w, Assets<$struct>>,
}
impl<'w> [<Fetch $struct>]<'w> {
pub fn get(&self) -> Option<&$struct> {
self.asset.get(&self.wrapper.handle)
}
}
fn [<init_ $struct:snake>](mut commands: Commands, assets: Res<AssetServer>) {
let handle = assets.load(format!("config/config.{}", $ext));
commands.insert_resource([<$struct Wrapper>] { handle });
}
)*
pub struct ConfigsPlugin;
impl Plugin for ConfigsPlugin {
fn build(&self, app: &mut App) {$(
app.add_asset::<$struct>()
.add_asset_loader([<$struct Loader>])
.add_systems(OnEnter(AppState::Preload), [<init_ $struct:snake>]);
)*}
}
}
pub use _inner::ConfigsPlugin;
pub use _inner::{$([<Fetch $struct>]),*};
}
};
}
#[derive(Copy, Clone, TypeUuid, TypePath, Debug, Default, Serialize, Deserialize)]
#[uuid = "f7d88160-28e4-11ee-bcad-b34d9ff949be"]
pub struct PhysicsConfig {
pub gravity: f32,
pub jump: f32,
pub speed: f32,
}
impl_config_lifecycle!((PhysicsConfig, "phys"));
mod configs;
mod loader; mod loader;
mod resources; mod resources;
mod startup; mod startup;
...@@ -23,6 +24,7 @@ mod _plugin { ...@@ -23,6 +24,7 @@ mod _plugin {
} }
pub use _plugin::AssetLoadingPlugin; pub use _plugin::AssetLoadingPlugin;
pub use configs::{ConfigsPlugin, FetchPhysicsConfig, PhysicsConfig};
pub(self) use loader::AssetTypeLoader; pub(self) use loader::AssetTypeLoader;
pub use resources::AssetHandles; pub use resources::AssetHandles;
pub(self) use resources::{AssetNameMapping, FixedAssetNameMapping, SpriteSheetConfig}; pub(self) use resources::{AssetNameMapping, FixedAssetNameMapping, SpriteSheetConfig};
...@@ -15,11 +15,12 @@ mod _plugin { ...@@ -15,11 +15,12 @@ mod _plugin {
Collider::cuboid(200.0, 50.0), Collider::cuboid(200.0, 50.0),
)); ));
}) })
.add_systems( // .add_systems(
Update, // Update,
(|gamepads: Res<Gamepads>| info!("{:?}", gamepads)) // (|gamepads: Res<Gamepads>| info!("{:?}", gamepads))
.run_if(on_fixed_timer(Duration::from_secs(5))), // .run_if(on_fixed_timer(Duration::from_secs(5))),
); // )
;
} }
} }
} }
......
use crate::assets::FetchPhysicsConfig;
use crate::system::run_in_game; use crate::system::run_in_game;
use bevy::ecs::query::Has;
use bevy::prelude::*; use bevy::prelude::*;
use bevy_rapier2d::prelude::KinematicCharacterController; use bevy_rapier2d::prelude::KinematicCharacterController;
...@@ -8,6 +10,9 @@ pub const GRAVITY_VEC: Vec2 = Vec2::new(0.0, GRAVITY_ACC); ...@@ -8,6 +10,9 @@ pub const GRAVITY_VEC: Vec2 = Vec2::new(0.0, GRAVITY_ACC);
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, SystemSet)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, SystemSet)]
pub struct PhysicsSet; pub struct PhysicsSet;
#[derive(Component, Clone, Copy, Debug)]
pub struct HasGravity;
#[derive(Component, Clone, Copy, Debug, Default, Deref, DerefMut)] #[derive(Component, Clone, Copy, Debug, Default, Deref, DerefMut)]
pub struct Velocity(Vec2); pub struct Velocity(Vec2);
...@@ -43,15 +48,28 @@ impl Acceleration { ...@@ -43,15 +48,28 @@ impl Acceleration {
pub fn gravity() -> Self { pub fn gravity() -> Self {
Acceleration(GRAVITY_VEC) Acceleration(GRAVITY_VEC)
} }
pub fn new(val: Vec2) -> Self {
Acceleration(val)
}
} }
fn apply_acceleration( fn apply_acceleration(
time: Res<Time>, time: Res<Time>,
mut query: Query<(&mut Velocity, &Acceleration, Option<&PhysicsLimits>)>, mut query: Query<(
&mut Velocity,
&Acceleration,
Option<&PhysicsLimits>,
Has<HasGravity>,
)>,
phys_config: FetchPhysicsConfig,
) { ) {
let gravity = phys_config.get().map(|p| p.gravity).unwrap_or_default();
let dt = time.delta_seconds(); let dt = time.delta_seconds();
for (mut velocity, acceleration, limits) in &mut query { for (mut velocity, acceleration, limits, has_gravity) in &mut query {
**velocity += **acceleration * dt; **velocity += **acceleration * dt;
if has_gravity {
**velocity += Vec2::new(0.0, gravity) * dt;
}
**velocity = limits **velocity = limits
.copied() .copied()
.unwrap_or_default() .unwrap_or_default()
......
use crate::assets::AssetHandles; use crate::assets::{AssetHandles, FetchPhysicsConfig};
use crate::system::{AppState, ChaseCam, PolyInputManager}; use crate::system::{AppState, ChaseCam, PolyInputManager};
use bevy::prelude::*; use bevy::prelude::*;
use crate::entities::physics::HasGravity;
use crate::entities::{ use crate::entities::{
Acceleration, PhysicsLimits, PhysicsSet, SimpleAnimation, SimpleAnimationBundle, Velocity, Acceleration, PhysicsLimits, PhysicsSet, SimpleAnimation, SimpleAnimationBundle, Velocity,
GRAVITY_ACC, GRAVITY_ACC,
...@@ -27,8 +28,9 @@ pub fn spawn_player(mut commands: Commands, assets: Res<AssetHandles>) { ...@@ -27,8 +28,9 @@ pub fn spawn_player(mut commands: Commands, assets: Res<AssetHandles>) {
offset: CharacterLength::Absolute(0.03), offset: CharacterLength::Absolute(0.03),
..Default::default() ..Default::default()
}, },
Acceleration::gravity(), Acceleration::default(),
Velocity::default(), Velocity::default(),
HasGravity,
PhysicsLimits { PhysicsLimits {
velocity: ( velocity: (
Some(Vec2::new(f32::NEG_INFINITY, GRAVITY_ACC)), Some(Vec2::new(f32::NEG_INFINITY, GRAVITY_ACC)),
...@@ -53,7 +55,13 @@ pub fn spawn_player(mut commands: Commands, assets: Res<AssetHandles>) { ...@@ -53,7 +55,13 @@ pub fn spawn_player(mut commands: Commands, assets: Res<AssetHandles>) {
pub fn handle_input( pub fn handle_input(
input: PolyInputManager, input: PolyInputManager,
mut query: Query<(&mut Velocity, &KinematicCharacterControllerOutput), With<Player>>, mut query: Query<(&mut Velocity, &KinematicCharacterControllerOutput), With<Player>>,
phys_config: FetchPhysicsConfig,
) { ) {
let speed = phys_config
.get()
.map(|phys_config| phys_config.speed)
.unwrap_or_default();
for (mut velocity, controller) in &mut query { for (mut velocity, controller) in &mut query {
let delta_y = if controller.grounded && input.is_jump_just_pressed() { let delta_y = if controller.grounded && input.is_jump_just_pressed() {
Some(40.0) Some(40.0)
...@@ -62,9 +70,9 @@ pub fn handle_input( ...@@ -62,9 +70,9 @@ pub fn handle_input(
}; };
let delta_x = if input.is_right_pressed_or_active() { let delta_x = if input.is_right_pressed_or_active() {
200.0 speed
} else if input.is_left_pressed_or_active() { } else if input.is_left_pressed_or_active() {
-200.0 -speed
} else { } else {
0.0 0.0
}; };
......
...@@ -2,8 +2,9 @@ use bevy::prelude::App; ...@@ -2,8 +2,9 @@ use bevy::prelude::App;
fn main() { fn main() {
App::new() App::new()
.add_plugins(game_core::assets::AssetLoadingPlugin)
.add_plugins(game_core::system::SystemPluginSet) .add_plugins(game_core::system::SystemPluginSet)
.add_plugins(game_core::assets::AssetLoadingPlugin)
.add_plugins(game_core::assets::ConfigsPlugin)
.add_plugins(game_core::entities::EntityPluginSet) .add_plugins(game_core::entities::EntityPluginSet)
.add_plugins(game_core::debug::DebugPlugin) .add_plugins(game_core::debug::DebugPlugin)
.add_plugins(bevy_rapier2d::plugin::RapierPhysicsPlugin::<()>::pixels_per_meter(18.0)) .add_plugins(bevy_rapier2d::plugin::RapierPhysicsPlugin::<()>::pixels_per_meter(18.0))
......
...@@ -31,7 +31,7 @@ pub fn configure_default_plugins() -> PluginGroupBuilder { ...@@ -31,7 +31,7 @@ pub fn configure_default_plugins() -> PluginGroupBuilder {
}) })
.set(AssetPlugin { .set(AssetPlugin {
asset_folder: get_asset_path_string(), asset_folder: get_asset_path_string(),
watch_for_changes: ChangeWatcher::with_delay(Duration::from_secs(1)), watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(25)),
}) })
.set(ImagePlugin::default_nearest()) .set(ImagePlugin::default_nearest())
.set(LogPlugin { .set(LogPlugin {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment