Merge pull request #1946 from vlidholt/master

Adds dialog for completed workout in Fitness demo
diff --git a/examples/material_gallery/lib/demo/fitness_demo.dart b/examples/material_gallery/lib/demo/fitness_demo.dart
index e2e12ec..d34f4c3 100644
--- a/examples/material_gallery/lib/demo/fitness_demo.dart
+++ b/examples/material_gallery/lib/demo/fitness_demo.dart
@@ -8,6 +8,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_sprites/flutter_sprites.dart';
+import 'package:vector_math/vector_math_64.dart' as vec;
 
 ImageMap _images;
 SpriteSheet _sprites;
@@ -173,6 +174,25 @@
   void endWorkout() {
     setState(() {
       workoutAnimation.stop();
+
+      if (count >= 3) {
+        showDialog(
+          context: context,
+          child: new Stack(children: <Widget>[
+            new _Fireworks(),
+            new Dialog(
+              title: new Text("Awesome workout"),
+              content: new Text("You have completed $count jumping jacks. Good going!"),
+              actions: <Widget>[
+                new FlatButton(
+                  child: new Text("SWEET"),
+                  onPressed: () { Navigator.pop(context); }
+                )
+              ]
+            )
+          ])
+        );
+      }
     });
   }
 }
@@ -489,3 +509,70 @@
     }
   }
 }
+
+class _Fireworks extends StatefulComponent {
+  _Fireworks({ Key key }) : super(key: key);
+
+  _FireworksState createState() => new _FireworksState();
+}
+
+class _FireworksState extends State<_Fireworks> {
+  void initState() {
+    super.initState();
+    fireworks = new _FireworksNode();
+  }
+
+  _FireworksNode fireworks;
+
+  Widget build(BuildContext context) {
+    return new SpriteWidget(fireworks);
+  }
+}
+
+class _FireworksNode extends NodeWithSize {
+  _FireworksNode() : super(const Size(1024.0, 1024.0));
+  double _countDown = 0.0;
+
+  void update(double dt) {
+    if (_countDown <= 0.0) {
+      _addExplosion();
+      _countDown = randomDouble();
+    }
+
+    _countDown -= dt;
+  }
+
+  Color _randomExplosionColor() {
+    double rand = randomDouble();
+    if (rand < 0.25)
+      return Colors.pink[200];
+    else if (rand < 0.5)
+      return Colors.lightBlue[200];
+    else if (rand < 0.75)
+      return Colors.purple[200];
+    else
+      return Colors.cyan[200];
+  }
+
+  void _addExplosion() {
+    Color startColor = _randomExplosionColor();
+    Color endColor = startColor.withAlpha(0);
+
+    ParticleSystem system = new ParticleSystem(
+      _sprites['particle-0.png'],
+      numParticlesToEmit: 100,
+      emissionRate: 1000.0,
+      rotateToMovement: true,
+      startRotation: 90.0,
+      endRotation: 90.0,
+      speed: 100.0,
+      speedVar: 50.0,
+      startSize: 1.0,
+      startSizeVar: 0.5,
+      gravity: new vec.Vector2(0.0, 30.0),
+      colorSequence: new ColorSequence.fromStartAndEndColor(startColor, endColor)
+    );
+    system.position = new Point(randomDouble() * 1024.0, randomDouble() * 1024.0);
+    addChild(system);
+  }
+}
diff --git a/examples/material_gallery/pubspec.yaml b/examples/material_gallery/pubspec.yaml
index 00bf3f7..7928aa2 100644
--- a/examples/material_gallery/pubspec.yaml
+++ b/examples/material_gallery/pubspec.yaml
@@ -6,4 +6,4 @@
     path: ../../packages/flutter
   flutter_sprites:
     path: ../../packages/flutter_sprites
-  flutter_gallery_assets: '0.0.7'
+  flutter_gallery_assets: '0.0.9'
diff --git a/packages/flutter_sprites/lib/src/particle_system.dart b/packages/flutter_sprites/lib/src/particle_system.dart
index ee40e7f..3b8fb40 100644
--- a/packages/flutter_sprites/lib/src/particle_system.dart
+++ b/packages/flutter_sprites/lib/src/particle_system.dart
@@ -252,7 +252,7 @@
         particle.dir += accel;
       } else if (gravity[0] != 0.0 || gravity[1] != 0) {
         // gravity
-        Vector2 accel = gravity.scale(dt);
+        Vector2 accel = new Vector2.copy(gravity).scale(dt);
         particle.dir += accel;
       }