save
This commit is contained in:
parent
895b56c326
commit
ee8799c324
8 changed files with 177 additions and 38 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use std::{f32::consts::TAU, fmt::Debug};
|
||||
use std::f32::consts::TAU;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use rand::Rng;
|
||||
|
|
@ -8,10 +8,11 @@ use crate::{
|
|||
kirby::Kirby,
|
||||
life::{DamageDealer, Life},
|
||||
physics_body::PhysicsBody,
|
||||
sphere_collider::SphereCollider,
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
#[require(Sprite, PhysicsBody, DensityObject, Life, DamageDealer)]
|
||||
#[require(Sprite, PhysicsBody, DensityObject, Life, DamageDealer, SphereCollider)]
|
||||
pub struct Bubble {
|
||||
move_force: f32,
|
||||
}
|
||||
|
|
@ -27,10 +28,11 @@ pub fn bubble_spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
commands.spawn((
|
||||
Bubble { move_force: 3000.0 },
|
||||
Sprite { image: texture.clone(), ..default() },
|
||||
Transform::from_translation(pos.extend(0.0)).with_scale(Vec3::splat(1.0)),
|
||||
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),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -55,3 +57,11 @@ pub fn bubble_move(
|
|||
bubble_body.force += dir * bubble.move_force;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BubblePlugin;
|
||||
|
||||
impl Plugin for BubblePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, bubble_spawn).add_systems(FixedUpdate, bubble_move);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,51 @@
|
|||
use std::f32::consts::TAU;
|
||||
|
||||
use bevy::{prelude::*, render::renderer};
|
||||
|
||||
pub fn spawn_camera(mut commands: Commands) {
|
||||
commands.spawn(Camera2d);
|
||||
use crate::counter::KirbyHitCountThisFrame;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct MyCamera {
|
||||
shaking_intensity_factor: f32,
|
||||
shaking_reset_speed: f32,
|
||||
}
|
||||
|
||||
pub fn spawn_camera(mut commands: Commands) {
|
||||
let mycam = commands
|
||||
.spawn((
|
||||
MyCamera { shaking_intensity_factor: 10.0, shaking_reset_speed: 0.1 },
|
||||
Transform::from_translation(Vec3::ZERO),
|
||||
))
|
||||
.id();
|
||||
commands.entity(mycam).with_child((Camera2d, Transform::from_xyz(0.0, 0.0, 0.0)));
|
||||
}
|
||||
|
||||
pub fn camera_shake(
|
||||
time: Res<Time<Fixed>>,
|
||||
kirby_hit_count: Res<KirbyHitCountThisFrame>,
|
||||
parent_query: Query<(&MyCamera, &Children)>,
|
||||
mut children_query: Query<&mut Transform, With<Camera2d>>,
|
||||
) {
|
||||
let (parent, children) = parent_query.single().expect("Expect exactly one MyCamera entity");
|
||||
let child = children.first().expect("MyCamera must have at least one child Camera2d");
|
||||
let mut child_transform = children_query.get_mut(*child).expect("Camera child must have a Transform and Camera2d");
|
||||
|
||||
let rand_angle = rand::random_range(0.0..TAU);
|
||||
let rand_vec = Vec2::from_angle(rand_angle);
|
||||
let shaking_strength = kirby_hit_count.count as f32 * parent.shaking_intensity_factor;
|
||||
let shaking_vec = rand_vec * shaking_strength;
|
||||
let mut child_translation = child_transform.translation.clone();
|
||||
child_translation += shaking_vec.extend(0.0);
|
||||
child_translation -= child_translation * parent.shaking_reset_speed * time.delta_secs();
|
||||
child_transform.translation.x = child_translation.x;
|
||||
child_transform.translation.y = child_translation.y;
|
||||
// println!("{:?}", child_transform.translation);
|
||||
}
|
||||
|
||||
pub struct MyCameraPlugin;
|
||||
|
||||
impl Plugin for MyCameraPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, spawn_camera).add_systems(FixedPostUpdate, camera_shake);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
51
src/counter.rs
Normal file
51
src/counter.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
use bevy::prelude::*;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
|
||||
#[derive(Resource, Default)]
|
||||
pub struct Counter {
|
||||
pub count: u32,
|
||||
}
|
||||
|
||||
impl Counter {
|
||||
pub fn new() -> Self {
|
||||
Counter { count: 0 }
|
||||
}
|
||||
|
||||
pub fn increase(&mut self, delta: u32) {
|
||||
self.count += delta;
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource, Default, Deref, DerefMut)]
|
||||
pub struct BubbleExplodedCountThisFrame(pub Counter);
|
||||
|
||||
#[derive(Resource, Default, Deref, DerefMut)]
|
||||
pub struct BubbleSuckedCountThisFrame(pub Counter);
|
||||
|
||||
#[derive(Resource, Default, Deref, DerefMut)]
|
||||
pub struct KirbyHitCountThisFrame(pub Counter);
|
||||
|
||||
fn reset_frame_counters(
|
||||
mut bubble_sucked: ResMut<BubbleSuckedCountThisFrame>,
|
||||
mut bubble_exploded: ResMut<BubbleExplodedCountThisFrame>,
|
||||
mut kirby_hit: ResMut<KirbyHitCountThisFrame>,
|
||||
) {
|
||||
bubble_sucked.reset();
|
||||
bubble_exploded.reset();
|
||||
kirby_hit.reset();
|
||||
}
|
||||
|
||||
pub struct CounterPlugin;
|
||||
|
||||
impl Plugin for CounterPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(BubbleSuckedCountThisFrame::default())
|
||||
.insert_resource(BubbleExplodedCountThisFrame::default())
|
||||
.insert_resource(KirbyHitCountThisFrame::default())
|
||||
.add_systems(FixedPostUpdate, reset_frame_counters);
|
||||
}
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ pub fn init_density_object(mut density_grid: ResMut<DensityGrid>, mut query: Que
|
|||
}
|
||||
}
|
||||
|
||||
pub fn density_grid_update(mut density_grid: ResMut<DensityGrid>, query: Query<&Transform>) {
|
||||
pub fn density_grid_update(mut density_grid: ResMut<DensityGrid>, query: Query<&Transform, With<DensityObject>>) {
|
||||
density_grid.grid.fill(0);
|
||||
|
||||
for transform in &query {
|
||||
|
|
@ -86,3 +86,13 @@ pub fn density_grid_force(
|
|||
physics_body.force -= density_gradient * DENSITY_FORCE_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DensityGridPlugin;
|
||||
|
||||
impl Plugin for DensityGridPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(DensityGrid::new())
|
||||
.add_systems(PostStartup, init_density_object)
|
||||
.add_systems(FixedUpdate, (density_grid_update, density_grid_force).chain());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
29
src/kirby.rs
29
src/kirby.rs
|
|
@ -26,7 +26,6 @@ pub fn kirby_spawn(
|
|||
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
||||
) {
|
||||
let texture: Handle<Image> = asset_server.load("sprites/Sprite_kirby-Sheet.png");
|
||||
let body = PhysicsBody { mass: 10.0, force: Vec2::ZERO, velocity: Vec2::ZERO, drag: 0.05 };
|
||||
let layout = TextureAtlasLayout::from_grid(UVec2::splat(32), 3, 3, None, None);
|
||||
let texture_atlas_layout = texture_atlas_layouts.add(layout);
|
||||
let animation_indices = AnimationIndices { first: 3, last: 5 }; // idle
|
||||
|
|
@ -38,22 +37,21 @@ pub fn kirby_spawn(
|
|||
texture,
|
||||
TextureAtlas { layout: texture_atlas_layout, index: animation_indices.first },
|
||||
),
|
||||
Transform::from_scale(Vec3::splat(KIRBY_SCALE)),
|
||||
PhysicsBody { mass: 10.0, force: Vec2::ZERO, velocity: Vec2::ZERO, drag: 0.05 },
|
||||
SphereCollider::new(20.0),
|
||||
animation_indices,
|
||||
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
|
||||
body,
|
||||
SphereCollider::new(50.0),
|
||||
Life::new(1000.0),
|
||||
Transform::from_scale(Vec3::splat(KIRBY_SCALE)),
|
||||
))
|
||||
.id();
|
||||
|
||||
commands.entity(kirby_entity).with_children(|parent| {
|
||||
parent.spawn((
|
||||
Transform::from_xyz(40.0, 0.0, 0.0),
|
||||
SuckArea,
|
||||
SphereCollider::new(80.0),
|
||||
DamageDealer::new(10000.0),
|
||||
));
|
||||
});
|
||||
commands.entity(kirby_entity).with_child((
|
||||
Transform::from_xyz(40.0, 0.0, 0.0),
|
||||
SuckArea,
|
||||
SphereCollider::new(80.0),
|
||||
DamageDealer::new(10000.0),
|
||||
));
|
||||
}
|
||||
|
||||
pub fn get_dir(keys: Res<ButtonInput<KeyCode>>) -> Vec2 {
|
||||
|
|
@ -106,3 +104,10 @@ pub fn kirby_actions(
|
|||
}
|
||||
}
|
||||
}
|
||||
pub struct KirbyPlugin;
|
||||
|
||||
impl Plugin for KirbyPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, kirby_spawn).add_systems(FixedUpdate, kirby_actions);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
24
src/life.rs
24
src/life.rs
|
|
@ -2,6 +2,7 @@ use bevy::prelude::*;
|
|||
|
||||
use crate::{
|
||||
bubble::Bubble,
|
||||
counter::{BubbleExplodedCountThisFrame, BubbleSuckedCountThisFrame, KirbyHitCountThisFrame},
|
||||
kirby::{Kirby, SuckArea},
|
||||
sphere_collider::SphereCollider,
|
||||
};
|
||||
|
|
@ -55,7 +56,7 @@ impl DamageDealer {
|
|||
// Considerating ennemies are ponctual
|
||||
pub fn bubble_receive_damage(
|
||||
time: Res<Time<Fixed>>,
|
||||
|
||||
mut bubble_sucked: ResMut<BubbleSuckedCountThisFrame>,
|
||||
mut enemy_query: Query<(&GlobalTransform, &mut Life), With<Bubble>>,
|
||||
|
||||
kirby_query: Query<(&Kirby, &Children)>,
|
||||
|
|
@ -74,6 +75,7 @@ pub fn bubble_receive_damage(
|
|||
for (enemy_transform, mut enemy_life) in &mut enemy_query {
|
||||
if suck_collider.point_inside(suck_transform.translation(), enemy_transform.translation()) {
|
||||
enemy_life.damage(suck_damage.damage_strength * time.delta_secs());
|
||||
bubble_sucked.increase(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -82,14 +84,22 @@ pub fn bubble_receive_damage(
|
|||
|
||||
// Considerating allies are ponctual
|
||||
pub fn kirby_receive_damage(
|
||||
mut ally_query: Query<(&GlobalTransform, &mut Life), With<Kirby>>,
|
||||
mut enemy_query: Query<(&GlobalTransform, &SphereCollider, &DamageDealer, &mut Life), With<Bubble>>,
|
||||
mut bubble_exploded: ResMut<BubbleExplodedCountThisFrame>,
|
||||
mut kirby_hit: ResMut<KirbyHitCountThisFrame>,
|
||||
mut kirby_query: Query<(&GlobalTransform, &mut Life), (With<Kirby>, Without<Bubble>)>,
|
||||
mut bubble_query: Query<
|
||||
(&GlobalTransform, &SphereCollider, &DamageDealer, &mut Life),
|
||||
(With<Bubble>, Without<Kirby>),
|
||||
>,
|
||||
) {
|
||||
for (ally_transform, mut ally_life) in &mut ally_query {
|
||||
for (enemy_transform, enemy_sphere_collider, enemy_damage_dealer, mut bubble_life) in &mut enemy_query {
|
||||
if enemy_sphere_collider.point_inside(ally_transform.translation(), enemy_transform.translation()) {
|
||||
ally_life.damage(enemy_damage_dealer.damage_strength);
|
||||
for (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 {
|
||||
if bubble_sphere_collider.point_inside(kirby_transform.translation(), bubble_transform.translation()) {
|
||||
kirby_life.damage(bubble_damage_dealer.damage_strength);
|
||||
bubble_life.damage(1000000.0); // Bubble explode
|
||||
// println!("{:?}", kirby_life.current_life)
|
||||
bubble_exploded.increase(1);
|
||||
kirby_hit.increase(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
27
src/main.rs
27
src/main.rs
|
|
@ -3,16 +3,21 @@ use bevy::prelude::*;
|
|||
use bubble::{bubble_move, bubble_spawn};
|
||||
use camera::spawn_camera;
|
||||
use density_grid::{DensityGrid, density_grid_force, density_grid_update, init_density_object};
|
||||
use kirby::{kirby_actions, kirby_spawn};
|
||||
use life::despawn_if_dead;
|
||||
use life::{bubble_receive_damage, kirby_receive_damage};
|
||||
use map::MapBounds;
|
||||
use physics_body::integrate;
|
||||
use physics_body::physics_integrate;
|
||||
|
||||
use crate::life::bubble_receive_damage;
|
||||
use crate::bubble::BubblePlugin;
|
||||
use crate::camera::MyCameraPlugin;
|
||||
use crate::counter::CounterPlugin;
|
||||
use crate::density_grid::DensityGridPlugin;
|
||||
use crate::kirby::KirbyPlugin;
|
||||
|
||||
mod animation;
|
||||
mod bubble;
|
||||
mod camera;
|
||||
mod counter;
|
||||
mod density_grid;
|
||||
mod globals;
|
||||
mod kirby;
|
||||
|
|
@ -24,19 +29,17 @@ mod sphere_collider;
|
|||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
||||
.add_plugins(CounterPlugin)
|
||||
.add_plugins(KirbyPlugin)
|
||||
.add_plugins(DensityGridPlugin)
|
||||
.add_plugins(BubblePlugin)
|
||||
.add_plugins(MyCameraPlugin)
|
||||
.insert_resource(Time::<Fixed>::from_seconds(1.0 / 60.0))
|
||||
.insert_resource(MapBounds { min: Vec2::ONE * -600.0, max: Vec2::ONE * 600.0 })
|
||||
.insert_resource(DensityGrid::new())
|
||||
.add_systems(Startup, spawn_camera)
|
||||
.add_systems(Startup, kirby_spawn)
|
||||
.add_systems(Startup, bubble_spawn)
|
||||
.add_systems(PostStartup, init_density_object)
|
||||
.add_systems(Update, animate_sprite)
|
||||
.add_systems(FixedUpdate, (density_grid_update, density_grid_force).chain())
|
||||
.add_systems(FixedUpdate, kirby_actions)
|
||||
.add_systems(FixedUpdate, bubble_move)
|
||||
.add_systems(FixedUpdate, bubble_receive_damage)
|
||||
.add_systems(FixedUpdate, kirby_receive_damage)
|
||||
.add_systems(FixedPostUpdate, despawn_if_dead)
|
||||
.add_systems(FixedPostUpdate, integrate)
|
||||
.add_systems(FixedPostUpdate, physics_integrate)
|
||||
.run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@ impl Default for PhysicsBody {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn integrate(bounds: Res<MapBounds>, mut query: Query<(&mut Transform, &mut PhysicsBody)>, time: Res<Time<Fixed>>) {
|
||||
pub fn physics_integrate(
|
||||
bounds: Res<MapBounds>,
|
||||
mut query: Query<(&mut Transform, &mut PhysicsBody)>,
|
||||
time: Res<Time<Fixed>>,
|
||||
) {
|
||||
for (mut transform, mut physicsbody) in &mut query {
|
||||
let force = physicsbody.force;
|
||||
let mass = physicsbody.mass;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue