waves
This commit is contained in:
parent
751d8097d2
commit
4b9101ad2c
7 changed files with 143 additions and 29 deletions
|
|
@ -4,11 +4,12 @@ use bevy::prelude::*;
|
|||
use rand::Rng;
|
||||
|
||||
use crate::{
|
||||
core::kirby::Kirby,
|
||||
core::life::{DamageDealer, Life},
|
||||
physics::density_grid::DensityObject,
|
||||
physics::physics_body::PhysicsBody,
|
||||
physics::sphere_collider::SphereCollider,
|
||||
core::{
|
||||
kirby::Kirby,
|
||||
life::{DamageDealer, Life},
|
||||
wave::BubbleSplash,
|
||||
},
|
||||
physics::{density_grid::DensityObject, physics_body::PhysicsBody, sphere_collider::SphereCollider},
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
|
|
@ -17,23 +18,29 @@ pub struct Bubble {
|
|||
move_force: f32,
|
||||
}
|
||||
|
||||
pub fn bubble_spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
// pub fn bubble_spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
// bubble_spawn_wave(&mut commands, &asset_server, 1000);
|
||||
// }
|
||||
|
||||
pub fn bubble_spawn_wave(commands: &mut Commands, asset_server: &Res<AssetServer>, bubble_splashes: &[BubbleSplash]) {
|
||||
let texture: Handle<Image> = asset_server.load("sprites/bubble.png");
|
||||
let mut rng = rand::rng();
|
||||
|
||||
for _ in 0..50 {
|
||||
let angle = rng.random_range(0.0..TAU);
|
||||
let pos = Vec2::from_angle(angle) * 500.0;
|
||||
for BubbleSplash { bubble_type, center, radius, nb_bubbles } in bubble_splashes {
|
||||
for _ in 0..*nb_bubbles {
|
||||
let angle = rng.random_range(0.0..TAU);
|
||||
let pos = center + Vec2::from_angle(angle) * radius;
|
||||
|
||||
commands.spawn((
|
||||
Bubble { move_force: 3000.0 },
|
||||
Sprite { image: texture.clone(), ..default() },
|
||||
PhysicsBody { mass: 10.0, force: Vec2::ZERO, velocity: Vec2::ZERO, drag: 0.05 },
|
||||
Transform::from_translation(pos.extend(0.0)).with_scale(Vec3::splat(1.0)),
|
||||
Life::new(10.0),
|
||||
DamageDealer::new(0.5),
|
||||
SphereCollider::new(20.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Bubble { move_force: bubble_type.move_force },
|
||||
Sprite { image: texture.clone(), color: bubble_type.color, ..default() },
|
||||
PhysicsBody { mass: 10.0, force: Vec2::ZERO, velocity: Vec2::ZERO, drag: 0.05 },
|
||||
Transform::from_translation(pos.extend(0.0)).with_scale(Vec3::splat(1.0)),
|
||||
Life::new(bubble_type.max_life),
|
||||
DamageDealer::new(0.5),
|
||||
SphereCollider::new(20.0),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,6 +69,6 @@ pub struct BubblePlugin;
|
|||
|
||||
impl Plugin for BubblePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, bubble_spawn).add_systems(FixedUpdate, bubble_move);
|
||||
app.add_systems(FixedUpdate, bubble_move);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
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::*;
|
||||
|
|
@ -80,9 +76,10 @@ fn shield_boost(kirby: &mut Kirby) {
|
|||
}
|
||||
|
||||
fn new_kirby(kirby_pos: Vec3, commands: &mut Commands) {
|
||||
commands.spawn(
|
||||
(KirbySpawnHandler { timer: Timer::new(KIRBY_SPAWN_TIMER_DURATION, TimerMode::Once), position: kirby_pos }),
|
||||
);
|
||||
commands.spawn(KirbySpawnHandler {
|
||||
timer: Timer::new(KIRBY_SPAWN_TIMER_DURATION, TimerMode::Once),
|
||||
position: kirby_pos,
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
|
|
@ -92,7 +89,7 @@ struct KirbySpawnHandler {
|
|||
}
|
||||
|
||||
// After player get new_kirby item, it should spawn a new_kirby after a certain time
|
||||
pub fn kirby_spawn_timer(
|
||||
fn kirby_spawn_timer(
|
||||
mut commands: Commands,
|
||||
asset_server: Res<AssetServer>,
|
||||
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ pub fn kirby_spawn(
|
|||
Transform::from_xyz(40.0, 0.0, 0.0),
|
||||
SuckArea,
|
||||
SphereCollider::new(80.0),
|
||||
DamageDealer::new(10000.0),
|
||||
DamageDealer::new(100.0),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ pub mod collectible;
|
|||
pub mod counter;
|
||||
pub mod kirby;
|
||||
pub mod life;
|
||||
pub mod wave;
|
||||
|
|
|
|||
97
src/core/wave.rs
Normal file
97
src/core/wave.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
use std::thread::panicking;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use rand::distr::slice::Empty;
|
||||
|
||||
use crate::{
|
||||
core::bubble::{Bubble, bubble_spawn_wave},
|
||||
map::map::{BOTTOM, LEFT, RIGHT, TOP},
|
||||
};
|
||||
|
||||
pub struct BubbleType {
|
||||
pub color: Color,
|
||||
pub move_force: f32,
|
||||
pub max_life: f32,
|
||||
}
|
||||
|
||||
pub struct BubbleSplash {
|
||||
pub bubble_type: BubbleType,
|
||||
pub center: Vec2,
|
||||
pub radius: f32,
|
||||
pub nb_bubbles: u32,
|
||||
}
|
||||
|
||||
impl BubbleSplash {
|
||||
fn new(bubble_type: BubbleType, center: Vec2, radius: f32, nb_bubbles: u32) -> Self {
|
||||
BubbleSplash { bubble_type, center, radius, nb_bubbles }
|
||||
}
|
||||
}
|
||||
|
||||
const BASE_MOVE_FORCE: f32 = 3000.0;
|
||||
const BASE_LIFE: f32 = 10.0;
|
||||
|
||||
const NORMAL_BUBBLE: BubbleType = BubbleType {
|
||||
color: Color::linear_rgb(1.0, 1.0, 1.0),
|
||||
move_force: BASE_MOVE_FORCE * 1.0,
|
||||
max_life: BASE_LIFE * 1.0,
|
||||
};
|
||||
|
||||
const RED_BUBBLE: BubbleType = BubbleType {
|
||||
color: Color::linear_rgb(1.0, 0.0, 0.0),
|
||||
move_force: BASE_MOVE_FORCE * 2.0,
|
||||
max_life: BASE_LIFE * 0.5,
|
||||
};
|
||||
|
||||
const GREEN_BUBBLE: BubbleType = BubbleType {
|
||||
color: Color::linear_rgb(1.0, 0.0, 0.0),
|
||||
move_force: BASE_MOVE_FORCE * 0.5,
|
||||
max_life: BASE_LIFE * 2.0,
|
||||
};
|
||||
|
||||
#[derive(Resource)]
|
||||
pub struct BubbleWaves {
|
||||
pub waves: Vec<Vec<BubbleSplash>>,
|
||||
pub current_wave: usize,
|
||||
}
|
||||
|
||||
fn get_bubble_waves() -> BubbleWaves {
|
||||
BubbleWaves {
|
||||
waves: vec![
|
||||
vec![BubbleSplash::new(NORMAL_BUBBLE, RIGHT, 10.0, 10)],
|
||||
vec![BubbleSplash::new(NORMAL_BUBBLE, RIGHT, 10.0, 10), BubbleSplash::new(NORMAL_BUBBLE, TOP, 10.0, 10)],
|
||||
vec![BubbleSplash::new(NORMAL_BUBBLE, RIGHT, 10.0, 100), BubbleSplash::new(NORMAL_BUBBLE, TOP, 10.0, 100)],
|
||||
vec![
|
||||
BubbleSplash::new(NORMAL_BUBBLE, RIGHT, 10.0, 100),
|
||||
BubbleSplash::new(NORMAL_BUBBLE, TOP, 10.0, 100),
|
||||
BubbleSplash::new(RED_BUBBLE, BOTTOM, 10.0, 20),
|
||||
],
|
||||
vec![
|
||||
BubbleSplash::new(NORMAL_BUBBLE, RIGHT, 10.0, 200),
|
||||
BubbleSplash::new(RED_BUBBLE, RIGHT, 10.0, 100),
|
||||
BubbleSplash::new(RED_BUBBLE, LEFT, 10.0, 100),
|
||||
],
|
||||
],
|
||||
current_wave: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn no_ennemy_left(bubble_query: Query<(), With<Bubble>>) -> bool {
|
||||
bubble_query.is_empty()
|
||||
}
|
||||
|
||||
fn change_wave(mut bubble_wave: ResMut<BubbleWaves>, mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
let max_bubble_wave = bubble_wave.waves.len();
|
||||
bubble_wave.current_wave += 1;
|
||||
if bubble_wave.current_wave >= max_bubble_wave {
|
||||
panic!("GG you win");
|
||||
}
|
||||
bubble_spawn_wave(&mut commands, &asset_server, bubble_wave.waves[bubble_wave.current_wave].as_slice());
|
||||
}
|
||||
|
||||
pub struct WavePlugin;
|
||||
|
||||
impl Plugin for WavePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(get_bubble_waves()).add_systems(Update, change_wave.run_if(no_ennemy_left));
|
||||
}
|
||||
}
|
||||
|
|
@ -14,12 +14,15 @@ use core::life::{bubble_receive_damage, despawn_if_dead, kirby_receive_damage};
|
|||
|
||||
mod map;
|
||||
use map::map::MAP_SIZE;
|
||||
use map::map::MAP_WIDTH;
|
||||
use map::map::MapBounds;
|
||||
|
||||
mod juice;
|
||||
use juice::animation::animate_sprite;
|
||||
use juice::camera::MyCameraPlugin;
|
||||
|
||||
use crate::core::wave::WavePlugin;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()).set(WindowPlugin {
|
||||
|
|
@ -37,8 +40,9 @@ fn main() {
|
|||
.add_plugins(BubblePlugin)
|
||||
.add_plugins(MyCameraPlugin)
|
||||
.add_plugins(CollectablePlugin)
|
||||
.add_plugins(WavePlugin)
|
||||
.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_WIDTH as f32, max: Vec2::ONE * MAP_WIDTH as f32 })
|
||||
.add_systems(Update, animate_sprite)
|
||||
.add_systems(FixedUpdate, bubble_receive_damage)
|
||||
.add_systems(FixedUpdate, kirby_receive_damage)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
pub const MAP_SIZE: u32 = 1000;
|
||||
pub const MAP_WIDTH: u32 = MAP_SIZE / 2;
|
||||
|
||||
pub const NEAR_LIMIT: f32 = (MAP_WIDTH as f32) * 0.8;
|
||||
|
||||
pub const RIGHT: Vec2 = Vec2::new(NEAR_LIMIT, 0.0);
|
||||
pub const LEFT: Vec2 = Vec2::new(-NEAR_LIMIT, 0.0);
|
||||
pub const TOP: Vec2 = Vec2::new(0.0, NEAR_LIMIT);
|
||||
pub const BOTTOM: Vec2 = Vec2::new(0.0, -NEAR_LIMIT);
|
||||
|
||||
#[derive(Resource)]
|
||||
pub struct MapBounds {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue