Skip to content

Commit 49a4c3b

Browse files
committed
feat: Add smoke explosion on demon boss spawn
1 parent 30d9f11 commit 49a4c3b

File tree

6 files changed

+93
-7
lines changed

6 files changed

+93
-7
lines changed

assets/spell/smoke.png

5.05 KB
Loading

assets/spell/smoke.trickfilm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
(
3+
name: "main",
4+
keyframes: KeyframesRange((start: 0, end: 12)),
5+
duration: 1.0,
6+
),
7+
]

src/assets.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ pub struct GameAssets {
108108
pub demon_boss_explosion2: Handle<TextureAtlas>,
109109
#[asset(paths("spell/explosion2.trickfilm#main"), collection(typed))]
110110
pub demon_boss_explosion2_animations: Vec<Handle<AnimationClip2D>>,
111+
#[asset(texture_atlas(tile_size_x = 64.0, tile_size_y = 64.0, columns = 12, rows = 1))]
112+
#[asset(path = "spell/smoke.png")]
113+
pub demon_boss_smoke: Handle<TextureAtlas>,
114+
#[asset(paths("spell/smoke.trickfilm#main"), collection(typed))]
115+
pub demon_boss_smoke_animations: Vec<Handle<AnimationClip2D>>,
111116

112117
// --- MAP ---
113118
#[asset(path = "map/level.ldtk")]

src/audio/bgm.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use std::time::Duration;
33
use bevy::prelude::*;
44
use bevy_kira_audio::prelude::*;
55

6-
use crate::{item::statue::StatueUnlockedDelayed, GameAssets, GameState};
6+
use crate::{
7+
item::{platform::TriggerFinalAct, statue::StatueUnlockedDelayed},
8+
GameAssets, GameState,
9+
};
710

811
use super::GameAudio;
912

@@ -38,6 +41,31 @@ fn play_bgm(
3841
commands.spawn(Bgm { handle });
3942
}
4043

44+
fn play_boss_bgm(
45+
mut commands: Commands,
46+
assets: Res<GameAssets>,
47+
audio: Res<Audio>,
48+
game_audio: Res<GameAudio>,
49+
mut ev_trigger_final_act: EventReader<TriggerFinalAct>,
50+
) {
51+
if ev_trigger_final_act.is_empty() {
52+
return;
53+
}
54+
ev_trigger_final_act.clear();
55+
56+
let volume = game_audio.main_volume * BGM_VOLUME;
57+
let handle = audio
58+
.play(assets.bgm_boss.clone())
59+
.fade_in(AudioTween::new(
60+
Duration::from_secs_f32(3.0),
61+
AudioEasing::InPowi(3),
62+
))
63+
.with_volume(volume)
64+
.looped()
65+
.handle();
66+
commands.spawn(Bgm { handle });
67+
}
68+
4169
fn update_bgm_volumes(
4270
game_audio: Res<GameAudio>,
4371
mut audio_instances: ResMut<Assets<AudioInstance>>,
@@ -104,6 +132,25 @@ fn unmute_bgms(
104132
}
105133
}
106134

135+
fn despawn_normal_bgm(
136+
mut commands: Commands,
137+
mut audio_instances: ResMut<Assets<AudioInstance>>,
138+
q_bgms: Query<(Entity, &Bgm)>,
139+
mut ev_trigger_final_act: EventReader<TriggerFinalAct>,
140+
) {
141+
if ev_trigger_final_act.is_empty() {
142+
return;
143+
}
144+
ev_trigger_final_act.clear();
145+
146+
for (entity, bgm) in &q_bgms {
147+
if let Some(instance) = audio_instances.get_mut(bgm.handle.clone()) {
148+
instance.stop(AudioTween::default());
149+
}
150+
commands.entity(entity).despawn_recursive();
151+
}
152+
}
153+
107154
pub struct BgmPlugin;
108155

109156
impl Plugin for BgmPlugin {
@@ -112,9 +159,11 @@ impl Plugin for BgmPlugin {
112159
.add_systems(
113160
Update,
114161
(
162+
play_boss_bgm.run_if(in_state(GameState::Gaming)),
115163
update_bgm_volumes.run_if(in_state(GameState::GameOver)),
116164
mute_bgms.after(update_bgm_volumes),
117165
unmute_bgms,
166+
despawn_normal_bgm,
118167
),
119168
);
120169
}

src/enemy/demon_boss/spawn.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use super::{
1616
};
1717

1818
const SCALE: f32 = 1.5;
19-
const SPAWN_POS: Vec3 = Vec3::new(250.0, 0.0, 0.0);
19+
const SPAWN_POS: Vec3 = Vec3::new(200.0, 0.0, 0.0);
2020

2121
#[derive(Component)]
2222
struct Shadow;
@@ -25,11 +25,30 @@ struct DemonCollider;
2525

2626
#[derive(Component, Deref, DerefMut)]
2727
struct SpawnDelay(Timer);
28+
#[derive(Component)]
29+
struct Smoke;
30+
31+
fn spawn_smokes(commands: &mut Commands, assets: &Res<GameAssets>, pos: Vec3) {
32+
let mut animator = AnimationPlayer2D::default();
33+
animator.play(assets.demon_boss_smoke_animations[0].clone());
34+
35+
commands.spawn((
36+
Smoke,
37+
animator,
38+
YSort(1.0),
39+
SpriteSheetBundle {
40+
texture_atlas: assets.demon_boss_smoke.clone(),
41+
transform: Transform::from_translation(pos).with_scale(Vec3::splat(5.0)),
42+
..default()
43+
},
44+
));
45+
}
2846

2947
fn spawn_demon_boss(
3048
mut commands: Commands,
3149
assets: Res<GameAssets>,
3250
time: Res<Time>,
51+
q_smoke: Query<Entity, (With<Smoke>, Without<SpawnDelay>)>,
3352
mut q_delay: Query<(Entity, &mut SpawnDelay)>,
3453
) {
3554
let (entity, mut delay) = match q_delay.get_single_mut() {
@@ -43,6 +62,13 @@ fn spawn_demon_boss(
4362
}
4463
commands.entity(entity).despawn_recursive();
4564

65+
let pos = PLAYER_SPAWN_POS + SPAWN_POS;
66+
if q_smoke.is_empty() {
67+
spawn_smokes(&mut commands, &assets, pos);
68+
commands.spawn(SpawnDelay(Timer::from_seconds(0.2, TimerMode::Once)));
69+
return;
70+
}
71+
4672
let mut animator = AnimationPlayer2D::default();
4773
animator
4874
.play(assets.enemy_boss_animations[0].clone())
@@ -83,8 +109,7 @@ fn spawn_demon_boss(
83109
YSort(36.0 * SCALE * TRANSLATION_TO_PIXEL),
84110
SpriteSheetBundle {
85111
texture_atlas: assets.enemy_boss.clone(),
86-
transform: Transform::from_translation(PLAYER_SPAWN_POS + SPAWN_POS)
87-
.with_scale(Vec3::splat(SCALE)),
112+
transform: Transform::from_translation(pos).with_scale(Vec3::splat(SCALE)),
88113
..default()
89114
},
90115
))
@@ -100,7 +125,7 @@ fn spawn_demon_boss_delay(
100125
}
101126
ev_trigger_final_act.clear();
102127

103-
commands.spawn(SpawnDelay(Timer::from_seconds(3.5, TimerMode::Once)));
128+
commands.spawn(SpawnDelay(Timer::from_seconds(5.0, TimerMode::Once)));
104129
}
105130

106131
fn despawn_demon_boss(

src/item/platform.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ fn trigger_final_act(
185185
CollisionEvent::Stopped(_, _, _) => continue,
186186
};
187187

188-
if !(&player.collider_entity == source && &item_entity == target)
189-
&& !(&player.collider_entity == target && &item_entity == source)
188+
if !(&player.collider_entity == source && &item_entity == target
189+
|| &player.collider_entity == target && &item_entity == source)
190190
{
191191
continue;
192192
}

0 commit comments

Comments
 (0)