Added music2, some work on start of game
This commit is contained in:
parent
9d3fc59354
commit
9a9bc083f5
2 changed files with 276 additions and 19 deletions
295
src/main.rs
295
src/main.rs
|
@ -1,6 +1,9 @@
|
||||||
use quicksilver::{
|
use quicksilver::{
|
||||||
geom::{Circle, Rectangle, Vector},
|
geom::{Circle, Rectangle, Vector},
|
||||||
graphics::{Background::{Col, Img}, Color, Font, FontStyle, Image},
|
graphics::{
|
||||||
|
Background::{Col, Img},
|
||||||
|
Color, Font, FontStyle, Image,
|
||||||
|
},
|
||||||
input::{ButtonState, Key},
|
input::{ButtonState, Key},
|
||||||
lifecycle::{run, Asset, Event, Settings, State, Window},
|
lifecycle::{run, Asset, Event, Settings, State, Window},
|
||||||
sound::Sound,
|
sound::Sound,
|
||||||
|
@ -9,7 +12,9 @@ use quicksilver::{
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
const WIDTH_F: f32 = 800.0;
|
const WIDTH_F: f32 = 800.0;
|
||||||
const WIDTH_H: f32 = 600.0;
|
const HEIGHT_F: f32 = 600.0;
|
||||||
|
const MUSIC2_LENGTH: f64 = 2.0 * 60.0 * 1000.0;
|
||||||
|
const TEXT_RATE: f64 = 100.0;
|
||||||
|
|
||||||
enum MenuItemType {
|
enum MenuItemType {
|
||||||
Button {
|
Button {
|
||||||
|
@ -19,6 +24,18 @@ enum MenuItemType {
|
||||||
h_c: Color,
|
h_c: Color,
|
||||||
c: Color,
|
c: Color,
|
||||||
},
|
},
|
||||||
|
AppearingText {
|
||||||
|
text: &'static str,
|
||||||
|
text_image: Option<Image>,
|
||||||
|
current_text: String,
|
||||||
|
text_size: f32,
|
||||||
|
text_c: Color,
|
||||||
|
timer: f64,
|
||||||
|
},
|
||||||
|
Pause {
|
||||||
|
timer: f64,
|
||||||
|
length: f64,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MenuItem {
|
struct MenuItem {
|
||||||
|
@ -67,6 +84,66 @@ impl Menu {
|
||||||
|
|
||||||
Menu { items: vec![item] }
|
Menu { items: vec![item] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn text(x: f32, y: f32, text_size: f32, first: bool, s: &'static str) -> MenuItem {
|
||||||
|
MenuItem {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
w: 0.0,
|
||||||
|
h: 0.0,
|
||||||
|
item_type: MenuItemType::AppearingText {
|
||||||
|
text: s,
|
||||||
|
text_image: None,
|
||||||
|
text_size,
|
||||||
|
current_text: String::new(),
|
||||||
|
text_c: Color::WHITE,
|
||||||
|
timer: 0.0,
|
||||||
|
},
|
||||||
|
is_hover: false,
|
||||||
|
is_focus: false,
|
||||||
|
is_loaded: !first,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pause(length: f64, first: bool) -> MenuItem {
|
||||||
|
MenuItem {
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
|
w: 0.0,
|
||||||
|
h: 0.0,
|
||||||
|
item_type: MenuItemType::Pause { timer: 0.0, length },
|
||||||
|
is_hover: false,
|
||||||
|
is_focus: false,
|
||||||
|
is_loaded: !first,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn s_01() -> Menu {
|
||||||
|
Menu {
|
||||||
|
items: vec![
|
||||||
|
Menu::pause(500.0, true),
|
||||||
|
Menu::text(50.0, HEIGHT_F - 140.0, 40.0, false, "This is how it is."),
|
||||||
|
Menu::pause(500.0, false),
|
||||||
|
Menu::text(
|
||||||
|
50.0,
|
||||||
|
HEIGHT_F - 100.0,
|
||||||
|
40.0,
|
||||||
|
false,
|
||||||
|
"Nothing is, and everything is nothing.",
|
||||||
|
),
|
||||||
|
Menu::pause(500.0, false),
|
||||||
|
Menu::text(50.0, HEIGHT_F - 60.0, 40.0, false, "...until you appeared."),
|
||||||
|
Menu::pause(100.0, false),
|
||||||
|
Menu::text(
|
||||||
|
570.0,
|
||||||
|
HEIGHT_F - 50.0,
|
||||||
|
30.0,
|
||||||
|
false,
|
||||||
|
"(Click to continue...)",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GameState {
|
struct GameState {
|
||||||
|
@ -77,8 +154,15 @@ struct GameState {
|
||||||
s_speak_m: Asset<Sound>,
|
s_speak_m: Asset<Sound>,
|
||||||
s_speak_f: Asset<Sound>,
|
s_speak_f: Asset<Sound>,
|
||||||
font: Asset<Font>,
|
font: Asset<Font>,
|
||||||
timer: f64,
|
music2: Asset<Sound>,
|
||||||
|
music_on: bool,
|
||||||
|
music_timer: f64,
|
||||||
menu: Menu,
|
menu: Menu,
|
||||||
|
state: u32,
|
||||||
|
state_dirty: bool,
|
||||||
|
selection_mode: bool,
|
||||||
|
current_item: Option<usize>,
|
||||||
|
current_finished: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State for GameState {
|
impl State for GameState {
|
||||||
|
@ -91,21 +175,93 @@ impl State for GameState {
|
||||||
s_speak_m: Asset::new(Sound::load("speak_m.mp3")),
|
s_speak_m: Asset::new(Sound::load("speak_m.mp3")),
|
||||||
s_speak_f: Asset::new(Sound::load("speak_f.mp3")),
|
s_speak_f: Asset::new(Sound::load("speak_f.mp3")),
|
||||||
font: Asset::new(Font::load("ClearSans-Regular.ttf")),
|
font: Asset::new(Font::load("ClearSans-Regular.ttf")),
|
||||||
timer: 0.0,
|
music2: Asset::new(Sound::load("music2.mp3")),
|
||||||
|
music_on: false,
|
||||||
|
music_timer: 0.0,
|
||||||
menu: Menu::start(),
|
menu: Menu::start(),
|
||||||
|
state: 0,
|
||||||
|
state_dirty: false,
|
||||||
|
selection_mode: true,
|
||||||
|
current_item: None,
|
||||||
|
current_finished: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
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) => {
|
||||||
for mi in &mut self.menu.items {
|
let mut hovered = false;
|
||||||
if mi.is_inside(v.x, v.y) {
|
for i in 0..self.menu.items.len() {
|
||||||
mi.is_hover = true;
|
if self.menu.items[i].is_inside(v.x, v.y) {
|
||||||
|
self.menu.items[i].is_hover = true;
|
||||||
|
self.current_item = Some(i);
|
||||||
|
hovered = true;
|
||||||
} else {
|
} else {
|
||||||
mi.is_hover = false;
|
self.menu.items[i].is_hover = false;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
if !hovered {
|
||||||
|
self.current_item = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::MouseButton(button, state) => {
|
||||||
|
if let ButtonState::Pressed = state {
|
||||||
|
if self.current_finished {
|
||||||
|
if self.selection_mode {
|
||||||
|
if let Some(idx) = self.current_item {
|
||||||
|
match self.state {
|
||||||
|
0 => {
|
||||||
|
self.state += 1;
|
||||||
|
self.state_dirty = true;
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.state += 1;
|
||||||
|
self.state_dirty = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for mi in &mut self.menu.items {
|
||||||
|
match &mut mi.item_type {
|
||||||
|
MenuItemType::AppearingText {
|
||||||
|
text,
|
||||||
|
text_image,
|
||||||
|
current_text,
|
||||||
|
text_size,
|
||||||
|
text_c,
|
||||||
|
timer,
|
||||||
|
} => {
|
||||||
|
self.font.execute(|f| {
|
||||||
|
*current_text = text.to_string();
|
||||||
|
let style = FontStyle::new(*text_size, *text_c);
|
||||||
|
*text_image = Some(f.render(text, &style)?);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
MenuItemType::Button {
|
||||||
|
text,
|
||||||
|
text_image,
|
||||||
|
text_c,
|
||||||
|
h_c,
|
||||||
|
c,
|
||||||
|
} => {
|
||||||
|
if text_image.is_none() {
|
||||||
|
self.font.execute(|font| {
|
||||||
|
let style = FontStyle::new(42.0, *text_c);
|
||||||
|
*text_image = Some(font.render(text, &style)?);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItemType::Pause { timer, length } => (),
|
||||||
|
}
|
||||||
|
mi.is_loaded = true;
|
||||||
|
}
|
||||||
|
self.current_finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -113,19 +269,100 @@ 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.timer += dt;
|
|
||||||
for mi in &mut self.menu.items {
|
if self.state_dirty {
|
||||||
|
self.state_dirty = false;
|
||||||
|
match self.state {
|
||||||
|
1 => {
|
||||||
|
self.menu = Menu::s_01();
|
||||||
|
self.current_finished = false;
|
||||||
|
self.selection_mode = false;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.menu = Menu::start();
|
||||||
|
self.current_item = None;
|
||||||
|
self.selection_mode = true;
|
||||||
|
self.state = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.music_on {
|
||||||
|
self.music_timer += dt;
|
||||||
|
if self.music_timer > MUSIC2_LENGTH {
|
||||||
|
self.music_timer = 0.0;
|
||||||
|
self.music2.execute(|m2| m2.play())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in 0..self.menu.items.len() {
|
||||||
|
let mi: &mut MenuItem = &mut self.menu.items[i];
|
||||||
if !mi.is_loaded {
|
if !mi.is_loaded {
|
||||||
match &mut mi.item_type {
|
match &mut mi.item_type {
|
||||||
MenuItemType::Button { text, text_image, text_c, h_c, c } => {
|
MenuItemType::Button {
|
||||||
|
text,
|
||||||
|
text_image,
|
||||||
|
text_c,
|
||||||
|
h_c,
|
||||||
|
c,
|
||||||
|
} => {
|
||||||
self.font.execute(|font| {
|
self.font.execute(|font| {
|
||||||
let style = FontStyle::new(42.0, *text_c);
|
let style = FontStyle::new(42.0, *text_c);
|
||||||
*text_image = Some(font.render(text, &style)?);
|
*text_image = Some(font.render(text, &style)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
mi.is_loaded = true;
|
||||||
|
if i + 1 < self.menu.items.len() {
|
||||||
|
self.menu.items[i + 1].is_loaded = false;
|
||||||
|
} else {
|
||||||
|
self.current_finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItemType::AppearingText {
|
||||||
|
text,
|
||||||
|
text_image,
|
||||||
|
current_text,
|
||||||
|
text_size,
|
||||||
|
text_c,
|
||||||
|
timer,
|
||||||
|
} => {
|
||||||
|
*timer += dt;
|
||||||
|
if *timer > TEXT_RATE {
|
||||||
|
*timer -= TEXT_RATE;
|
||||||
|
let next = text.chars().nth(current_text.len());
|
||||||
|
if let Some(next_t) = next {
|
||||||
|
current_text.push(next_t);
|
||||||
|
self.s_speak_f.execute(|s| {
|
||||||
|
s.set_volume(0.3);
|
||||||
|
s.play()
|
||||||
|
})?;
|
||||||
|
} else {
|
||||||
|
mi.is_loaded = true;
|
||||||
|
if i + 1 < self.menu.items.len() {
|
||||||
|
self.menu.items[i + 1].is_loaded = false;
|
||||||
|
} else {
|
||||||
|
self.current_finished = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
self.font.execute(|font| {
|
||||||
|
let style = FontStyle::new(*text_size, *text_c);
|
||||||
|
*text_image = Some(font.render(current_text, &style)?);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItemType::Pause { timer, length } => {
|
||||||
|
*timer += dt;
|
||||||
|
if timer > length {
|
||||||
|
mi.is_loaded = true;
|
||||||
|
if i + 1 < self.menu.items.len() {
|
||||||
|
self.menu.items[i + 1].is_loaded = false;
|
||||||
|
} else {
|
||||||
|
self.current_finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mi.is_loaded = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -140,7 +377,13 @@ impl State for GameState {
|
||||||
rect.size.x = mi.w;
|
rect.size.x = mi.w;
|
||||||
rect.size.y = mi.h;
|
rect.size.y = mi.h;
|
||||||
match &mut mi.item_type {
|
match &mut mi.item_type {
|
||||||
MenuItemType::Button{ text, text_image, text_c, h_c, c } => {
|
MenuItemType::Button {
|
||||||
|
text,
|
||||||
|
text_image,
|
||||||
|
text_c,
|
||||||
|
h_c,
|
||||||
|
c,
|
||||||
|
} => {
|
||||||
if mi.is_hover {
|
if mi.is_hover {
|
||||||
window.draw(&rect, Col(*h_c));
|
window.draw(&rect, Col(*h_c));
|
||||||
} else {
|
} else {
|
||||||
|
@ -150,11 +393,25 @@ impl State for GameState {
|
||||||
let mut image_rect = i.area();
|
let mut image_rect = i.area();
|
||||||
image_rect.pos.x = mi.x + (mi.w - image_rect.size.x) / 2.0;
|
image_rect.pos.x = mi.x + (mi.w - image_rect.size.x) / 2.0;
|
||||||
image_rect.pos.y = mi.y + (mi.h - image_rect.size.y) / 2.0;
|
image_rect.pos.y = mi.y + (mi.h - image_rect.size.y) / 2.0;
|
||||||
window.draw(
|
window.draw(&image_rect, Img(i));
|
||||||
&image_rect,
|
|
||||||
Img(i));
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
MenuItemType::AppearingText {
|
||||||
|
text,
|
||||||
|
text_image,
|
||||||
|
current_text,
|
||||||
|
text_size,
|
||||||
|
text_c,
|
||||||
|
timer,
|
||||||
|
} => {
|
||||||
|
if let Some(i) = text_image {
|
||||||
|
let mut image_rect = i.area();
|
||||||
|
image_rect.pos.x = mi.x;
|
||||||
|
image_rect.pos.y = mi.y;
|
||||||
|
window.draw(&image_rect, Img(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItemType::Pause { timer, length } => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
BIN
static/music2.mp3
Normal file
BIN
static/music2.mp3
Normal file
Binary file not shown.
Loading…
Reference in a new issue