]> git.seodisparate.com - LudumDare45_StartWithNothing/commitdiff
Added music2, some work on start of game
authorStephen Seo <seo.disparate@gmail.com>
Sat, 5 Oct 2019 05:17:14 +0000 (14:17 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sat, 5 Oct 2019 05:17:14 +0000 (14:17 +0900)
src/main.rs
static/music2.mp3 [new file with mode: 0644]

index 560317275ff7a9f798113d9dde579ca6f0c739b5..80c572f021461122e9f839318027755d1dd71433 100644 (file)
@@ -1,6 +1,9 @@
 use quicksilver::{
     geom::{Circle, Rectangle, Vector},
-    graphics::{Background::{Col, Img}, Color, Font, FontStyle, Image},
+    graphics::{
+        Background::{Col, Img},
+        Color, Font, FontStyle, Image,
+    },
     input::{ButtonState, Key},
     lifecycle::{run, Asset, Event, Settings, State, Window},
     sound::Sound,
@@ -9,7 +12,9 @@ use quicksilver::{
 use rand::prelude::*;
 
 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 {
     Button {
@@ -19,6 +24,18 @@ enum MenuItemType {
         h_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 {
@@ -67,6 +84,66 @@ impl Menu {
 
         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 {
@@ -77,8 +154,15 @@ struct GameState {
     s_speak_m: Asset<Sound>,
     s_speak_f: Asset<Sound>,
     font: Asset<Font>,
-    timer: f64,
+    music2: Asset<Sound>,
+    music_on: bool,
+    music_timer: f64,
     menu: Menu,
+    state: u32,
+    state_dirty: bool,
+    selection_mode: bool,
+    current_item: Option<usize>,
+    current_finished: bool,
 }
 
 impl State for GameState {
@@ -91,21 +175,93 @@ impl State for GameState {
             s_speak_m: Asset::new(Sound::load("speak_m.mp3")),
             s_speak_f: Asset::new(Sound::load("speak_f.mp3")),
             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(),
+            state: 0,
+            state_dirty: false,
+            selection_mode: true,
+            current_item: None,
+            current_finished: true,
         })
     }
 
     fn event(&mut self, event: &Event, window: &mut Window) -> Result<()> {
         match event {
-            Event::MouseMoved(v) =>
-                for mi in &mut self.menu.items {
-                    if mi.is_inside(v.x, v.y) {
-                        mi.is_hover = true;
+            Event::MouseMoved(v) => {
+                let mut hovered = false;
+                for i in 0..self.menu.items.len() {
+                    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 {
-                        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(())
@@ -113,19 +269,100 @@ impl State for GameState {
 
     fn update(&mut self, window: &mut Window) -> Result<()> {
         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 {
                 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| {
                             let style = FontStyle::new(42.0, *text_c);
                             *text_image = Some(font.render(text, &style)?);
                             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(())
@@ -140,7 +377,13 @@ impl State for GameState {
             rect.size.x = mi.w;
             rect.size.y = mi.h;
             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 {
                         window.draw(&rect, Col(*h_c));
                     } else {
@@ -150,11 +393,25 @@ impl State for GameState {
                         let mut image_rect = i.area();
                         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;
-                        window.draw(
-                            &image_rect,
-                            Img(i));
+                        window.draw(&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(())
diff --git a/static/music2.mp3 b/static/music2.mp3
new file mode 100644 (file)
index 0000000..b1b22ce
Binary files /dev/null and b/static/music2.mp3 differ