From 5536e1bd4f7cf7f0afa1fb4b8af38d833e99b300 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Sat, 3 Oct 2020 17:45:04 +0900 Subject: [PATCH] Impl opening "cutscene" --- src/scenes/gamestart.rs | 17 +++- src/scenes/mainscene.rs | 187 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 185 insertions(+), 19 deletions(-) diff --git a/src/scenes/gamestart.rs b/src/scenes/gamestart.rs index 2e5613f..1a83fdf 100644 --- a/src/scenes/gamestart.rs +++ b/src/scenes/gamestart.rs @@ -23,6 +23,7 @@ pub struct GameStartScene { color_blue: Color, pick_color_text: Text, player: Rc>, + drawed_loading_text: bool, } impl GameStartScene { @@ -43,6 +44,7 @@ impl GameStartScene { color_blue: Color::from_rgb(0, 0, 0xff), pick_color_text, player, + drawed_loading_text: false, } } @@ -144,6 +146,19 @@ impl EventHandler for GameStartScene { DrawParam::new().dest([400f32 + 128f32 - 64f32, 328f32]), )?; + if self.finished { + self.pick_color_text = Text::new("Loading..."); + self.pick_color_text + .set_font(self.font, Scale::uniform(32f32)); + let text_width = self.pick_color_text.width(ctx) as f32 / 2f32; + graphics::draw( + ctx, + &self.pick_color_text, + DrawParam::new().dest([400f32 - text_width, 520f32]), + )?; + self.drawed_loading_text = true; + } + Ok(()) } @@ -185,6 +200,6 @@ impl EventHandler for GameStartScene { impl Scene for GameStartScene { fn finished(&self) -> bool { - self.finished + self.finished && self.drawed_loading_text } } diff --git a/src/scenes/mainscene.rs b/src/scenes/mainscene.rs index 1588823..b8b7c7e 100644 --- a/src/scenes/mainscene.rs +++ b/src/scenes/mainscene.rs @@ -3,7 +3,8 @@ use std::rc::Rc; use ggez::audio::{SoundSource, Source}; use ggez::event::EventHandler; -use ggez::graphics::{self, Color, DrawMode, DrawParam, Font, Image, Mesh, Rect, Text}; +use ggez::graphics::{self, Color, DrawMode, DrawParam, Font, Image, Mesh, Rect, Scale, Text}; +use ggez::input::keyboard::{KeyCode, KeyMods}; use ggez::input::mouse::MouseButton; use ggez::timer::delta; use ggez::{Context, GameResult}; @@ -11,10 +12,23 @@ use ggez::{Context, GameResult}; use super::Scene; use crate::player::Player; -const DARKNESS_PAN_RATE: f32 = 50f32; +const DARKNESS_PAN_RATE: f32 = 40f32; +const FLICKER_TIME: [f32; 6] = [1f32, 0.1f32, 0.85f32, 0.07f32, 0.12f32, 0.09f32]; +const FLICKER_STATE: [bool; 6] = [true, false, true, false, true, false]; +const TEXT_RATE: f32 = 0.3f32; +const TEXT_FAST_RATE: f32 = 0.1f32; +const IN_POD_TEXT_WAIT_TIME: f32 = 1f32; +const GET_OUT_OF_POD_TIME: f32 = 3f32; enum State { InPod_InDarkness, + InPod_WakeupText, + GetOutOfPod, + Investigate, +} + +enum Room { + StasisPod, } pub struct MainScene { @@ -23,14 +37,18 @@ pub struct MainScene { finished: bool, current_text: Text, final_text: String, - text_idx: usize, + text_sfx: Source, music: Source, pod_image: Image, - pod_empty_image: Image, + pod_flicker_image: Image, ground_rect: Rect, state: State, darkness_image: Image, darkness_yoffset: f32, + timer: f32, + draw_flicker_pod: bool, + index: usize, + room: Room, } impl MainScene { @@ -38,20 +56,26 @@ impl MainScene { let mut music = Source::new(ctx, "/music00.ogg").unwrap(); music.set_repeat(true); // music.play().unwrap(); + let mut current_text = Text::new("".to_owned()); + current_text.set_font(font, Scale::uniform(26f32)); Self { font, player, finished: false, - current_text: Text::new("".to_owned()), + current_text, final_text: String::new(), - text_idx: 0usize, + text_sfx: Source::new(ctx, "/text.ogg").unwrap(), music, pod_image: Image::new(ctx, "/stasis_pod.png").unwrap(), - pod_empty_image: Image::new(ctx, "/stasis_pod_empty.png").unwrap(), + pod_flicker_image: Image::new(ctx, "/stasis_pod_empty.png").unwrap(), ground_rect: Rect::new(0f32, 550f32, 800f32, 50f32), state: State::InPod_InDarkness, darkness_image: Image::new(ctx, "/darkness.png").unwrap(), darkness_yoffset: 0f32, + timer: FLICKER_TIME[0], + draw_flicker_pod: false, + index: 0usize, + room: Room::StasisPod, } } @@ -62,46 +86,137 @@ impl MainScene { impl EventHandler for MainScene { fn update(&mut self, ctx: &mut Context) -> GameResult<()> { + let dt = delta(ctx).as_secs_f32(); match self.state { State::InPod_InDarkness => { let mut player = self.player.borrow_mut(); player.x = 520f32; player.y = 350f32; player.rot = 0.78f32; - if self.darkness_yoffset > -400f32 { - self.darkness_yoffset -= delta(ctx).as_secs_f32() * DARKNESS_PAN_RATE; + self.timer -= dt; + if self.timer <= 0f32 { + self.draw_flicker_pod = FLICKER_STATE[self.index]; + self.index = (self.index + 1) % 6; + self.timer = FLICKER_TIME[self.index]; + } + if self.darkness_yoffset > -300f32 { + self.darkness_yoffset -= dt * DARKNESS_PAN_RATE; + } else { + self.state = State::InPod_WakeupText; + self.timer = TEXT_RATE; + self.final_text = "What.. Where am I?..".chars().rev().collect::(); + } + } + State::InPod_WakeupText => { + if !self.final_text.is_empty() { + self.timer -= dt; + if self.timer <= 0f32 { + self.timer = TEXT_RATE; + self.current_text.fragments_mut()[0] + .text + .push(self.final_text.pop().unwrap()); + self.text_sfx.play()?; + if self.final_text.is_empty() { + self.timer = IN_POD_TEXT_WAIT_TIME; + } + } + } else { + self.timer -= dt; + if self.timer <= 0f32 { + self.timer = 0f32; + } } } + State::GetOutOfPod => { + self.timer -= dt; + if self.timer > 0f32 { + let mut player = self.player.borrow_mut(); + let lerp = self.timer / GET_OUT_OF_POD_TIME; + player.x = (520f32 * lerp) + (500f32 * (1f32 - lerp)); + player.y = (350f32 * lerp) + (430f32 * (1f32 - lerp)); + player.rot = (0.78f32 * lerp) + (0f32 * (1f32 - lerp)); + } else if self.timer <= 0f32 { + self.state = State::Investigate; + self.music.play()?; + } + } + State::Investigate => { + // TODO + } } self.player.borrow_mut().update(ctx)?; Ok(()) } fn draw(&mut self, ctx: &mut Context) -> GameResult<()> { + { + let ground_mesh = Mesh::new_rectangle( + ctx, + DrawMode::fill(), + self.ground_rect, + Color::from_rgb(0x49, 0x49, 0x49), + )?; + graphics::draw(ctx, &ground_mesh, DrawParam::new())?; + } + match self.state { State::InPod_InDarkness => { + if self.draw_flicker_pod { + graphics::draw( + ctx, + &self.pod_flicker_image, + DrawParam::new().dest([600f32, 170f32]).rotation(0.7f32), + )?; + } else { + graphics::draw( + ctx, + &self.pod_image, + DrawParam::new().dest([600f32, 170f32]).rotation(0.7f32), + )?; + } + self.player.borrow_mut().draw(ctx)?; + } + State::InPod_WakeupText | State::GetOutOfPod => { graphics::draw( ctx, - &self.pod_image, + &self.pod_flicker_image, DrawParam::new().dest([600f32, 170f32]).rotation(0.7f32), )?; self.player.borrow_mut().draw(ctx)?; } + State::Investigate => { + match self.room { + Room::StasisPod => { + graphics::draw( + ctx, + &self.pod_flicker_image, + DrawParam::new().dest([600f32, 170f32]).rotation(0.7f32), + )?; + } + } + self.player.borrow_mut().draw(ctx)?; + } } - let ground_mesh = Mesh::new_rectangle( - ctx, - DrawMode::fill(), - self.ground_rect, - Color::from_rgb(0x49, 0x49, 0x49), - )?; - graphics::draw(ctx, &ground_mesh, DrawParam::new())?; - graphics::draw( ctx, &self.darkness_image, DrawParam::new().dest([0f32, self.darkness_yoffset]), )?; + + match self.state { + State::InPod_InDarkness => (), + State::InPod_WakeupText => { + graphics::draw( + ctx, + &self.current_text, + DrawParam::new().dest([100f32, 100f32]), + )?; + } + State::GetOutOfPod => (), + State::Investigate => (), + } + Ok(()) } @@ -112,6 +227,42 @@ impl EventHandler for MainScene { x: f32, y: f32, ) { + match self.state { + State::InPod_InDarkness => (), + State::InPod_WakeupText => { + if self.final_text.is_empty() && self.timer <= 0f32 { + self.state = State::GetOutOfPod; + self.timer = GET_OUT_OF_POD_TIME; + } else { + self.timer = 0f32; + } + } + State::GetOutOfPod => (), + State::Investigate => {} + } + } + + fn key_down_event( + &mut self, + _ctx: &mut Context, + _keycode: KeyCode, + _keymods: KeyMods, + _repeat: bool, + ) { + match self.state { + State::InPod_InDarkness => (), + State::InPod_WakeupText => { + if self.final_text.is_empty() && self.timer <= 0f32 { + self.state = State::GetOutOfPod; + self.timer = GET_OUT_OF_POD_TIME; + self.current_text.fragments_mut()[0].text.clear(); + } else { + self.timer = 0f32; + } + } + State::GetOutOfPod => (), + State::Investigate => {} + } } } -- 2.49.0