提交 8647cbd7 编写于 作者: V Viktor Lidholt

Adds action classes

Refactors clamp function

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/1215413002.
上级 24620282
part of sprites;
typedef void PointSetter(Point point);
abstract class Action {
bool _finished = false;
void step(double dt);
void update(double t) {
}
}
abstract class ActionInterval extends Action {
double _duration;
bool _firstTick = true;
double _elapsed = 0.0;
double get duration => _duration;
ActionInterval([this._duration = 0.0]);
void step(double dt) {
if (_firstTick) {
_firstTick = false;
} else {
_elapsed += dt;
}
double t;
if (this._duration == 0.0) {
t = 1.0;
} else {
t = (_elapsed / _duration).clamp(0.0, 1.0);
}
update(t);
if (t >= 1.0) _finished = true;
}
}
class ActionRepeat extends ActionInterval {
final int numRepeats;
final ActionInterval action;
ActionRepeat(this.action, this.numRepeats) {
_duration = action.duration * numRepeats;
}
void update(double t) {
action.update((t * numRepeats.toDouble()) % numRepeats.toDouble());
}
}
// TODO: Implement
class ActionSequence extends ActionInterval {
final List<ActionInterval> actions;
ActionSequence(this.actions) {
for (Action action in actions) {
_duration += action._duration;
}
}
}
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;
final endVal;
var _delta;
ActionTween(this.setter, this.startVal, this.endVal, double duration) : super(duration) {
_computeDelta();
}
void _computeDelta() {
if (startVal is 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 double) {
_delta = endVal - startVal;
} else {
assert(false);
}
}
void update(double t) {
var newVal;
if (startVal is Point) {
double xStart = startVal.x;
double yStart = startVal.y;
double xDelta = _delta.x;
double yDelta = _delta.y;
newVal = new Point(xStart + xDelta * t, yStart + yDelta * t);
} else if (startVal is double) {
newVal = startVal + _delta * t;
} else {
assert(false);
}
setter(newVal);
}
}
class ActionController {
List<Action> _actions = [];
ActionController();
void run(Action action) {
_actions.add(action);
}
void step(double dt) {
for (int i = _actions.length - 1; i >= 0; i--) {
Action action = _actions[i];
action.step(dt);
if (action._finished) {
_actions.removeAt(i);
}
}
}
}
\ No newline at end of file
......@@ -32,21 +32,15 @@ class ColorSequence {
int gDelta = ((rand.nextDouble() * 2.0 - 1.0) * greenVar).toInt();
int bDelta = ((rand.nextDouble() * 2.0 - 1.0) * blueVar).toInt();
int aNew = _clamp(color.alpha + aDelta, 0, 255);
int rNew = _clamp(color.red + rDelta, 0, 255);
int gNew = _clamp(color.green + gDelta, 0, 255);
int bNew = _clamp(color.blue + bDelta, 0, 255);
int aNew = (color.alpha + aDelta).clamp(0, 255);
int rNew = (color.red + rDelta).clamp(0, 255);
int gNew = (color.green + gDelta).clamp(0, 255);
int bNew = (color.blue + bDelta).clamp(0, 255);
colors.add(new Color.fromARGB(aNew, rNew, gNew, bNew));
}
}
int _clamp(int val, int min, int max) {
if (val < min) return min;
if (val > max) return max;
return val;
}
Color colorAtPosition(double pos) {
assert(pos >= 0.0 && pos <= 1.0);
......
......@@ -303,6 +303,12 @@ class Asteroid extends Sprite {
_rand.nextDouble() * _maxAsteroidSpeed * 2 - _maxAsteroidSpeed);
userInteractionEnabled = true;
// Rotate forever
double direction = (_rand.nextBool()) ? 360.0 : -360.0;
ActionTween rot = new ActionTween( (a) => rotation = a, 0.0, direction, 2.0 * _rand.nextDouble() + 2.0);
ActionRepeatForever repeat = new ActionRepeatForever(rot);
actions.run(repeat);
}
bool handleEvent(SpriteBoxEvent event) {
......
......@@ -59,6 +59,15 @@ class Node {
List<Node>_children = [];
ActionController _actions;
ActionController get actions {
if (_actions == null) {
_actions = new ActionController();
}
return _actions;
}
// Constructors
/// Creates a new [Node] without any transformation.
......
......@@ -287,10 +287,21 @@ class SpriteBox extends RenderBox {
// Print frame rate
if (_numFrames % 60 == 0) print("delta: $delta fps: $_frameRate");
_runActions(_rootNode, delta);
_callUpdate(_rootNode, delta);
_scheduleTick();
}
void _runActions(Node node, double dt) {
if (node._actions != null) {
node._actions.step(dt);
}
for (int i = node.children.length - 1; i >= 0; i--) {
Node child = node.children[i];
_runActions(child, dt);
}
}
void _callUpdate(Node node, double dt) {
node.update(dt);
for (int i = node.children.length - 1; i >= 0; i--) {
......
......@@ -21,3 +21,5 @@ part 'texture.dart';
part 'spritesheet.dart';
part 'particle_system.dart';
part 'color_secuence.dart';
part 'action.dart';
part 'util.dart';
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册