scroll the map in the background while the splash screen menu is up.

remove screensaver as a plugin.
This commit is contained in:
Dustin Carlino 2019-04-21 13:35:32 -07:00
parent 17870baf9d
commit 31f9f455bb
5 changed files with 77 additions and 85 deletions

View File

@ -8,5 +8,4 @@ pub mod geom_validation;
pub mod hider;
pub mod layers;
pub mod orig_roads;
pub mod screensaver;
pub mod spawn_agent;

View File

@ -1,69 +0,0 @@
use crate::plugins::{BlockingPlugin, PluginCtx};
use abstutil::elapsed_seconds;
use ezgui::EventLoopMode;
use geom::{Duration, Line, Pt2D, Speed};
use rand::Rng;
use rand_xorshift::XorShiftRng;
use std::time::Instant;
const SPEED: Speed = Speed::const_meters_per_second(50.0);
pub struct Screensaver {
line: Line,
started: Instant,
rng: XorShiftRng,
}
impl Screensaver {
pub fn new(ctx: &mut PluginCtx) -> Option<Screensaver> {
if ctx.input.action_chosen("screensaver mode") {
let mut rng = ctx.primary.current_flags.sim_flags.make_rng();
ctx.hints.mode = EventLoopMode::Animation;
let at = ctx.canvas.center_to_map_pt();
ctx.canvas.cam_zoom = 10.0;
ctx.canvas.center_on_map_pt(at);
return Some(Screensaver {
line: Screensaver::bounce(ctx, &mut rng),
started: Instant::now(),
rng,
});
}
None
}
fn bounce(ctx: &mut PluginCtx, rng: &mut XorShiftRng) -> Line {
let bounds = ctx.primary.map.get_bounds();
let at = ctx.canvas.center_to_map_pt();
// TODO Ideally bounce off the edge of the map
let goto = Pt2D::new(
rng.gen_range(0.0, bounds.max_x),
rng.gen_range(0.0, bounds.max_y),
);
Line::new(at, goto)
}
}
impl BlockingPlugin for Screensaver {
fn blocking_event(&mut self, ctx: &mut PluginCtx) -> bool {
ctx.input.set_mode("Screensaver", &ctx.canvas);
if ctx.input.modal_action("quit") {
return false;
}
if ctx.input.nonblocking_is_update_event() {
ctx.input.use_update_event();
let dist_along = Duration::seconds(elapsed_seconds(self.started)) * SPEED;
if dist_along < self.line.length() {
ctx.canvas
.center_on_map_pt(self.line.dist_along(dist_along));
} else {
self.line = Screensaver::bounce(ctx, &mut self.rng);
self.started = Instant::now();
}
ctx.hints.mode = EventLoopMode::Animation;
}
true
}
}

View File

