Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
932 changes: 510 additions & 422 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ license = "MIT OR Apache-2.0"
debug = ["bevy_rapier2d/debug-render-2d"]

[dependencies]
bevy = { version = "0.15", features = ["webgpu"] }
bevy_rapier2d = "0.29"
bevy_ecs_ldtk = "0.11"
bevy_ecs_tilemap = "0.15"
bevy_asset_loader = { version = "0.22", features = ["2d"] }
bevy_light_2d = { version = "0.5" }
bevy = { version = "0.16", features = ["webgpu"] }
bevy_rapier2d = "0.31"
bevy_ecs_ldtk = "0.12"
bevy_ecs_tilemap = "0.16"
bevy_asset_loader = { version = "0.23", features = ["2d"] }
bevy_light_2d = { version = "0.7" }
better_default = "1"
log = { version = "*", features = ["max_level_debug", "release_max_level_warn"] }

Expand Down
30 changes: 10 additions & 20 deletions src/camera.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{player::PlayerEntity, ASPECT_RATIO};
use bevy::{
prelude::*,
render::camera::{ScalingMode, Viewport},
render::camera::Viewport,
};
use bevy_ecs_ldtk::prelude::*;
use bevy_rapier2d::prelude::*;
Expand All @@ -20,19 +20,10 @@ impl Plugin for MainCameraPlugin {
pub struct MainCamera;

fn spawn_camera(mut commands: Commands) {
let mut orthographic_project = OrthographicProjection::default_2d();
orthographic_project.scaling_mode = ScalingMode::AutoMin {
min_width: 1280.,
min_height: 720.,
};

commands.spawn(MainCamera).insert(OrthographicProjection {
scaling_mode: ScalingMode::AutoMin {
min_width: 1280.,
min_height: 720.,
},
..OrthographicProjection::default_2d()
});
commands.spawn((
MainCamera,
Camera2d,
));
}

fn update_camera_viewport(
Expand Down Expand Up @@ -70,13 +61,13 @@ fn update_camera_viewport(
#[allow(clippy::type_complexity)]
fn sync_camera(
mut camera_query: Query<
(&mut Transform, &mut OrthographicProjection),
&mut Transform,
(With<MainCamera>, Without<PlayerEntity>),
>,
player_query: Query<&Transform, With<PlayerEntity>>,
level_query: Query<
(&Transform, &LevelIid),
(Without<OrthographicProjection>, Without<PlayerEntity>),
(Without<MainCamera>, Without<PlayerEntity>),
>,
ldtk_projects: Query<&LdtkProjectHandle>,
level_selection: Option<Res<LevelSelection>>,
Expand All @@ -85,15 +76,15 @@ fn sync_camera(
if let Ok(Transform {
translation: player_translation,
..
}) = player_query.get_single()
}) = player_query.single()
{
let player_translation = *player_translation;

let (mut camera_transform, mut orthographic_projection) = camera_query.single_mut();
let mut camera_transform = camera_query.single_mut().expect("Camera should exist");

for (level_transform, level_iid) in &level_query {
let ldtk_project = ldtk_project_assets
.get(ldtk_projects.single())
.get(ldtk_projects.single().expect("Project should be loaded"))
.expect("Project should be loaded if level has spawned");

let level = ldtk_project
Expand All @@ -106,7 +97,6 @@ fn sync_camera(

if level_selection.is_match(&LevelIndices::default(), level) {
let level_ratio = level.px_wid as f32 / level.px_hei as f32;
orthographic_projection.viewport_origin = Vec2::ZERO;

if level_ratio > ASPECT_RATIO {
// level is wider than the screen
Expand Down
2 changes: 1 addition & 1 deletion src/ground_detection.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::GameState;
use bevy::prelude::*;
use bevy::utils::HashSet;
use std::collections::HashSet;
use bevy_rapier2d::prelude::*;

#[derive(Component)]
Expand Down
4 changes: 3 additions & 1 deletion src/hostile_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ fn damage_player(
audio_assets: Res<AudioAssets>,
) {
for collision in collision_events.read() {
let (player_entity, mut player_healtbar, audio_player) = player_query.single_mut();
let Ok((player_entity, mut player_healtbar, audio_player)) = player_query.single_mut() else {
return;
};
match *collision {
CollisionEvent::Started(entity_one, entity_two, ..) => {
if entity_one == player_entity || entity_two == player_entity {
Expand Down
2 changes: 1 addition & 1 deletion src/level_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn sync_level_changes(
{
log::info!("Inserting level {}", current_level_info.current_level_id);
commands.insert_resource(LevelSelection::iid(level_iid));
restart_time_event.send(RestartTimeEvent);
restart_time_event.write(RestartTimeEvent);
} else {
next_game_state.set(GameState::CreditScreen);
// log::error!("Level didn't found, make sure the ldtk map is syned with the default implementation.");
Expand Down
10 changes: 5 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use assets::AssetsManagerPlugin;
use bevy::prelude::*;
use bevy::utils::{Duration, Instant};
use std::time::{Duration, Instant};
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use bevy::window::WindowMode;
use bevy::window::{WindowMode, MonitorSelection, VideoModeSelection};
use bevy_ecs_ldtk::LdtkWorldBundle;
use bevy_light_2d::plugin::Light2dPlugin;
use hostile_entity::HostilePlugin;
Expand Down Expand Up @@ -148,7 +148,7 @@ pub fn auto_despawn_system(mut commands: Commands, query: Query<(Entity, &AutoDe
for (entity, auto_despawn) in &query {
if auto_despawn.instant.elapsed() > auto_despawn.duration {
if auto_despawn.recursive_despawn {
commands.entity(entity).despawn_recursive();
commands.entity(entity).despawn();
} else {
commands.entity(entity).despawn();
}
Expand All @@ -168,11 +168,11 @@ fn full_screen(keyboard: Res<ButtonInput<KeyCode>>, mut windows: Query<&mut Wind
if keyboard.just_pressed(KeyCode::F11) {
for mut window in &mut windows {
match window.mode {
WindowMode::Fullscreen(_) => {
WindowMode::Fullscreen(_, _) => {
window.mode = WindowMode::Windowed;
}
_ => {
window.mode = WindowMode::Fullscreen(MonitorSelection::Current);
window.mode = WindowMode::Fullscreen(MonitorSelection::Current, VideoModeSelection::Current);
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
time::RecordTimeEvent,
GameState, GRID_SIZE,
};
use bevy::utils::Duration;
use std::time::Duration;
use bevy::{color::palettes::css::YELLOW, prelude::*, time::common_conditions::on_real_timer};
use bevy_ecs_ldtk::prelude::*;
use bevy_light_2d::prelude::{AmbientLight2d, PointLight2d};
Expand Down Expand Up @@ -213,7 +213,7 @@ fn sync_healthbar(
for health_bar in &health_bar_query {
if health_bar.health == 0 {
// Game Over
record_time_event.send(RecordTimeEvent(current_level_info.current_level_id));
record_time_event.write(RecordTimeEvent(current_level_info.current_level_id));
next_game_state.set(GameState::GameOverScreen);
time.pause();
return;
Expand All @@ -222,8 +222,8 @@ fn sync_healthbar(
for health_bar_context in &health_bar_context_query {
let mut health_bar_context_commands = commands.entity(health_bar_context);

// Remove the old hearts
health_bar_context_commands.despawn_descendants();
// Clear and regenerate hearts - despawn_descendants is no longer available
health_bar_context_commands.despawn();

// Generate Sprite Bundle with all the hearts
health_bar_context_commands.with_children(|parent| {
Expand Down
8 changes: 4 additions & 4 deletions src/screens/game_over_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ fn restart_game(
) {
for interaction in &query {
if Interaction::Pressed == *interaction {
restart_game_event.send(RestartGameEvent);
restart_game_event.write(RestartGameEvent);
}
}
}
Expand Down Expand Up @@ -219,7 +219,7 @@ fn restart_game_event(
LevelSelection::Iid(iid) => iid,
LevelSelection::Indices(indice) => {
let ldtk_project = ldtk_project_assets
.get(ldtk_projects.single())
.get(ldtk_projects.single().expect("Project should be loaded"))
.expect("Project should be loaded if level has spawned");

&match ldtk_project.get_raw_level_at_indices(indice) {
Expand All @@ -241,12 +241,12 @@ fn restart_game_event(

for (level_entity, level_iid) in &levels {
if level_iid == current_level {
restart_time_event.send(RestartTimeEvent);
restart_time_event.write(RestartTimeEvent);
commands.entity(level_entity).insert(Respawn);
next_game_state.set(GameState::PlayingScreen);
time.unpause();

let main_camera = main_camera_query.single();
let main_camera = main_camera_query.single().expect("Main camera should exist");
commands.entity(main_camera).remove::<AmbientLight2d>();

return;
Expand Down
2 changes: 1 addition & 1 deletion src/screens/levels_menu_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ fn choose_level(
if Interaction::Pressed == *interaction {
next_game_state.set(GameState::PlayingScreen);
if current_level_info.current_level_id == level_button.level_id {
restart_game_event.send(RestartGameEvent);
restart_game_event.write(RestartGameEvent);
}
current_level_info.current_level_id = level_button.level_id;
return;
Expand Down
2 changes: 1 addition & 1 deletion src/screens/main_menu_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ fn exit_game(
) {
for interaction in &query {
if Interaction::Pressed == *interaction {
app_exit_event.send(AppExit::Success);
app_exit_event.write(AppExit::Success);
}
}
}
2 changes: 1 addition & 1 deletion src/screens/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub struct LevelsMenuButton;
pub fn despawn_screen<T: Component>(to_despawn: Query<Entity, With<T>>, mut commands: Commands) {
for entity in &to_despawn {
info!("Despawning Screen Recursively");
commands.entity(entity).despawn_recursive();
commands.entity(entity).despawn();
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/special_tiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ fn jump_booster_collision_event(
) {
for collision in collision_events.read() {
if let CollisionEvent::Started(entity_one, entity_two, ..) = *collision {
let (player_entity, mut player_velocty) = player_query.single_mut();
let Ok((player_entity, mut player_velocty)) = player_query.single_mut() else {
continue;
};

if entity_one == player_entity || entity_two == player_entity {
for (jump_booster_entity, jump_booster) in &jump_booster_query {
Expand Down
3 changes: 2 additions & 1 deletion src/time.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::{assets::FontAssets, screens::despawn_screen, GameState};
use bevy::prelude::*;
use bevy::time::Stopwatch;
use bevy::utils::{Duration, HashMap};
use std::time::Duration;
use std::collections::HashMap;

pub struct TimeTakenPlugin;

Expand Down
4 changes: 2 additions & 2 deletions src/tutorial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
AutoDespawn, GameState,
};
use bevy::prelude::*;
use bevy::utils::Duration;
use std::time::Duration;

pub struct GameTutorialPlugin;

Expand Down Expand Up @@ -786,7 +786,7 @@ fn auto_remove_tutorial(
if current_level_info.is_changed() {
for (entity, tutorial) in &query {
if tutorial.0 != current_level_info.current_level_id {
commands.entity(entity).despawn_recursive();
commands.entity(entity).despawn();
}
}
}
Expand Down
26 changes: 10 additions & 16 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use bevy::{
ecs::{component::ComponentId, world::DeferredWorld},
prelude::*,
};
use bevy::prelude::*;
use std::marker::PhantomData;

pub struct Maybe<B: Bundle>(pub Option<B>);
Expand All @@ -27,23 +24,20 @@ impl<B: Bundle> Default for Maybe<B> {
impl<B: Bundle> Component for Maybe<B> {
const STORAGE_TYPE: bevy::ecs::component::StorageType =
bevy::ecs::component::StorageType::SparseSet;

type Mutability = bevy::ecs::component::Mutable;

fn register_component_hooks(hooks: &mut bevy::ecs::component::ComponentHooks) {
hooks.on_add(maybe_hook::<B>);
hooks.on_add(|mut world, hook_context| {
// Component hooks can't perform structural changes, so we need to rely on commands.
world.commands().queue(MaybeCommand {
entity: hook_context.entity,
_phantom: std::marker::PhantomData::<B>,
});
});
}
}

/// A hook that runs whenever [`Maybe`] is added to an entity.
///
/// Generates a [`MaybeCommand`].
fn maybe_hook<B: Bundle>(mut world: DeferredWorld<'_>, entity: Entity, _component_id: ComponentId) {
// Component hooks can't perform structural changes, so we need to rely on commands.
world.commands().queue(MaybeCommand {
entity,
_phantom: PhantomData::<B>,
});
}

struct MaybeCommand<B> {
entity: Entity,
_phantom: PhantomData<B>,
Expand Down
Loading
Loading