~starkingdoms/starkingdoms

ref: 461d3d233fe9f2f94f9a1f1b9ccf9d1cdc9a9edb starkingdoms/crates/unified/src/particle_editor/spawn.rs -rw-r--r-- 2.8 KiB
461d3d23TerraMaster85 fix starfield alignment(?) 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::time::Duration;

use bevy::prelude::*;
use bevy_rapier2d::prelude::{RigidBody, Velocity};

use crate::{particle_editor::ecs::{CircleMesh, LifetimeTimer, ParentEffect, Particle, SpawnDelayTimer}, particles::ParticleEffect};

pub fn spawn_plugin(app: &mut App) {
    app.add_systems(Update, spawn_particles);
    app.add_systems(Update, lifetime_particles);
}

fn spawn_particles(
    mut commands: Commands,
    particle_effects: Query<(&Transform, &ParticleEffect, &mut SpawnDelayTimer)>,
    time: ResMut<Time>,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    for (transform, effect, mut delay_timer) in particle_effects {
        delay_timer.0.tick(time.delta());
        if delay_timer.0.just_finished() {
            for _ in 0..effect.particles_in_batch.sample(&mut rand::rng()) {
                let circle = CircleMesh(meshes.add(Circle::new(1.0)),
                    materials.add(effect.color.sample(effect.color.clamp_time(0.0).unwrap()).unwrap()));
                commands.spawn((
                    RigidBody::Dynamic,
                    Particle,
                    transform.with_scale(Vec3::splat(effect.scale.sample(effect.scale.clamp_time(0.0).unwrap()).unwrap())),
                    Mesh2d(circle.0.clone()),
                    MeshMaterial2d(circle.1.clone()),
                    Velocity {
                        linvel: effect.initial_linear_velocity.sample(&mut rand::rng()),
                        angvel: effect.initial_angular_velocity.sample(&mut rand::rng()),
                    },
                    LifetimeTimer(Timer::from_seconds(effect.lifetime_seconds.sample(&mut rand::rng()), TimerMode::Once)),
                    circle,
                    ParentEffect(effect.clone()),
                ));
            }
            delay_timer.0.set_duration(Duration::from_secs_f32(effect.batch_spawn_delay_seconds.sample(&mut rand::rng())));
            delay_timer.0.reset();
        }
    }
}

fn lifetime_particles(
    mut commands: Commands,
    mut particles: Query<(Entity, &mut LifetimeTimer, &mut Transform, &CircleMesh, &ParentEffect), With<Particle>>,
    time: ResMut<Time>,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    for (entity, mut timer, mut transform, circle, parent) in &mut particles {
        timer.0.tick(time.delta());
        transform.scale = Vec3::splat(parent.0.scale.sample(parent.0.scale.clamp_time(timer.0.elapsed_secs()).unwrap()).unwrap());
        materials.get_mut(&circle.1).unwrap().color = parent.0.color.sample(parent.0.color.clamp_time(timer.0.elapsed_secs()).unwrap()).unwrap();
        if timer.0.just_finished() {
            commands.entity(entity).despawn();
            meshes.remove(&circle.0);
            materials.remove(&circle.1);
        }
    }
}