@ -1,9 +1,15 @@
use crate::state::{DefaultUIState, Flags};
use crate::state::{DefaultUIState, Flags, UIState};
use crate::ui::UI;
use abstutil::elapsed_seconds;
use ezgui::{
Canvas, EventCtx, EventLoopMode, GfxCtx, ModalMenu, Prerender, TopMenu, Wizard, WrappedWizard,
GUI,
Canvas, EventCtx, EventLoopMode, GfxCtx, ModalMenu, Prerender, TopMenu, UserInput, Wizard,
WrappedWizard, GUI,
};
use geom::{Duration, Line, Pt2D, Speed};
use map_model::Map;
use rand::Rng;
use rand_xorshift::XorShiftRng;
use std::time::Instant;
pub struct GameState {
mode: Mode,
@ -11,15 +17,19 @@ pub struct GameState {
}
enum Mode {
SplashScreen(Wizard),
SplashScreen(Wizard, Screensaver, XorShiftRng),
Playing,
}
impl GameState {
pub fn new(flags: Flags, canvas: &mut Canvas, prerender: &Prerender) -> GameState {
let mut rng = flags.sim_flags.make_rng();
let ui = UI::new(DefaultUIState::new(flags, prerender, true), canvas);
let screensaver =
Screensaver::start_bounce(&mut rng, canvas, &ui.state.get_state().primary.map);
GameState {
mode: Mode::SplashScreen(Wizard::new()),
ui: UI::new(DefaultUIState::new(flags, prerender, true), canvas),
mode: Mode::SplashScreen(Wizard::new(), screensaver, rng),
ui,
}
}
}
@ -37,11 +47,18 @@ impl GUI for GameState {
fn event(&mut self, mut ctx: EventCtx) -> EventLoopMode {
match self.mode {
Mode::SplashScreen(ref mut wizard) => {
Mode::SplashScreen(ref mut wizard, ref mut screensaver, ref mut rng) => {
screensaver.update(
rng,
&mut ctx.input,
&mut ctx.canvas,
&self.ui.state.get_state().primary.map,
);
if splash_screen(wizard.wrap(&mut ctx.input, ctx.canvas), &mut self.ui).is_some() {
self.mode = Mode::Playing;
}
EventLoopMode::InputOnly
EventLoopMode::Animation
}
Mode::Playing => self.ui.event(ctx),
}
@ -49,7 +66,10 @@ impl GUI for GameState {
fn draw(&self, g: &mut GfxCtx, screencap: bool) -> Option<String> {
match self.mode {
Mode::SplashScreen(ref wizard) => {
Mode::SplashScreen(ref wizard, _, _) => {
// Draw the map in the background.
self.ui.draw(g, screencap);
wizard.draw(g);
None
}
@ -85,3 +105,50 @@ fn splash_screen(mut wizard: WrappedWizard, ui: &mut UI<DefaultUIState>) -> Opti
_ => unreachable!(),
}
}
const SPEED: Speed = Speed::const_meters_per_second(50.0);
// TODO I'd prefer to store the XorShiftRng in here, but it makes borrow checking without some
// boilerplate hard.
struct Screensaver {
line: Line,
started: Instant,
}
impl Screensaver {
fn start_bounce(rng: &mut XorShiftRng, canvas: &mut Canvas, map: &Map) -> Screensaver {
let at = canvas.center_to_map_pt();
let bounds = map.get_bounds();
// TODO Ideally bounce off the edge of the map
let goto = Pt2D::new(
rng.gen_range(0.0, bounds.max_x),
rng.gen_range(0.0, bounds.max_y),
);
canvas.cam_zoom = 10.0;
canvas.center_on_map_pt(at);
Screensaver {
line: Line::new(at, goto),
started: Instant::now(),
}
}
fn update(
&mut self,
rng: &mut XorShiftRng,
input: &mut UserInput,
canvas: &mut Canvas,
map: &Map,
) {
if input.nonblocking_is_update_event() {
input.use_update_event();
let dist_along = Duration::seconds(elapsed_seconds(self.started)) * SPEED;
if dist_along < self.line.length() {
canvas.center_on_map_pt(self.line.dist_along(dist_along));
} else {
*self = Screensaver::start_bounce(rng, canvas, map)
}
}
}
}

View File

@ -289,9 +289,6 @@ impl UIState for DefaultUIState {
} else if let Some(p) = debug::spawn_agent::SpawnAgent::new(&mut ctx) {
self.exclusive_blocking_plugin = Some(Box::new(p));
return;
} else if let Some(p) = debug::screensaver::Screensaver::new(&mut ctx) {
self.exclusive_blocking_plugin = Some(Box::new(p));
return;
}
}
}

View File

@ -18,7 +18,7 @@ pub struct UI<S: UIState> {
// TODO Probably move this into DefaultUIState after rewriting Tutorial and the whole UIState
// abstraction.
hints: RenderingHints,
state: S,
pub state: S,
}
impl<S: UIState> GUI for UI<S> {
@ -44,7 +44,6 @@ impl<S: UIState> GUI for UI<S> {
(Some(Key::Num7), "show/hide extra shapes"),
(Some(Key::Num9), "show/hide all turn icons"),
(None, "show/hide geometry debug mode"),
(None, "screensaver mode"),
],
));
}
@ -173,7 +172,6 @@ impl<S: UIState> GUI for UI<S> {
vec![(Key::Enter, "quit"), (Key::N, "see next problem")],
),
ModalMenu::new("Original Roads", vec![(Key::Enter, "quit")]),
ModalMenu::new("Screensaver", vec![(Key::Enter, "quit")]),
ModalMenu::new("OSM Classifier", vec![(Key::Num6, "quit")]),
ModalMenu::new(
"Floodfiller",