Add objects from first choice
Add draw fn to ParticleSystem structs.
This commit is contained in:
parent
dec7627e37
commit
c3b50c8995
1 changed files with 153 additions and 33 deletions
186
src/main.rs
186
src/main.rs
|
@ -16,6 +16,12 @@ const HEIGHT_F: f32 = 600.0;
|
||||||
const MUSIC2_LENGTH: f64 = 2.0 * 60.0 * 1000.0;
|
const MUSIC2_LENGTH: f64 = 2.0 * 60.0 * 1000.0;
|
||||||
const TEXT_RATE: f64 = 100.0;
|
const TEXT_RATE: f64 = 100.0;
|
||||||
const PP_GEN_RATE: f64 = 75.0;
|
const PP_GEN_RATE: f64 = 75.0;
|
||||||
|
const PARTICLE_RAND_VEL_RANGE: f32 = 0.2;
|
||||||
|
const PARTICLE_RAND_VEL_DIST: f32 = 0.2828427; // dist where x and y = 0.2
|
||||||
|
const PARTICLE_RAND_ROT_RANGE: f32 = 0.5;
|
||||||
|
const JOINING_OPACITY_RATE: f32 = 0.00008;
|
||||||
|
const JOINING_FAR_DIST: f32 = 700.0;
|
||||||
|
const JOINING_NEAR_DIST: f32 = 150.0;
|
||||||
|
|
||||||
enum MenuItemType {
|
enum MenuItemType {
|
||||||
Button {
|
Button {
|
||||||
|
@ -117,13 +123,7 @@ impl Menu {
|
||||||
Menu {
|
Menu {
|
||||||
items: vec![
|
items: vec![
|
||||||
item,
|
item,
|
||||||
Menu::instant_text(
|
Menu::instant_text(150.0, 50.0, 55.0, true, "One And All"),
|
||||||
150.0,
|
|
||||||
50.0,
|
|
||||||
45.0,
|
|
||||||
true,
|
|
||||||
"One And All",
|
|
||||||
),
|
|
||||||
Menu::instant_text(
|
Menu::instant_text(
|
||||||
25.0,
|
25.0,
|
||||||
HEIGHT_F - 100.0,
|
HEIGHT_F - 100.0,
|
||||||
|
@ -445,10 +445,19 @@ struct ParticleSystem {
|
||||||
lifetime: f64,
|
lifetime: f64,
|
||||||
host_rect: Rectangle,
|
host_rect: Rectangle,
|
||||||
direction: Vector,
|
direction: Vector,
|
||||||
|
color: Color,
|
||||||
|
opacity: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParticleSystem {
|
impl ParticleSystem {
|
||||||
fn new(spawn_time: f64, lifetime: f64, host_rect: Rectangle, direction: Vector) -> Self {
|
fn new(
|
||||||
|
spawn_time: f64,
|
||||||
|
lifetime: f64,
|
||||||
|
host_rect: Rectangle,
|
||||||
|
direction: Vector,
|
||||||
|
color: Color,
|
||||||
|
opacity: f32,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
particles: Vec::new(),
|
particles: Vec::new(),
|
||||||
spawn_timer: 0.0,
|
spawn_timer: 0.0,
|
||||||
|
@ -456,6 +465,8 @@ impl ParticleSystem {
|
||||||
lifetime,
|
lifetime,
|
||||||
host_rect,
|
host_rect,
|
||||||
direction,
|
direction,
|
||||||
|
color,
|
||||||
|
opacity,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,15 +487,99 @@ impl ParticleSystem {
|
||||||
self.spawn_timer -= self.spawn_time;
|
self.spawn_timer -= self.spawn_time;
|
||||||
self.particles.push(Particle {
|
self.particles.push(Particle {
|
||||||
rect: self.host_rect,
|
rect: self.host_rect,
|
||||||
velx: rand::thread_rng().gen_range(-0.2, 0.2) + self.direction.x,
|
velx: rand::thread_rng()
|
||||||
vely: rand::thread_rng().gen_range(-0.2, 0.2) + self.direction.y,
|
.gen_range(-PARTICLE_RAND_VEL_RANGE, PARTICLE_RAND_VEL_RANGE)
|
||||||
velr: rand::thread_rng().gen_range(-0.5, 0.5),
|
+ self.direction.x,
|
||||||
|
vely: rand::thread_rng()
|
||||||
|
.gen_range(-PARTICLE_RAND_VEL_RANGE, PARTICLE_RAND_VEL_RANGE)
|
||||||
|
+ self.direction.y,
|
||||||
|
// velx: self.direction.x,
|
||||||
|
// vely: self.direction.y,
|
||||||
|
velr: rand::thread_rng()
|
||||||
|
.gen_range(-PARTICLE_RAND_ROT_RANGE, PARTICLE_RAND_ROT_RANGE),
|
||||||
r: rand::thread_rng().gen_range(0.0, 90.0),
|
r: rand::thread_rng().gen_range(0.0, 90.0),
|
||||||
lifetime: self.lifetime,
|
lifetime: self.lifetime,
|
||||||
life_timer: 0.0,
|
life_timer: 0.0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw(&mut self, window: &mut Window, transform: Transform) {
|
||||||
|
if self.opacity == 0.0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for particle in &mut self.particles {
|
||||||
|
self.color.a = (1.0 - (particle.life_timer / particle.lifetime) as f32) * self.opacity;
|
||||||
|
let pre_transform =
|
||||||
|
Transform::translate((-particle.rect.size.x / 2.0, -particle.rect.size.y / 2.0))
|
||||||
|
* Transform::rotate(particle.r);
|
||||||
|
window.draw_ex(
|
||||||
|
&particle.rect,
|
||||||
|
Col(self.color),
|
||||||
|
transform * pre_transform,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RotatingParticleSystem {
|
||||||
|
particle_system: ParticleSystem,
|
||||||
|
r: f32,
|
||||||
|
velr: f32,
|
||||||
|
offset: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RotatingParticleSystem {
|
||||||
|
fn new(
|
||||||
|
spawn_time: f64,
|
||||||
|
lifetime: f64,
|
||||||
|
host_rect: Rectangle,
|
||||||
|
direction: Vector,
|
||||||
|
color: Color,
|
||||||
|
opacity: f32,
|
||||||
|
rotation: f32,
|
||||||
|
velr: f32,
|
||||||
|
offset: f32,
|
||||||
|
) -> Self {
|
||||||
|
RotatingParticleSystem {
|
||||||
|
particle_system: ParticleSystem::new(
|
||||||
|
spawn_time, lifetime, host_rect, direction, color, opacity,
|
||||||
|
),
|
||||||
|
r: rotation,
|
||||||
|
velr,
|
||||||
|
offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, dt: f64) {
|
||||||
|
let saved_rect = self.particle_system.host_rect;
|
||||||
|
self.particle_system.host_rect.pos +=
|
||||||
|
Transform::rotate(self.r) * Vector::new(self.offset, 0.0);
|
||||||
|
self.particle_system.update(dt);
|
||||||
|
self.particle_system.host_rect = saved_rect;
|
||||||
|
self.r += self.velr * dt as f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&mut self, window: &mut Window, transform: Transform) {
|
||||||
|
if self.particle_system.opacity == 0.0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.particle_system.direction =
|
||||||
|
Transform::rotate(self.r) * Vector::new(0.0, -PARTICLE_RAND_VEL_DIST);
|
||||||
|
self.particle_system.draw(window, transform);
|
||||||
|
let mut moved_rect = self.particle_system.host_rect;
|
||||||
|
moved_rect.pos += Transform::rotate(self.r) * Vector::new(self.offset, 0.0);
|
||||||
|
let mut solid_color = self.particle_system.color;
|
||||||
|
solid_color.a = self.particle_system.opacity;
|
||||||
|
window.draw_ex(
|
||||||
|
&moved_rect,
|
||||||
|
Col(solid_color),
|
||||||
|
Transform::translate((-moved_rect.size.x / 2.0, -moved_rect.size.y / 2.0))
|
||||||
|
* Transform::rotate(self.r * 1.3),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GameState {
|
struct GameState {
|
||||||
|
@ -507,7 +602,7 @@ struct GameState {
|
||||||
player: Rectangle,
|
player: Rectangle,
|
||||||
player_r: f64,
|
player_r: f64,
|
||||||
player_particles: ParticleSystem,
|
player_particles: ParticleSystem,
|
||||||
player_opacity: f32,
|
joining_particles: RotatingParticleSystem,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State for GameState {
|
impl State for GameState {
|
||||||
|
@ -536,8 +631,20 @@ impl State for GameState {
|
||||||
1000.0,
|
1000.0,
|
||||||
Rectangle::new((400.0, 300.0), (32.0, 32.0)),
|
Rectangle::new((400.0, 300.0), (32.0, 32.0)),
|
||||||
Vector::new(0.0, 0.0),
|
Vector::new(0.0, 0.0),
|
||||||
|
Color::WHITE,
|
||||||
|
0.0,
|
||||||
|
),
|
||||||
|
joining_particles: RotatingParticleSystem::new(
|
||||||
|
PP_GEN_RATE,
|
||||||
|
1000.0,
|
||||||
|
Rectangle::new((400.0, 300.0), (16.0, 16.0)),
|
||||||
|
Vector::new(0.0, 0.0),
|
||||||
|
Color::GREEN,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.1,
|
||||||
|
JOINING_FAR_DIST,
|
||||||
),
|
),
|
||||||
player_opacity: 0.0,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,18 +680,26 @@ impl State for GameState {
|
||||||
// hope
|
// hope
|
||||||
self.state = 3;
|
self.state = 3;
|
||||||
self.state_dirty = true;
|
self.state_dirty = true;
|
||||||
|
self.joining_particles.particle_system.color =
|
||||||
|
Color::from_rgba(0xAA, 0xCC, 0xFF, 1.0);
|
||||||
} else if idx == 6 {
|
} else if idx == 6 {
|
||||||
// miracles
|
// miracles
|
||||||
self.state = 4;
|
self.state = 4;
|
||||||
self.state_dirty = true;
|
self.state_dirty = true;
|
||||||
|
self.joining_particles.particle_system.color =
|
||||||
|
Color::from_rgba(0xFF, 0xFF, 0xAA, 1.0);
|
||||||
} else if idx == 7 {
|
} else if idx == 7 {
|
||||||
// kindness
|
// kindness
|
||||||
self.state = 5;
|
self.state = 5;
|
||||||
self.state_dirty = true;
|
self.state_dirty = true;
|
||||||
|
self.joining_particles.particle_system.color =
|
||||||
|
Color::from_rgba(0xBB, 0xFF, 0xBB, 1.0);
|
||||||
} else {
|
} else {
|
||||||
// determination
|
// determination
|
||||||
self.state = 6;
|
self.state = 6;
|
||||||
self.state_dirty = true;
|
self.state_dirty = true;
|
||||||
|
self.joining_particles.particle_system.color =
|
||||||
|
Color::from_rgba(0xFF, 0xAA, 0xAA, 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -716,15 +831,26 @@ impl State for GameState {
|
||||||
self.current_item = None;
|
self.current_item = None;
|
||||||
self.selection_mode = true;
|
self.selection_mode = true;
|
||||||
self.state = 0;
|
self.state = 0;
|
||||||
self.player_opacity = 0.0;
|
self.player_particles.opacity = 0.0;
|
||||||
|
self.joining_particles.particle_system.opacity = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.player_opacity < 1.0 && self.state > 1 {
|
if self.joining_particles.particle_system.opacity < 1.0 && self.state > 2 {
|
||||||
self.player_opacity += dt as f32 / 7000.0;
|
self.joining_particles.particle_system.opacity += JOINING_OPACITY_RATE * dt as f32;
|
||||||
if self.player_opacity > 1.0 {
|
if self.joining_particles.particle_system.opacity > 1.0 {
|
||||||
self.player_opacity = 1.0;
|
self.joining_particles.particle_system.opacity = 1.0;
|
||||||
|
}
|
||||||
|
self.joining_particles.offset =
|
||||||
|
(1.0 - self.joining_particles.particle_system.opacity / 1.0) * JOINING_FAR_DIST
|
||||||
|
+ self.joining_particles.particle_system.opacity / 1.0 * JOINING_NEAR_DIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.player_particles.opacity < 1.0 && self.state > 1 {
|
||||||
|
self.player_particles.opacity += dt as f32 / 7000.0;
|
||||||
|
if self.player_particles.opacity > 1.0 {
|
||||||
|
self.player_particles.opacity = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,6 +957,7 @@ impl State for GameState {
|
||||||
|
|
||||||
self.player_particles.host_rect = self.player;
|
self.player_particles.host_rect = self.player;
|
||||||
self.player_particles.update(dt);
|
self.player_particles.update(dt);
|
||||||
|
self.joining_particles.update(dt);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -894,27 +1021,20 @@ impl State for GameState {
|
||||||
MenuItemType::Pause { timer, length } => (),
|
MenuItemType::Pause { timer, length } => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for particle in &self.player_particles.particles {
|
self.player_particles.draw(window, Transform::IDENTITY);
|
||||||
window.draw_ex(
|
|
||||||
&particle.rect,
|
|
||||||
Col(Color::from_rgba(
|
|
||||||
0xFF,
|
|
||||||
0xFF,
|
|
||||||
0xFF,
|
|
||||||
(1.0 - (particle.life_timer / particle.lifetime) as f32) * self.player_opacity,
|
|
||||||
)),
|
|
||||||
Transform::translate((-particle.rect.size.x / 2.0, -particle.rect.size.y / 2.0))
|
|
||||||
* Transform::rotate(particle.r),
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
window.draw_ex(
|
window.draw_ex(
|
||||||
&self.player,
|
&self.player,
|
||||||
Col(Color::from_rgba(0xFF, 0xFF, 0xFF, self.player_opacity)),
|
Col(Color::from_rgba(
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
self.player_particles.opacity,
|
||||||
|
)),
|
||||||
Transform::translate((-self.player.size.x / 2.0, -self.player.size.y / 2.0))
|
Transform::translate((-self.player.size.x / 2.0, -self.player.size.y / 2.0))
|
||||||
* Transform::rotate(self.player_r as f32),
|
* Transform::rotate(self.player_r as f32),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
self.joining_particles.draw(window, Transform::IDENTITY);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue