diff --git a/assets/sprites/shield.png b/assets/sprites/shield.png deleted file mode 100644 index 5075be5..0000000 Binary files a/assets/sprites/shield.png and /dev/null differ diff --git a/assets/sprites/speed.png b/assets/sprites/speed.png deleted file mode 100644 index 8186b79..0000000 Binary files a/assets/sprites/speed.png and /dev/null differ diff --git a/src/core/bubble.rs b/src/core/bubble.rs index d997a6d..62e2903 100644 --- a/src/core/bubble.rs +++ b/src/core/bubble.rs @@ -21,7 +21,7 @@ pub fn bubble_spawn(mut commands: Commands, asset_server: Res) { let texture: Handle = asset_server.load("sprites/bubble.png"); let mut rng = rand::rng(); - for _ in 0..500 { + for _ in 0..50 { let angle = rng.random_range(0.0..TAU); let pos = Vec2::from_angle(angle) * 500.0; diff --git a/src/core/collectible.rs b/src/core/collectible.rs new file mode 100644 index 0000000..c69a86b --- /dev/null +++ b/src/core/collectible.rs @@ -0,0 +1,118 @@ +use std::path::Path; +use std::time::Duration; + +#[derive(Component)] +struct kirbyTimer(Timer); + +use crate::core::counter::BubbleKilledTotalCount; +use crate::core::kirby::{Kirby, kirby_spawn}; +use crate::physics::sphere_collider::SphereCollider; +use bevy::prelude::*; + +const ASSETS_NAME: [&str; 3] = ["speed_item.png", "shield_item.png", "kirby_item.png"]; +const COLLECTABLE_COLLIDER_RADIUS: f32 = 50.0; +const KIRBY_SPAWN_TIMER_DURATION: Duration = Duration::from_secs(2); + +#[derive(Clone, Copy)] +pub enum CollectableType { + SpeedBoost = 0, + ShieldBoost = 1, + NewKirby = 2, +} + +#[derive(Component)] +#[require(SphereCollider, Sprite)] +pub struct Collectable(CollectableType); + +// Not a system. +pub fn collectable_spawn( + commands: &mut Commands, + asset_server: &Res, + collectable_type: CollectableType, + pos: Vec3, +) { + let asset_name = ASSETS_NAME[collectable_type as usize]; + let asset_path = Path::new("sprites").join(asset_name); + let sprite = Sprite::from_image(asset_server.load(asset_path)); + commands.spawn(( + Collectable(collectable_type), + SphereCollider::new(COLLECTABLE_COLLIDER_RADIUS), + Transform::from_translation(pos).with_scale(Vec3::splat(5.0)), + sprite, + )); +} + +pub struct CollectableSpawner; +pub fn collectable_spawner_init(mut commands: Commands, asset_server: Res) { + collectable_spawn(&mut commands, &asset_server, CollectableType::NewKirby, Vec3::new(250.0, 250.0, 0.0)); +} + +pub fn collectable_actions_system( + mut commands: Commands, + mut kirby_query: Query<(&mut Kirby, &SphereCollider, &Transform)>, + collectable_query: Query<(Entity, &Collectable, &SphereCollider, &Transform)>, +) { + for (mut kirby, kirby_collider, kirby_tf) in &mut kirby_query { + for (collectible_entity, collectible, c_collider, collectable_tf) in collectable_query { + let collides = c_collider.collides(collectable_tf.translation, kirby_collider, kirby_tf.translation); + let kirby_pos = kirby_tf.translation; + if !collides { + continue; + } + + match &collectible.0 { + CollectableType::SpeedBoost => speed_boost(&mut kirby), + CollectableType::ShieldBoost => shield_boost(&mut kirby), + CollectableType::NewKirby => new_kirby(kirby_pos, &mut commands), + } + + commands.entity(collectible_entity).despawn(); + } + } +} + +fn speed_boost(kirby: &mut Kirby) { + kirby.speed_force *= 1.2; +} + +fn shield_boost(kirby: &mut Kirby) { + kirby.shield_factor *= 0.8; +} + +fn new_kirby(kirby_pos: Vec3, commands: &mut Commands) { + commands.spawn( + (KirbySpawnHandler { timer: Timer::new(KIRBY_SPAWN_TIMER_DURATION, TimerMode::Once), position: kirby_pos }), + ); +} + +#[derive(Component)] +struct KirbySpawnHandler { + timer: Timer, + position: Vec3, +} + +// After player get new_kirby item, it should spawn a new_kirby after a certain time +pub fn kirby_spawn_timer( + mut commands: Commands, + asset_server: Res, + mut texture_atlas_layouts: ResMut>, + query: Query<(&mut KirbySpawnHandler, Entity)>, + time: Res