Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Unified Diff: sky/sdk/example/game/lib/action.dart

Issue 1235653004: Improved action animations in sprites (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sky/sdk/example/game/lib/sprite_box.dart » ('j') | sky/sdk/example/game/lib/sprites.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/sdk/example/game/lib/action.dart
diff --git a/sky/sdk/example/game/lib/action.dart b/sky/sdk/example/game/lib/action.dart
index 0c6119d528a3937a7b938b18fba62953699ac465..54073173e09704e9f75bb4c1c9825c0b4dbd6bfe 100644
--- a/sky/sdk/example/game/lib/action.dart
+++ b/sky/sdk/example/game/lib/action.dart
@@ -5,11 +5,16 @@ typedef void ActionCallback();
abstract class Action {
Object _tag;
bool _finished = false;
+ bool _added = false;
void step(double dt);
void update(double t) {
}
+ void _reset() {
+ _finished = false;
+ }
+
double get duration => 0.0;
}
@@ -20,8 +25,9 @@ abstract class ActionInterval extends Action {
double _elapsed = 0.0;
double get duration => _duration;
+ Curve curve;
- ActionInterval([this._duration = 0.0]);
+ ActionInterval([this._duration = 0.0, this.curve]);
void step(double dt) {
if (_firstTick) {
@@ -37,7 +43,11 @@ abstract class ActionInterval extends Action {
t = (_elapsed / _duration).clamp(0.0, 1.0);
}
- update(t);
+ if (curve == null) {
+ update(t);
+ } else {
+ update(curve.transform(t));
+ }
if (t >= 1.0) _finished = true;
}
@@ -46,13 +56,53 @@ abstract class ActionInterval extends Action {
class ActionRepeat extends ActionInterval {
final int numRepeats;
final ActionInterval action;
+ int _lastFinishedRepeat = -1;
ActionRepeat(this.action, this.numRepeats) {
_duration = action.duration * numRepeats;
}
void update(double t) {
- action.update((t * numRepeats.toDouble()) % numRepeats.toDouble());
+ int currentRepeat = Math.min((t * numRepeats.toDouble()).toInt(), numRepeats - 1);
+ for (int i = Math.max(_lastFinishedRepeat, 0); i < currentRepeat; i++) {
+ if (!action._finished) action.update(1.0);
+ action._reset();
+ }
+ _lastFinishedRepeat = currentRepeat;
+
+ double ta = (t * numRepeats.toDouble()) % 1.0;
+ action.update(ta);
+
+ if (t >= 1.0) {
+ action.update(1.0);
+ action._finished = true;
+ }
+ }
+}
+
+class ActionRepeatForever extends Action {
+ final ActionInterval action;
+ double _elapsedInAction = 0.0;
+
+ ActionRepeatForever(this.action);
+
+ step(double dt) {
+ _elapsedInAction += dt;
+ while (_elapsedInAction > action.duration) {
+ _elapsedInAction -= action.duration;
+ if (!action._finished) action.update(1.0);
+ action._reset();
+ }
+ _elapsedInAction = Math.max(_elapsedInAction, 0.0);
+
+ double t;
+ if (action._duration == 0.0) {
+ t = 1.0;
+ } else {
+ t = (_elapsedInAction / action._duration).clamp(0.0, 1.0);
+ }
+
+ action.update(t);
}
}
@@ -91,21 +141,107 @@ class ActionSequence extends ActionInterval {
} else {
ta = 1.0;
}
- _a.update(ta);
+ _updateWithCurve(_a, ta);
} else if (t >= 1.0) {
// Make sure everything is finished
- if (!_a._finished) _a.update(1.0);
- if (!_b._finished) _b.update(1.0);
+ if (!_a._finished) _finish(_a);
+ if (!_b._finished) _finish(_b);
} else {
// Play second action, but first make sure the first has finished
- if (!_a._finished) _a.update(1.0);
+ if (!_a._finished) _finish(_a);
double tb;
if (_split < 1.0) {
tb = (1.0 - (1.0 - t) / (1.0 - _split)).clamp(0.0, 1.0);
} else {
tb = 1.0;
}
- _b.update(tb);
+ _updateWithCurve(_b, tb);
+ }
+ }
+
+ void _updateWithCurve(Action action, double t) {
+ if (action is ActionInterval) {
+ ActionInterval actionInterval = action;
+ if (actionInterval.curve == null) {
+ action.update(t);
+ } else {
+ action.update(actionInterval.curve.transform(t));
+ }
+ } else {
+ action.update(t);
+ }
+
+ if (t >= 1.0) {
+ action._finished = true;
+ }
+ }
+
+ void _finish(Action action) {
+ action.update(1.0);
+ action._finished = true;
+ }
+
+ void _reset() {
+ super._reset();
+ _a._reset();
+ _b._reset();
+ }
+}
+
+class ActionGroup extends ActionInterval {
+ List<Action> _actions;
+
+ ActionGroup(this._actions) {
+ for (Action action in _actions) {
+ if (action.duration > _duration) {
+ _duration = action.duration;
+ }
+ }
+ }
+
+ void update(double t) {
+ if (t >= 1.0) {
+ // Finish all unfinished actions
+ for (Action action in _actions) {
+ if (!action._finished) {
+ action.update(1.0);
+ action._finished = true;
+ }
+ }
+ } else {
+ for (Action action in _actions) {
+ if (action.duration == 0.0) {
+ // Fire all instant actions immediately
+ if (!action._finished) {
+ action.update(1.0);
+ action._finished = true;
+ }
+ } else {
+ // Update child actions
+ double ta = (t / (action.duration / duration)).clamp(0.0, 1.0);
+ if (ta < 1.0) {
+ if (action is ActionInterval) {
+ ActionInterval actionInterval = action;
+ if (actionInterval.curve == null) {
+ action.update(ta);
+ } else {
+ action.update(actionInterval.curve.transform(ta));
+ }
+ } else {
+ action.update(ta);
+ }
+ } else if (!action._finished){
+ action.update(1.0);
+ action._finished = true;
+ }
+ }
+ }
+ }
+ }
+
+ void _reset() {
+ for (Action action in _actions) {
+ action._reset();
}
}
}
@@ -143,30 +279,6 @@ class ActionRemoveNode extends ActionInstant {
}
}
-class ActionRepeatForever extends Action {
- final ActionInterval action;
- double _elapsedInAction = 0.0;
-
- ActionRepeatForever(this.action);
-
- step(double dt) {
- _elapsedInAction += dt;
- while (_elapsedInAction > action.duration) {
- _elapsedInAction -= action.duration;
- }
- _elapsedInAction = Math.max(_elapsedInAction, 0.0);
-
- double t;
- if (action._duration == 0.0) {
- t = 1.0;
- } else {
- t = (_elapsedInAction / action._duration).clamp(0.0, 1.0);
- }
-
- action.update(t);
- }
-}
-
class ActionTween extends ActionInterval {
final Function setter;
final startVal;
@@ -174,20 +286,41 @@ class ActionTween extends ActionInterval {
var _delta;
- ActionTween(this.setter, this.startVal, this.endVal, double duration) : super(duration) {
+ ActionTween(this.setter, this.startVal, this.endVal, double duration, [Curve curve]) : super(duration, curve) {
_computeDelta();
}
void _computeDelta() {
if (startVal is Point) {
+ // Point
double xStart = startVal.x;
double yStart = startVal.y;
double xEnd = endVal.x;
double yEnd = endVal.y;
_delta = new Point(xEnd - xStart, yEnd - yStart);
+ } else if (startVal is Size) {
+ // Size
+ double wStart = startVal.width;
+ double hStart = startVal.height;
+ double wEnd = endVal.width;
+ double hEnd = endVal.height;
+ _delta = new Size(wEnd - wStart, hEnd - hStart);
+ } else if (startVal is Rect) {
+ // Rect
+ double lStart = startVal.left;
+ double tStart = startVal.top;
+ double rStart = startVal.right;
+ double bStart = startVal.bottom;
+ double lEnd = endVal.left;
+ double tEnd = endVal.top;
+ double rEnd = endVal.right;
+ double bEnd = endVal.bottom;
+ _delta = new Rect.fromLTRB(lEnd - lStart, tEnd - tStart, rEnd - rStart, bEnd - bStart);
} else if (startVal is double) {
+ // Double
_delta = endVal - startVal;
} else if (startVal is Color) {
+ // Color
int aDelta = endVal.alpha - startVal.alpha;
int rDelta = endVal.red - startVal.red;
int gDelta = endVal.green - startVal.green;
@@ -208,6 +341,24 @@ class ActionTween extends ActionInterval {
double xDelta = _delta.x;
double yDelta = _delta.y;
newVal = new Point(xStart + xDelta * t, yStart + yDelta * t);
+ } else if (startVal is Size) {
+ // Size
+ double wStart = startVal.width;
+ double hStart = startVal.height;
+ double wDelta = _delta.width;
+ double hDelta = _delta.height;
+ newVal = new Size(wStart + wDelta * t, hStart + hDelta * t);
+ } else if (startVal is Rect) {
+ // Rect
+ double lStart = startVal.left;
+ double tStart = startVal.top;
+ double rStart = startVal.right;
+ double bStart = startVal.bottom;
+ double lDelta = _delta.left;
+ double tDelta = _delta.top;
+ double rDelta = _delta.right;
+ double bDelta = _delta.bottom;
+ newVal = new Rect.fromLTRB(lStart + lDelta * t, tStart + tDelta * t, rStart + rDelta * t, bStart + bDelta * t);
} else if (startVal is double) {
// Doubles
newVal = startVal + _delta * t;
@@ -234,27 +385,41 @@ class ActionController {
ActionController();
void run(Action action, [Object tag]) {
+ assert(!action._added);
+
action._tag = tag;
+ action._added = true;
action.update(0.0);
_actions.add(action);
}
void stop(Action action) {
- _actions.remove(action);
+ if (_actions.remove(action)) {
+ action._added = false;
+ action._reset();
+ }
+ }
+
+ void _stopAtIndex(int i) {
+ Action action = _actions[i];
+ action._added = false;
+ action._reset();
+ _actions.removeAt(i);
}
void stopWithTag(Object tag) {
for (int i = _actions.length - 1; i >= 0; i--) {
Action action = _actions[i];
if (action._tag == tag) {
- _actions.removeAt(i);
- print("removing tag: $tag");
+ _stopAtIndex(i);
}
}
}
void stopAll() {
- _actions.clear();
+ for (int i = _actions.length - 1; i >= 0; i--) {
+ _stopAtIndex(i);
+ }
}
void step(double dt) {
@@ -263,6 +428,7 @@ class ActionController {
action.step(dt);
if (action._finished) {
+ action._added = false;
_actions.removeAt(i);
}
}
@@ -276,4 +442,29 @@ class _ColorDiff {
final int blue;
_ColorDiff(this.alpha, this.red, this.green, this.blue);
-}
+}
+
+double _bounce(double t)
+{
+ if (t < 1.0 / 2.75) {
+ return 7.5625 * t * t;
+ } else if (t < 2 / 2.75) {
+ t -= 1.5 / 2.75;
+ return 7.5625 * t * t + 0.75;
+ } else if (t < 2.5 / 2.75) {
+ t -= 2.25 / 2.75;
+ return 7.5625 * t * t + 0.9375;
+ }
+ t -= 2.625 / 2.75;
+ return 7.5625 * t * t + 0.984375;
+}
+
+class BounceOutCurve implements Curve {
+ const BounceOutCurve();
+
+ double transform(double t) {
+ return _bounce(t);
+ }
+}
+
+const BounceOutCurve bounceOut = const BounceOutCurve();
« no previous file with comments | « no previous file | sky/sdk/example/game/lib/sprite_box.dart » ('j') | sky/sdk/example/game/lib/sprites.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698