Index: sky/examples/game/lib/transform_node.dart |
diff --git a/sky/examples/game/lib/transform_node.dart b/sky/examples/game/lib/transform_node.dart |
index 199ca55f80719ce0d06f337c159b0415f1416fb5..07c08b6233dad84ed27b9996cfd719f4421f10a5 100644 |
--- a/sky/examples/game/lib/transform_node.dart |
+++ b/sky/examples/game/lib/transform_node.dart |
@@ -5,6 +5,12 @@ double degrees2radians(double degrees) => degrees * Math.PI/180.8; |
double radians2degrees(double radians) => radians * 180.0/Math.PI; |
class TransformNode { |
+ |
+ // Member variables |
+ |
+ SpriteBox _spriteBox; |
+ TransformNode _parent; |
+ |
Vector2 _position; |
double _rotation; |
@@ -14,11 +20,22 @@ class TransformNode { |
double _width; |
double _height; |
+ |
+ double _scaleX; |
+ double _scaleY; |
Vector2 _pivot; |
- |
- List<TransformNode>children; |
- |
+ |
+ bool visible; |
+ |
+ double _zPosition; |
+ int _addedOrder; |
+ int _childrenLastAddedOrder; |
+ bool _childrenNeedSorting; |
+ |
+ List<TransformNode>_children; |
+ |
+ // Constructors |
TransformNode() { |
_width = 0.0; |
@@ -26,11 +43,21 @@ class TransformNode { |
_rotation = 0.0; |
_pivot = new Vector2(0.0, 0.0); |
_position = new Vector2(0.0, 0.0); |
+ _scaleX = _scaleY = 1.0; |
_isMatrixDirty = false; |
_transform = new Matrix3.identity(); |
_pivotTransform = new Matrix3.identity(); |
- children = []; |
+ _children = []; |
+ _childrenNeedSorting = false; |
+ _childrenLastAddedOrder = 0; |
+ visible = true; |
} |
+ |
+ // Property setters and getters |
+ |
+ SpriteBox get spriteBox => _spriteBox; |
+ |
+ TransformNode get parent => _parent; |
double get rotation => _rotation; |
@@ -38,8 +65,7 @@ class TransformNode { |
_rotation = rotation; |
_isMatrixDirty = true; |
} |
- |
- |
+ |
Vector2 get position => _position; |
void set position(Vector2 position) { |
@@ -54,7 +80,6 @@ class TransformNode { |
_isMatrixDirty = true; |
} |
- |
double get height => _height; |
void set height(double height) { |
@@ -68,7 +93,63 @@ class TransformNode { |
_pivot = pivot; |
_isMatrixDirty = true; |
} |
- |
+ |
+ double get zPosition => _zPosition; |
+ |
+ void set zPosition(double zPosition) { |
+ _zPosition = zPosition; |
+ if (_parent != null) { |
+ _parent._childrenNeedSorting = true; |
+ } |
+ } |
+ |
+ double get scale { |
+ assert(_scaleX == _scaleY); |
+ return _scaleX; |
+ } |
+ |
+ void set scale(double scale) { |
+ _scaleX = _scaleY = scale; |
+ _isMatrixDirty = true; |
+ } |
+ |
+ List<TransformNode> get children => _children; |
+ |
+ // Adding and removing children |
+ |
+ void addChild(TransformNode child) { |
+ assert(child._parent == null); |
+ |
+ _childrenNeedSorting = true; |
+ _children.add(child); |
+ child._parent = this; |
+ child._spriteBox = this._spriteBox; |
+ _childrenLastAddedOrder += 1; |
+ child._addedOrder = _childrenLastAddedOrder; |
+ } |
+ |
+ void removeChild(TransformNode child) { |
+ if (_children.remove(child)) { |
+ child._parent = null; |
+ child._spriteBox = null; |
+ } |
+ } |
+ |
+ void removeFromParent() { |
+ assert(_parent != null); |
+ _parent.removeFromParent(); |
+ } |
+ |
+ void removeAllChildren() { |
+ for (TransformNode child in _children) { |
+ child._parent = null; |
+ child._spriteBox = null; |
+ } |
+ _children = []; |
+ _childrenNeedSorting = false; |
+ } |
+ |
+ // Calculating the transformation matrix |
Matrix3 get transformMatrix { |
if (!_isMatrixDirty) { |
@@ -111,8 +192,12 @@ class TransformNode { |
return _transform; |
} |
+ |
+ // Rendering |
void visit(PictureRecorder canvas) { |
+ if (!visible) return; |
+ |
prePaint(canvas); |
paint(canvas); |
visitChildren(canvas); |
@@ -124,6 +209,7 @@ class TransformNode { |
canvas.translate(_position[0], _position[1]); |
canvas.rotate(degrees2radians(_rotation)); |
+ canvas.scale(_scaleX, _scaleY); |
canvas.translate(-_width*_pivot[0], -_height*_pivot[1]); |
// TODO: Use transformation matrix instead of individual calls |
@@ -137,14 +223,33 @@ class TransformNode { |
} |
void visitChildren(PictureRecorder canvas) { |
- children.forEach((child) => child.visit(canvas)); |
+ // Sort children primarily by zPosition, secondarily by added order |
+ if (_childrenNeedSorting) { |
+ _children.sort((TransformNode a, TransformNode b) { |
+ if (a._zPosition == b._zPosition) { |
+ return b._addedOrder - a._addedOrder; |
+ } |
+ else if (a._zPosition > b._zPosition) { |
+ return 1; |
+ } |
+ else { |
+ return -1; |
+ } |
+ }); |
+ _childrenNeedSorting = false; |
+ } |
+ |
+ // Visit each child |
+ _children.forEach((child) => child.visit(canvas)); |
} |
void postPaint(PictureRecorder canvas) { |
canvas.restore(); |
} |
+ // Receiving update calls |
+ |
void update(double dt) { |
} |
-} |
+} |