Begin work on next part, creation
This commit is contained in:
parent
af2f3101af
commit
e7a6dd1293
1 changed files with 230 additions and 2 deletions
232
src/main.rs
232
src/main.rs
|
@ -22,6 +22,26 @@ const PARTICLE_RAND_ROT_RANGE: f32 = 0.5;
|
||||||
const JOINING_OPACITY_RATE: f32 = 0.00008;
|
const JOINING_OPACITY_RATE: f32 = 0.00008;
|
||||||
const JOINING_FAR_DIST: f32 = 700.0;
|
const JOINING_FAR_DIST: f32 = 700.0;
|
||||||
const JOINING_NEAR_DIST: f32 = 150.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 {
|
enum MenuItemType {
|
||||||
Button {
|
Button {
|
||||||
|
@ -426,6 +446,59 @@ impl Menu {
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 Particle {
|
||||||
|
@ -582,6 +655,100 @@ impl RotatingParticleSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
struct GameState {
|
||||||
s_boom: Asset<Sound>,
|
s_boom: Asset<Sound>,
|
||||||
s_get: Asset<Sound>,
|
s_get: Asset<Sound>,
|
||||||
|
@ -603,6 +770,11 @@ struct GameState {
|
||||||
player_r: f64,
|
player_r: f64,
|
||||||
player_particles: ParticleSystem,
|
player_particles: ParticleSystem,
|
||||||
joining_particles: RotatingParticleSystem,
|
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 {
|
impl State for GameState {
|
||||||
|
@ -645,12 +817,18 @@ impl State for GameState {
|
||||||
0.1,
|
0.1,
|
||||||
JOINING_FAR_DIST,
|
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<()> {
|
fn event(&mut self, event: &Event, window: &mut Window) -> Result<()> {
|
||||||
match event {
|
match event {
|
||||||
Event::MouseMoved(v) => {
|
Event::MouseMoved(v) => {
|
||||||
|
self.mouse_pos = *v;
|
||||||
let mut hovered = false;
|
let mut hovered = false;
|
||||||
for i in 0..self.menu.items.len() {
|
for i in 0..self.menu.items.len() {
|
||||||
if self.menu.items[i].is_inside(v.x, v.y) {
|
if self.menu.items[i].is_inside(v.x, v.y) {
|
||||||
|
@ -666,9 +844,25 @@ impl State for GameState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::MouseButton(button, state) => {
|
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.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 {
|
if let Some(idx) = self.current_item {
|
||||||
match self.state {
|
match self.state {
|
||||||
0 => {
|
0 => {
|
||||||
|
@ -712,6 +906,7 @@ impl State for GameState {
|
||||||
match self.state {
|
match self.state {
|
||||||
0 | 1 => self.state += 1,
|
0 | 1 => self.state += 1,
|
||||||
3 | 4 | 5 | 6 => self.state = 7,
|
3 | 4 | 5 | 6 => self.state = 7,
|
||||||
|
7 => self.state = 8,
|
||||||
_ => self.state = 0,
|
_ => self.state = 0,
|
||||||
}
|
}
|
||||||
self.state_dirty = true;
|
self.state_dirty = true;
|
||||||
|
@ -779,6 +974,7 @@ impl State for GameState {
|
||||||
fn update(&mut self, window: &mut Window) -> Result<()> {
|
fn update(&mut self, window: &mut Window) -> Result<()> {
|
||||||
let dt = window.update_rate();
|
let dt = window.update_rate();
|
||||||
|
|
||||||
|
self.click_release_time += dt;
|
||||||
self.player_r += dt / 10.0;
|
self.player_r += dt / 10.0;
|
||||||
|
|
||||||
if self.state_dirty {
|
if self.state_dirty {
|
||||||
|
@ -826,13 +1022,33 @@ impl State for GameState {
|
||||||
self.current_finished = false;
|
self.current_finished = false;
|
||||||
self.selection_mode = 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.menu = Menu::start();
|
||||||
self.current_item = None;
|
self.current_item = None;
|
||||||
self.selection_mode = true;
|
self.selection_mode = true;
|
||||||
|
self.is_create_mode = false;
|
||||||
self.state = 0;
|
self.state = 0;
|
||||||
self.player_particles.opacity = 0.0;
|
self.player_particles.opacity = 0.0;
|
||||||
self.joining_particles.particle_system.opacity = 0.0;
|
self.joining_particles.particle_system.opacity = 0.0;
|
||||||
|
self.expl_conv_p_systems.clear();
|
||||||
|
self.planets.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -961,6 +1177,12 @@ impl State for GameState {
|
||||||
self.player_particles.update(dt);
|
self.player_particles.update(dt);
|
||||||
self.joining_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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1037,6 +1259,12 @@ impl State for GameState {
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
self.joining_particles.draw(window, Transform::IDENTITY);
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue