collectables
This commit is contained in:
parent
467f147142
commit
5cafda10af
11 changed files with 162 additions and 19 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 193 B |
Binary file not shown.
|
Before Width: | Height: | Size: 181 B |
|
|
@ -21,7 +21,7 @@ pub fn bubble_spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
let texture: Handle<Image> = asset_server.load("sprites/bubble.png");
|
let texture: Handle<Image> = asset_server.load("sprites/bubble.png");
|
||||||
let mut rng = rand::rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
for _ in 0..500 {
|
for _ in 0..50 {
|
||||||
let angle = rng.random_range(0.0..TAU);
|
let angle = rng.random_range(0.0..TAU);
|
||||||
let pos = Vec2::from_angle(angle) * 500.0;
|
let pos = Vec2::from_angle(angle) * 500.0;
|
||||||
|
|
||||||
|
|
|
||||||
118
src/core/collectible.rs
Normal file
118
src/core/collectible.rs
Normal file
|
|
@ -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<AssetServer>,
|
||||||
|
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<AssetServer>) {
|
||||||
|
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<AssetServer>,
|
||||||
|
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
||||||
|
query: Query<(&mut KirbySpawnHandler, Entity)>,
|
||||||
|
time: Res<Time>,
|
||||||
|
) {
|
||||||
|
for (mut kirby_spawn_handler, kirby_spawn_entity) in query {
|
||||||
|
kirby_spawn_handler.timer.tick(time.delta());
|
||||||
|
if kirby_spawn_handler.timer.is_finished() {
|
||||||
|
kirby_spawn(&mut commands, &asset_server, &mut texture_atlas_layouts, kirby_spawn_handler.position);
|
||||||
|
commands.entity(kirby_spawn_entity).despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct CollectablePlugin;
|
||||||
|
|
||||||
|
impl Plugin for CollectablePlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(Startup, collectable_spawner_init)
|
||||||
|
.add_systems(FixedUpdate, collectable_actions_system)
|
||||||
|
.add_systems(Update, kirby_spawn_timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ use derive_more::{Deref, DerefMut};
|
||||||
|
|
||||||
#[derive(Resource, Default)]
|
#[derive(Resource, Default)]
|
||||||
pub struct Counter {
|
pub struct Counter {
|
||||||
pub count: u32,
|
count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Counter {
|
impl Counter {
|
||||||
|
|
@ -14,7 +14,14 @@ impl Counter {
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.count = 0;
|
self.count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_count(&self) -> u32 {
|
||||||
|
self.count
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Resource, Default)]
|
||||||
|
pub struct BubbleKilledTotalCount(pub Counter);
|
||||||
|
|
||||||
#[derive(Resource, Default, Deref, DerefMut)]
|
#[derive(Resource, Default, Deref, DerefMut)]
|
||||||
pub struct BubbleExplodedCountThisFrame(pub Counter);
|
pub struct BubbleExplodedCountThisFrame(pub Counter);
|
||||||
|
|
@ -26,13 +33,15 @@ pub struct BubbleSuckedCountThisFrame(pub Counter);
|
||||||
pub struct KirbyHitCountThisFrame(pub Counter);
|
pub struct KirbyHitCountThisFrame(pub Counter);
|
||||||
|
|
||||||
fn reset_frame_counters(
|
fn reset_frame_counters(
|
||||||
mut bubble_sucked: ResMut<BubbleSuckedCountThisFrame>,
|
mut bubble_sucked_this_frame: ResMut<BubbleSuckedCountThisFrame>,
|
||||||
mut bubble_exploded: ResMut<BubbleExplodedCountThisFrame>,
|
mut bubble_exploded_this_frame: ResMut<BubbleExplodedCountThisFrame>,
|
||||||
mut kirby_hit: ResMut<KirbyHitCountThisFrame>,
|
mut kirby_hit_count_this_frame: ResMut<KirbyHitCountThisFrame>,
|
||||||
|
mut total_killed: ResMut<BubbleKilledTotalCount>,
|
||||||
) {
|
) {
|
||||||
bubble_sucked.reset();
|
total_killed.0.count += bubble_sucked_this_frame.count + bubble_exploded_this_frame.count;
|
||||||
bubble_exploded.reset();
|
bubble_sucked_this_frame.reset();
|
||||||
kirby_hit.reset();
|
bubble_exploded_this_frame.reset();
|
||||||
|
kirby_hit_count_this_frame.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CounterPlugin;
|
pub struct CounterPlugin;
|
||||||
|
|
@ -42,6 +51,7 @@ impl Plugin for CounterPlugin {
|
||||||
app.insert_resource(BubbleSuckedCountThisFrame::default())
|
app.insert_resource(BubbleSuckedCountThisFrame::default())
|
||||||
.insert_resource(BubbleExplodedCountThisFrame::default())
|
.insert_resource(BubbleExplodedCountThisFrame::default())
|
||||||
.insert_resource(KirbyHitCountThisFrame::default())
|
.insert_resource(KirbyHitCountThisFrame::default())
|
||||||
|
.insert_resource(BubbleKilledTotalCount::default())
|
||||||
.add_systems(FixedPostUpdate, reset_frame_counters);
|
.add_systems(FixedPostUpdate, reset_frame_counters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,25 @@ pub struct SuckArea;
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
#[require(Sprite, PhysicsBody, SphereCollider, AnimationIndices, Life)]
|
#[require(Sprite, PhysicsBody, SphereCollider, AnimationIndices, Life)]
|
||||||
pub struct Kirby {
|
pub struct Kirby {
|
||||||
speed_force: f32,
|
pub speed_force: f32,
|
||||||
pub is_sucking: bool,
|
pub is_sucking: bool,
|
||||||
|
pub shield_factor: f32, // 1.0 receive full damage, 0.1 receive 10% of damage
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kirby_spawn(
|
pub fn kirby_spawn_start(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
||||||
|
) {
|
||||||
|
kirby_spawn(&mut commands, &asset_server, &mut texture_atlas_layouts, Vec3::ZERO);
|
||||||
|
// kirby_spawn(&mut commands, &asset_server, &mut texture_atlas_layouts, Vec3 { x: 500.0, y: 0.0, z: 0.0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kirby_spawn(
|
||||||
|
commands: &mut Commands,
|
||||||
|
asset_server: &Res<AssetServer>,
|
||||||
|
texture_atlas_layouts: &mut ResMut<Assets<TextureAtlasLayout>>,
|
||||||
|
pos: Vec3,
|
||||||
) {
|
) {
|
||||||
let texture: Handle<Image> = asset_server.load("sprites/Sprite_kirby-Sheet.png");
|
let texture: Handle<Image> = asset_server.load("sprites/Sprite_kirby-Sheet.png");
|
||||||
let layout = TextureAtlasLayout::from_grid(UVec2::splat(32), 3, 3, None, None);
|
let layout = TextureAtlasLayout::from_grid(UVec2::splat(32), 3, 3, None, None);
|
||||||
|
|
@ -32,7 +43,7 @@ pub fn kirby_spawn(
|
||||||
|
|
||||||
let kirby_entity = commands
|
let kirby_entity = commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Kirby { speed_force: 10000.0, is_sucking: false },
|
Kirby { speed_force: 10000.0, is_sucking: false, shield_factor: 1.0 },
|
||||||
Sprite::from_atlas_image(
|
Sprite::from_atlas_image(
|
||||||
texture,
|
texture,
|
||||||
TextureAtlas { layout: texture_atlas_layout, index: animation_indices.first },
|
TextureAtlas { layout: texture_atlas_layout, index: animation_indices.first },
|
||||||
|
|
@ -42,7 +53,7 @@ pub fn kirby_spawn(
|
||||||
animation_indices,
|
animation_indices,
|
||||||
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
|
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
|
||||||
Life::new(1000.0),
|
Life::new(1000.0),
|
||||||
Transform::from_scale(Vec3::splat(KIRBY_SCALE)),
|
Transform::from_translation(pos).with_scale(Vec3::splat(KIRBY_SCALE)),
|
||||||
))
|
))
|
||||||
.id();
|
.id();
|
||||||
|
|
||||||
|
|
@ -108,6 +119,6 @@ pub struct KirbyPlugin;
|
||||||
|
|
||||||
impl Plugin for KirbyPlugin {
|
impl Plugin for KirbyPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(Startup, kirby_spawn).add_systems(FixedUpdate, kirby_actions);
|
app.add_systems(Startup, kirby_spawn_start).add_systems(FixedUpdate, kirby_actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,16 +86,16 @@ pub fn bubble_receive_damage(
|
||||||
pub fn kirby_receive_damage(
|
pub fn kirby_receive_damage(
|
||||||
mut bubble_exploded: ResMut<BubbleExplodedCountThisFrame>,
|
mut bubble_exploded: ResMut<BubbleExplodedCountThisFrame>,
|
||||||
mut kirby_hit: ResMut<KirbyHitCountThisFrame>,
|
mut kirby_hit: ResMut<KirbyHitCountThisFrame>,
|
||||||
mut kirby_query: Query<(&GlobalTransform, &mut Life), (With<Kirby>, Without<Bubble>)>,
|
mut kirby_query: Query<(&Kirby, &GlobalTransform, &mut Life), (Without<Bubble>)>,
|
||||||
mut bubble_query: Query<
|
mut bubble_query: Query<
|
||||||
(&GlobalTransform, &SphereCollider, &DamageDealer, &mut Life),
|
(&GlobalTransform, &SphereCollider, &DamageDealer, &mut Life),
|
||||||
(With<Bubble>, Without<Kirby>),
|
(With<Bubble>, Without<Kirby>),
|
||||||
>,
|
>,
|
||||||
) {
|
) {
|
||||||
for (kirby_transform, mut kirby_life) in &mut kirby_query {
|
for (kirby, kirby_transform, mut kirby_life) in &mut kirby_query {
|
||||||
for (bubble_transform, bubble_sphere_collider, bubble_damage_dealer, mut bubble_life) in &mut bubble_query {
|
for (bubble_transform, bubble_sphere_collider, bubble_damage_dealer, mut bubble_life) in &mut bubble_query {
|
||||||
if bubble_sphere_collider.point_inside(kirby_transform.translation(), bubble_transform.translation()) {
|
if bubble_sphere_collider.point_inside(kirby_transform.translation(), bubble_transform.translation()) {
|
||||||
kirby_life.damage(bubble_damage_dealer.damage_strength);
|
kirby_life.damage(bubble_damage_dealer.damage_strength * kirby.shield_factor);
|
||||||
bubble_life.damage(1000000.0); // Bubble explode
|
bubble_life.damage(1000000.0); // Bubble explode
|
||||||
// println!("{:?}", kirby_life.current_life)
|
// println!("{:?}", kirby_life.current_life)
|
||||||
bubble_exploded.increase(1);
|
bubble_exploded.increase(1);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod bubble;
|
pub mod bubble;
|
||||||
|
pub mod collectible;
|
||||||
pub mod counter;
|
pub mod counter;
|
||||||
pub mod kirby;
|
pub mod kirby;
|
||||||
pub mod life;
|
pub mod life;
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ pub fn camera_shake(
|
||||||
|
|
||||||
let rand_angle = rand::random_range(0.0..TAU);
|
let rand_angle = rand::random_range(0.0..TAU);
|
||||||
let rand_vec = Vec2::from_angle(rand_angle);
|
let rand_vec = Vec2::from_angle(rand_angle);
|
||||||
let shaking_strength = kirby_hit_count.count as f32 * parent.shaking_intensity_factor;
|
let shaking_strength = kirby_hit_count.get_count() as f32 * parent.shaking_intensity_factor;
|
||||||
let shaking_vec = rand_vec * shaking_strength;
|
let shaking_vec = rand_vec * shaking_strength;
|
||||||
let mut child_translation = child_transform.translation.clone();
|
let mut child_translation = child_transform.translation.clone();
|
||||||
child_translation += shaking_vec.extend(0.0);
|
child_translation += shaking_vec.extend(0.0);
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,19 @@ use physics::physics_body::physics_integrate;
|
||||||
|
|
||||||
mod core;
|
mod core;
|
||||||
use core::bubble::BubblePlugin;
|
use core::bubble::BubblePlugin;
|
||||||
|
use core::collectible::CollectablePlugin;
|
||||||
use core::counter::CounterPlugin;
|
use core::counter::CounterPlugin;
|
||||||
use core::kirby::KirbyPlugin;
|
use core::kirby::KirbyPlugin;
|
||||||
use core::life::{bubble_receive_damage, despawn_if_dead, kirby_receive_damage};
|
use core::life::{bubble_receive_damage, despawn_if_dead, kirby_receive_damage};
|
||||||
|
|
||||||
mod map;
|
mod map;
|
||||||
|
use map::map::MAP_SIZE;
|
||||||
use map::map::MapBounds;
|
use map::map::MapBounds;
|
||||||
|
|
||||||
mod juice;
|
mod juice;
|
||||||
use juice::animation::animate_sprite;
|
use juice::animation::animate_sprite;
|
||||||
use juice::camera::MyCameraPlugin;
|
use juice::camera::MyCameraPlugin;
|
||||||
|
|
||||||
const MAP_SIZE: u32 = 1000;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()).set(WindowPlugin {
|
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()).set(WindowPlugin {
|
||||||
|
|
@ -36,6 +36,7 @@ fn main() {
|
||||||
.add_plugins(DensityGridPlugin)
|
.add_plugins(DensityGridPlugin)
|
||||||
.add_plugins(BubblePlugin)
|
.add_plugins(BubblePlugin)
|
||||||
.add_plugins(MyCameraPlugin)
|
.add_plugins(MyCameraPlugin)
|
||||||
|
.add_plugins(CollectablePlugin)
|
||||||
.insert_resource(Time::<Fixed>::from_seconds(1.0 / 60.0))
|
.insert_resource(Time::<Fixed>::from_seconds(1.0 / 60.0))
|
||||||
.insert_resource(MapBounds { min: -Vec2::ONE * MAP_SIZE as f32 / 2.0, max: Vec2::ONE * MAP_SIZE as f32 / 2.0 })
|
.insert_resource(MapBounds { min: -Vec2::ONE * MAP_SIZE as f32 / 2.0, max: Vec2::ONE * MAP_SIZE as f32 / 2.0 })
|
||||||
.add_systems(Update, animate_sprite)
|
.add_systems(Update, animate_sprite)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
pub const MAP_SIZE: u32 = 1000;
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct MapBounds {
|
pub struct MapBounds {
|
||||||
pub min: Vec2,
|
pub min: Vec2,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue