diff --git a/rustdoc/experiment/animation/enum.Effect.html b/rustdoc/experiment/animation/enum.Effect.html index f4c51e49b7..6bc8e92910 100644 --- a/rustdoc/experiment/animation/enum.Effect.html +++ b/rustdoc/experiment/animation/enum.Effect.html @@ -1,7 +1,7 @@ experiment::animation::Effect - Rust -

[][src]Enum experiment::animation::Effect

pub enum Effect {
+

[][src]Enum experiment::animation::Effect

pub enum Effect {
     Scale {
         orig: GeomBatch,
         center: Pt2D,
@@ -12,9 +12,14 @@
         width: Distance,
         pl: PolyLine,
     },
+    Flash {
+        orig: GeomBatch,
+        alpha_scale: (f32, f32),
+        cycles: usize,
+    },
 }

Variants

-
Scale

Fields of Scale

orig: GeomBatchcenter: Pt2Dlerp_scale: (f64, f64)
FollowPath

Fields of FollowPath

color: Colorwidth: Distancepl: PolyLine

Implementations

impl Effect[src]

fn render(&self, pct: f64, batch: &mut GeomBatch)[src]

Auto Trait Implementations

impl RefUnwindSafe for Effect

impl Send for Effect

impl Sync for Effect

impl Unpin for Effect

impl UnwindSafe for Effect

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

 use rand::{Rng, SeedableRng};
 use rand_xorshift::XorShiftRng;
 
 use geom::{Distance, Duration, PolyLine, Pt2D, Time};
-use widgetry::{Color, Drawable, EventCtx, GeomBatch, GfxCtx};
+use widgetry::{Color, Drawable, EventCtx, GeomBatch, GfxCtx, RewriteColor};
 
 pub struct Animator {
     active: Vec<Animation>,
-    draw_current: Drawable,
+    draw_mapspace: Drawable,
+    draw_screenspace: Option<Drawable>,
 }
 
 struct Animation {
     start: Time,
     end: Time,
     effect: Effect,
+    screenspace: bool,
 }
 
 pub enum Effect {
@@ -217,13 +265,19 @@
         width: Distance,
         pl: PolyLine,
     },
+    Flash {
+        orig: GeomBatch,
+        alpha_scale: (f32, f32),
+        cycles: usize,
+    },
 }
 
 impl Animator {
     pub fn new(ctx: &EventCtx) -> Animator {
         Animator {
             active: Vec::new(),
-            draw_current: Drawable::empty(ctx),
+            draw_mapspace: Drawable::empty(ctx),
+            draw_screenspace: None,
         }
     }
 
@@ -233,6 +287,16 @@
             start: now,
             end: now + duration,
             effect,
+            screenspace: false,
+        });
+    }
+
+    pub fn add_screenspace(&mut self, now: Time, duration: Duration, effect: Effect) {
+        self.active.push(Animation {
+            start: now,
+            end: now + duration,
+            effect,
+            screenspace: true,
         });
     }
 
@@ -240,7 +304,8 @@
         if self.active.is_empty() {
             return;
         }
-        let mut batch = GeomBatch::new();
+        let mut mapspace = GeomBatch::new();
+        let mut screenspace = GeomBatch::new();
         self.active.retain(|anim| {
             let pct = (now - anim.start) / (anim.end - anim.start);
             if pct < 0.0 {
@@ -249,15 +314,29 @@
             } else if pct > 1.0 {
                 false
             } else {
-                anim.effect.render(pct, &mut batch);
+                if anim.screenspace {
+                    anim.effect.render(pct, &mut screenspace);
+                } else {
+                    anim.effect.render(pct, &mut mapspace);
+                }
                 true
             }
         });
-        self.draw_current = ctx.upload(batch);
+        self.draw_mapspace = ctx.upload(mapspace);
+        if screenspace.is_empty() {
+            self.draw_screenspace = None;
+        } else {
+            self.draw_screenspace = Some(ctx.upload(screenspace));
+        }
     }
 
     pub fn draw(&self, g: &mut GfxCtx) {
-        g.redraw(&self.draw_current);
+        g.redraw(&self.draw_mapspace);
+        if let Some(ref d) = self.draw_screenspace {
+            g.fork_screenspace();
+            g.redraw(d);
+            g.unfork();
+        }
     }
 
     pub fn is_done(&self) -> bool {
@@ -285,6 +364,19 @@
                     batch.push(*color, pl.make_polygons(*width));
                 }
             }
+            Effect::Flash {
+                ref orig,
+                alpha_scale,
+                cycles,
+            } => {
+                // -1 to 1
+                let shift = (pct * (*cycles as f64) * (2.0 * std::f64::consts::PI)).sin() as f32;
+                let midpt = (alpha_scale.0 + alpha_scale.1) / 2.0;
+                let half_range = (alpha_scale.1 - alpha_scale.0) / 2.0;
+                let alpha = midpt + shift * half_range;
+
+                batch.append(orig.clone().color(RewriteColor::ChangeAlpha(alpha)));
+            }
         }
     }
 }
diff --git a/rustdoc/src/experiment/game.rs.html b/rustdoc/src/experiment/game.rs.html
index 2fda253a0c..b64a1725f1 100644
--- a/rustdoc/src/experiment/game.rs.html
+++ b/rustdoc/src/experiment/game.rs.html
@@ -632,6 +632,74 @@
 629
 630
 631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
 
 use std::collections::HashSet;
 
@@ -890,6 +958,7 @@
                     let refill = self.state.vehicle.max_energy - self.state.energy;
                     if refill > 0 {
                         self.state.energy += refill;
+                        self.state.warned_low_energy = false;
                         let path_speed = Duration::seconds(0.2);
                         self.animator.add(
                             app.time,
@@ -1022,6 +1091,69 @@
                 );
             }
 
+            if !self.state.warned_low_time
+                && self.state.level.time_limit - (app.time - Time::START_OF_DAY)
+                    <= Duration::seconds(20.0)
+            {
+                self.state.warned_low_time = true;
+                self.animator.add(
+                    app.time,
+                    Duration::seconds(2.0),
+                    Effect::Flash {
+                        alpha_scale: (0.1, 0.5),
+                        cycles: 2,
+                        orig: GeomBatch::from(vec![(
+                            Color::RED,
+                            app.map.get_boundary_polygon().clone(),
+                        )]),
+                    },
+                );
+                self.animator.add_screenspace(
+                    app.time,
+                    Duration::seconds(2.0),
+                    Effect::Scale {
+                        lerp_scale: (1.0, 4.0),
+                        center: {
+                            let pt = ctx.canvas.center_to_screen_pt();
+                            Pt2D::new(pt.x, pt.y / 2.0)
+                        },
+                        orig: Text::from(Line("Almost out of time!"))
+                            .bg(Color::RED)
+                            .render_autocropped(ctx),
+                    },
+                );
+            }
+
+            if !self.state.warned_low_energy && self.state.energy < 30 {
+                self.state.warned_low_energy = true;
+                self.animator.add(
+                    app.time,
+                    Duration::seconds(2.0),
+                    Effect::Flash {
+                        alpha_scale: (0.1, 0.5),
+                        cycles: 2,
+                        orig: GeomBatch::from(vec![(
+                            Color::RED,
+                            app.map.get_boundary_polygon().clone(),
+                        )]),
+                    },
+                );
+                self.animator.add_screenspace(
+                    app.time,
+                    Duration::seconds(2.0),
+                    Effect::Scale {
+                        lerp_scale: (1.0, 4.0),
+                        center: {
+                            let pt = ctx.canvas.center_to_screen_pt();
+                            Pt2D::new(pt.x, pt.y / 2.0)
+                        },
+                        orig: Text::from(Line("Low on blood sugar, refill soon!"))
+                            .bg(Color::RED)
+                            .render_autocropped(ctx),
+                    },
+                );
+            }
+
             ctx.request_update(UpdateType::Game);
             return Transition::Keep;
         }
@@ -1139,6 +1271,8 @@
     idle_time: Duration,
 
     game_over: bool,
+    warned_low_time: bool,
+    warned_low_energy: bool,
 }
 
 impl GameState {
@@ -1159,6 +1293,8 @@
             idle_time: Duration::ZERO,
 
             game_over: false,
+            warned_low_time: false,
+            warned_low_energy: false,
         }
     }
 
diff --git a/rustdoc/src/experiment/vehicles.rs.html b/rustdoc/src/experiment/vehicles.rs.html
index 18160ab08d..990e684fb1 100644
--- a/rustdoc/src/experiment/vehicles.rs.html
+++ b/rustdoc/src/experiment/vehicles.rs.html
@@ -100,7 +100,7 @@
                 name: "bike".to_string(),
 
                 speed: Speed::miles_per_hour(30.0),
-                max_energy: 100,
+                max_energy: 50,
 
                 draw_frames: vec!["bike1.svg", "bike2.svg", "bike1.svg", "bike3.svg"],
                 scale: 0.05,
