mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 02:33:54 +03:00
scroll the map in the background while the splash screen menu is up.
remove screensaver as a plugin.
This commit is contained in:
parent
17870baf9d
commit
31f9f455bb
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user