const JOINING_OPACITY_RATE: f32 = 0.00008;
const JOINING_FAR_DIST: f32 = 700.0;
const JOINING_NEAR_DIST: f32 = 150.0;
+const DOUBLE_CLICK_TIME: f64 = 350.0;
+
+fn interp_sq_inv(x: f32) -> f32 {
+ if x < 0.0 {
+ return 0.0
+ } else if x > 1.0 {
+ return 1.0
+ }
+ let y = x - 1.0;
+ -y * y + 1.0
+}
+
+fn interp_sq(x: f32) -> f32 {
+ if x < 0.0 {
+ return 0.0
+ } else if x > 1.0 {
+ return 1.0
+ }
+ x * x
+}
enum MenuItemType {
Button {
],
}
}
+
+ fn s_07() -> Menu {
+ Menu {
+ items: vec![
+ Menu::text(
+ 50.0,
+ HEIGHT_F - 130.0,
+ 40.0,
+ true,
+ "Now that you are here, it must mean a new time of",
+ ),
+ Menu::text(
+ 50.0,
+ HEIGHT_F - 90.0,
+ 40.0,
+ false,
+ "creation for the world.",
+ ),
+ Menu::pause(200.0, false),
+ Menu::text(
+ 50.0,
+ HEIGHT_F - 50.0,
+ 40.0,
+ false,
+ "Try double-clicking the void to create something...",
+ ),
+ ],
+ }
+ }
+
+ fn s_08() -> Menu {
+ Menu {
+ items: vec![
+ Menu::instant_text(
+ 50.0,
+ HEIGHT_F - 90.0,
+ 35.0,
+ true,
+ "(Try double-clicking now...)",
+ ),
+ ],
+ }
+ }
+
+ fn s_09() -> Menu {
+ Menu {
+ items: vec![
+ Menu::pause(400.0, true),
+ Menu::text(50.0, HEIGHT_F - 140.0, 40.0, false,
+ "A new planet... It has most certainly been a while."),
+ ]
+ }
+ }
}
struct Particle {
}
}
+struct ExplConvCircleParticle {
+ circle: Circle,
+ offset: f32,
+ r: f32,
+}
+
+struct ExplConvParticleSystem {
+ particles: Vec<ExplConvCircleParticle>,
+ lifetime: f64,
+ host_circle: Circle,
+ color: Color,
+ opacity: f32,
+ life_timer: f64,
+}
+
+impl ExplConvParticleSystem {
+ fn new(
+ lifetime: f64,
+ host_circle: Circle,
+ color: Color,
+ opacity: f32,
+ ) -> Self {
+ ExplConvParticleSystem {
+ particles: Vec::new(),
+ lifetime,
+ host_circle,
+ color,
+ opacity,
+ life_timer: 0.0,
+ }
+ }
+
+ fn activate(&mut self, count: usize, offset: f32) {
+ self.life_timer = 0.0;
+ for i in 0..count {
+ self.particles.push(ExplConvCircleParticle {
+ circle: self.host_circle,
+ offset,
+ r: rand::thread_rng().gen_range(0.0, 360.0),
+ });
+ }
+ }
+
+ // returns true if finished
+ fn update(&mut self, dt: f64, planets: &mut Vec<Planet>) -> bool {
+ self.life_timer += dt;
+ if self.life_timer >= self.lifetime {
+ if !self.particles.is_empty() {
+ self.particles.clear();
+ planets.push(Planet{ circle: self.host_circle, color: self.color, });
+ return true;
+ }
+ return false;
+ }
+
+ if self.life_timer < self.lifetime / 2.0 {
+ let amount = interp_sq_inv((self.life_timer / self.lifetime) as f32 * 2.0);
+ for particle in &mut self.particles {
+ let dir = Transform::rotate(particle.r) * Vector::new(
+ particle.offset * amount, 0.0);
+ particle.circle.pos = dir + self.host_circle.pos;
+ }
+ } else {
+ let amount = 1.0 - interp_sq(((self.life_timer / self.lifetime) as f32 - 0.5) * 2.0);
+ for particle in &mut self.particles {
+ let dir = Transform::rotate(particle.r) * Vector::new(
+ particle.offset * amount, 0.0);
+ particle.circle.pos = dir + self.host_circle.pos;
+ }
+ }
+ return false;
+ }
+
+ fn draw(&mut self, window: &mut Window, transform: Transform) {
+ if self.opacity == 0.0 {
+ return;
+ }
+ for particle in &mut self.particles {
+ self.color.a = ((self.life_timer / self.lifetime) as f32 / 2.0 + 0.5) * self.opacity;
+ window.draw_ex(
+ &particle.circle,
+ Col(self.color),
+ transform,
+ 1,
+ );
+ }
+ }
+}
+
+struct Planet {
+ circle: Circle,
+ color: Color,
+}
+
struct GameState {
s_boom: Asset<Sound>,
s_get: Asset<Sound>,
player_r: f64,
player_particles: ParticleSystem,
joining_particles: RotatingParticleSystem,
+ is_create_mode: bool,
+ click_release_time: f64,
+ mouse_pos: Vector,
+ expl_conv_p_systems: Vec<ExplConvParticleSystem>,
+ planets: Vec<Planet>,
}
impl State for GameState {
0.1,
JOINING_FAR_DIST,
),
+ is_create_mode: false,
+ click_release_time: 0.0,
+ mouse_pos: Vector::new(0.0, 0.0),
+ expl_conv_p_systems: Vec::new(),
+ planets: Vec::new(),
})
}
fn event(&mut self, event: &Event, window: &mut Window) -> Result<()> {
match event {
Event::MouseMoved(v) => {
+ self.mouse_pos = *v;
let mut hovered = false;
for i in 0..self.menu.items.len() {
if self.menu.items[i].is_inside(v.x, v.y) {
}
}
Event::MouseButton(button, state) => {
- if let ButtonState::Pressed = state {
+ if let ButtonState::Released = state {
+ self.click_release_time = 0.0;
+ } else if let ButtonState::Pressed = state {
if self.current_finished {
- if self.selection_mode {
+ if self.is_create_mode {
+ if self.click_release_time < DOUBLE_CLICK_TIME {
+ if self.state == 8 {
+ let mut expl_conv_system = ExplConvParticleSystem::new(
+ 1500.0, Circle::new(self.mouse_pos, 20.0),
+ Color::GREEN, 1.0,
+ );
+ expl_conv_system.activate(30, 200.0);
+ self.expl_conv_p_systems.push(expl_conv_system);
+ self.state = 9;
+ self.state_dirty = true;
+ }
+ }
+ }
+ else if self.selection_mode {
if let Some(idx) = self.current_item {
match self.state {
0 => {
match self.state {
0 | 1 => self.state += 1,
3 | 4 | 5 | 6 => self.state = 7,
+ 7 => self.state = 8,
_ => self.state = 0,
}
self.state_dirty = true;
fn update(&mut self, window: &mut Window) -> Result<()> {
let dt = window.update_rate();
+ self.click_release_time += dt;
self.player_r += dt / 10.0;
if self.state_dirty {
self.current_finished = false;
self.selection_mode = false;
}
+ 7 => {
+ self.menu = Menu::s_07();
+ self.current_finished = false;
+ self.selection_mode = false;
+ }
+ 8 => {
+ self.menu = Menu::s_08();
+ self.current_finished = true;
+ self.selection_mode = false;
+ self.is_create_mode = true;
+ }
+ 9 => {
+ self.menu = Menu::s_09();
+ self.current_finished = false;
+ self.selection_mode = false;
+ self.is_create_mode = false;
+ }
_ => {
self.menu = Menu::start();
self.current_item = None;
self.selection_mode = true;
+ self.is_create_mode = false;
self.state = 0;
self.player_particles.opacity = 0.0;
self.joining_particles.particle_system.opacity = 0.0;
+ self.expl_conv_p_systems.clear();
+ self.planets.clear();
}
}
}
self.player_particles.update(dt);
self.joining_particles.update(dt);
+ for i in (0..self.expl_conv_p_systems.len()).rev() {
+ if self.expl_conv_p_systems[i].update(dt, &mut self.planets) {
+ self.expl_conv_p_systems.swap_remove(i);
+ }
+ }
+
Ok(())
}
1,
);
self.joining_particles.draw(window, Transform::IDENTITY);
+ for expl_conv_ps in &mut self.expl_conv_p_systems {
+ expl_conv_ps.draw(window, Transform::IDENTITY);
+ }
+ for planet in &mut self.planets {
+ window.draw(&planet.circle, Col(planet.color));
+ }
Ok(())
}
}