diff --git a/rustdoc/src/game/home/runner/work/abstreet/abstreet/target/debug/build/game-c1f324f9d3d7e3b2/out/built.rs.html b/rustdoc/src/game/home/runner/work/abstreet/abstreet/target/debug/build/game-c1f324f9d3d7e3b2/out/built.rs.html
index 30967d9c89..03a453a9d5 100644
--- a/rustdoc/src/game/home/runner/work/abstreet/abstreet/target/debug/build/game-c1f324f9d3d7e3b2/out/built.rs.html
+++ b/rustdoc/src/game/home/runner/work/abstreet/abstreet/target/debug/build/game-c1f324f9d3d7e3b2/out/built.rs.html
@@ -122,7 +122,7 @@
 /// The output of `rustdoc -V`
 pub const RUSTDOC_VERSION: &str = "rustdoc 1.48.0 (7eac88abb 2020-11-16)";
 /// The built-time in RFC2822, UTC
-pub const BUILT_TIME_UTC: &str = "Thu, 17 Dec 2020 23:28:20 +0000";
+pub const BUILT_TIME_UTC: &str = "Fri, 18 Dec 2020 00:24:44 +0000";
 /// The target architecture, given by `cfg!(target_arch)`.
 pub const CFG_TARGET_ARCH: &str = "x86_64";
 /// The endianness, given by `cfg!(target_endian)`.
diff --git a/rustdoc/src/widgetry/geom.rs.html b/rustdoc/src/widgetry/geom.rs.html
index eacad15e28..7c11c68b75 100644
--- a/rustdoc/src/widgetry/geom.rs.html
+++ b/rustdoc/src/widgetry/geom.rs.html
@@ -394,7 +394,7 @@
     }
 
     /// True when the batch is empty.
-    pub(crate) fn is_empty(&self) -> bool {
+    pub fn is_empty(&self) -> bool {
         self.list.is_empty()
     }
 
diff --git a/rustdoc/widgetry/geom/struct.GeomBatch.html b/rustdoc/widgetry/geom/struct.GeomBatch.html
index 4210b19f21..0c8ddb58ac 100644
--- a/rustdoc/widgetry/geom/struct.GeomBatch.html
+++ b/rustdoc/widgetry/geom/struct.GeomBatch.html
@@ -24,7 +24,7 @@ many times later.

pub fn get_bounds(&self) -> Bounds[src]

Compute the bounds of all polygons in this batch.

pub fn autocrop(self) -> GeomBatch[src]

Sets the top-left to 0, 0. Not sure exactly when this should be used.

pub fn unioned_polygon(&self) -> Polygon[src]

Builds a single polygon covering everything in this batch. Use to create a hitbox.

-

pub(crate) fn is_empty(&self) -> bool[src]

True when the batch is empty.

+

pub fn is_empty(&self) -> bool[src]

True when the batch is empty.

pub fn get_dims(&self) -> ScreenDims[src]

Returns the width and height of all geometry contained in the batch.

pub fn from_svg_contents(raw: Vec<u8>) -> GeomBatch[src]

Returns a batch containing a parsed SVG string.

pub fn load_svg<P: AsRef<Prerender>>(prerender: &P, filename: &str) -> GeomBatch[src]

Returns a batch containing an SVG from a file.

diff --git a/rustdoc/widgetry/struct.GeomBatch.html b/rustdoc/widgetry/struct.GeomBatch.html index edc4da27b3..2d8314db1b 100644 --- a/rustdoc/widgetry/struct.GeomBatch.html +++ b/rustdoc/widgetry/struct.GeomBatch.html @@ -24,7 +24,7 @@ many times later.

pub fn get_bounds(&self) -> Bounds[src]

Compute the bounds of all polygons in this batch.

pub fn autocrop(self) -> GeomBatch[src]

Sets the top-left to 0, 0. Not sure exactly when this should be used.

pub fn unioned_polygon(&self) -> Polygon[src]

Builds a single polygon covering everything in this batch. Use to create a hitbox.

-

pub(crate) fn is_empty(&self) -> bool[src]

True when the batch is empty.

+

pub fn is_empty(&self) -> bool[src]

True when the batch is empty.

pub fn get_dims(&self) -> ScreenDims[src]

Returns the width and height of all geometry contained in the batch.

pub fn from_svg_contents(raw: Vec<u8>) -> GeomBatch[src]

Returns a batch containing a parsed SVG string.

pub fn load_svg<P: AsRef<Prerender>>(prerender: &P, filename: &str) -> GeomBatch[src]

Returns a batch containing an SVG from a file.