Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 part of sprites; | 1 part of sprites; |
| 2 | 2 |
| 3 double convertDegrees2Radians(double degrees) => degrees * Math.PI/180.8; | 3 double convertDegrees2Radians(double degrees) => degrees * Math.PI/180.8; |
| 4 | 4 |
| 5 double convertRadians2Degrees(double radians) => radians * 180.0/Math.PI; | 5 double convertRadians2Degrees(double radians) => radians * 180.0/Math.PI; |
| 6 | 6 |
| 7 /// A base class for all objects that can be added to the sprite node tree and r endered to screen using [SpriteBox] and | |
| 8 /// [SpriteWidget]. | |
| 9 /// | |
| 10 /// The [Node] class itself doesn't render any content, but provides the basic f unctions of any type of node, such as | |
| 11 /// handling transformations and user input. To render the node tree, a root nod e must be added to a [SpriteBox] or a | |
| 12 /// [SpriteWidget]. Commonly used sub-classes of [Node] are [Sprite], [NodeWithS ize], and many more upcoming subclasses. | |
| 13 /// | |
| 14 /// Nodes form a hierarchical tree. Each node can have a number of children, and the transformation (positioning, | |
| 15 /// rotation, and scaling) of a node also affects its children. | |
| 7 class Node { | 16 class Node { |
| 8 | 17 |
| 9 // Member variables | 18 // Member variables |
| 10 | 19 |
| 11 SpriteBox _spriteBox; | 20 SpriteBox _spriteBox; |
| 12 Node _parent; | 21 Node _parent; |
| 13 | 22 |
| 14 Point _position; | 23 Point _position = Point.origin; |
| 15 double _rotation; | 24 double _rotation = 0.0; |
| 16 | 25 |
| 17 Matrix4 _transformMatrix; | 26 Matrix4 _transformMatrix = new Matrix4.identity(); |
| 18 Matrix4 _transformMatrixNodeToBox; | 27 Matrix4 _transformMatrixNodeToBox; |
| 19 Matrix4 _transformMatrixBoxToNode; | 28 Matrix4 _transformMatrixBoxToNode; |
| 20 | 29 |
| 21 double _scaleX; | 30 double _scaleX = 1.0; |
| 22 double _scaleY; | 31 double _scaleY = 1.0; |
| 23 | 32 |
| 24 bool visible; | 33 /// The visibility of this node and its children. |
| 34 bool visible = true; | |
| 25 | 35 |
| 26 double _zPosition; | 36 double _zPosition = 0.0; |
| 27 int _addedOrder; | 37 int _addedOrder; |
| 28 int _childrenLastAddedOrder; | 38 int _childrenLastAddedOrder = 0; |
| 29 bool _childrenNeedSorting; | 39 bool _childrenNeedSorting = false; |
| 30 | 40 |
| 41 /// Decides if the node and its children is currently paused. | |
| 42 /// | |
| 43 /// A paused node will not receive any input events, update calls, or run any animations. | |
| 44 /// | |
| 45 /// myNodeTree.paused = true; | |
| 31 bool paused = false; | 46 bool paused = false; |
| 32 | 47 |
| 33 bool _userInteractionEnabled = false; | 48 bool _userInteractionEnabled = false; |
| 49 | |
| 50 /// If set to true the node will receive multiple pointers, otherwise it will only receive events the first pointer. | |
| 51 /// | |
| 52 /// This property is only meaningful if [userInteractionEnabled] is set to tru e. Default value is false. | |
| 53 /// | |
| 54 /// class MyCustomNode extends Node { | |
| 55 /// handleMultiplePointers = true; | |
| 56 /// } | |
| 34 bool handleMultiplePointers = false; | 57 bool handleMultiplePointers = false; |
| 35 int _handlingPointer; | 58 int _handlingPointer; |
| 36 | 59 |
| 37 List<Node>_children; | 60 List<Node>_children = []; |
| 38 | 61 |
| 39 // Constructors | 62 // Constructors |
| 40 | 63 |
| 64 /// Creates a new [Node] without any transformation. | |
| 65 /// | |
| 66 /// var myNode = new Node(); | |
| 41 Node() { | 67 Node() { |
| 42 _rotation = 0.0; | |
| 43 _position = Point.origin; | |
| 44 _scaleX = _scaleY = 1.0; | |
| 45 _transformMatrix = new Matrix4.identity(); | |
| 46 _children = []; | |
| 47 _childrenNeedSorting = false; | |
| 48 _childrenLastAddedOrder = 0; | |
| 49 _zPosition = 0.0; | |
| 50 visible = true; | |
| 51 } | 68 } |
| 52 | 69 |
| 53 // Property setters and getters | 70 // Property setters and getters |
| 54 | 71 |
| 72 /// The [SpriteBox] this node is added to, or null if it's not currently added to a [SpriteBox]. | |
| 73 /// | |
| 74 /// For most applications it's not necessary to access the [SpriteBox] directl y. | |
| 75 /// | |
| 76 /// // Get the transformMode of the sprite box | |
| 77 /// var transformMode = myNode.spriteBox.transformMode; | |
| 55 SpriteBox get spriteBox => _spriteBox; | 78 SpriteBox get spriteBox => _spriteBox; |
| 56 | 79 |
| 80 /// The parent of this node, or null if it doesn't have a parent. | |
| 81 /// | |
| 82 /// // Hide the parent | |
| 83 /// myNode.parent.visible = false; | |
| 57 Node get parent => _parent; | 84 Node get parent => _parent; |
| 58 | 85 |
| 86 /// The rotation of this node in degrees. | |
| 87 /// | |
| 88 /// myNode.rotation = 45.0; | |
| 59 double get rotation => _rotation; | 89 double get rotation => _rotation; |
| 60 | 90 |
| 61 void set rotation(double rotation) { | 91 void set rotation(double rotation) { |
| 62 assert(rotation != null); | 92 assert(rotation != null); |
| 63 _rotation = rotation; | 93 _rotation = rotation; |
| 64 _invalidateTransformMatrix(); | 94 _invalidateTransformMatrix(); |
| 65 } | 95 } |
| 66 | 96 |
| 97 /// The position of this node relative to its parent. | |
| 98 /// | |
| 99 /// myNode.position = new Point(42.0, 42.0); | |
| 67 Point get position => _position; | 100 Point get position => _position; |
| 68 | 101 |
| 69 void set position(Point position) { | 102 void set position(Point position) { |
| 70 assert(position != null); | 103 assert(position != null); |
| 71 _position = position; | 104 _position = position; |
| 72 _invalidateTransformMatrix(); | 105 _invalidateTransformMatrix(); |
| 73 } | 106 } |
| 74 | 107 |
| 108 /// The draw order of this node compared to its parent and its siblings. | |
| 109 /// | |
| 110 /// By default nodes are drawn in the order that they have been added to a par ent. To override this behavior the | |
| 111 /// [zPosition] property can be used. A higher value of this property will for ce the node to be drawn in front of | |
| 112 /// siblings that have a lower value. If a negative value is used the node wil l be drawn behind its parent. | |
| 113 /// | |
| 114 /// nodeInFront.zPosition = 1.0; | |
| 115 /// nodeBehind.zPosition = -1.0; | |
| 75 double get zPosition => _zPosition; | 116 double get zPosition => _zPosition; |
| 76 | 117 |
| 77 void set zPosition(double zPosition) { | 118 void set zPosition(double zPosition) { |
| 78 assert(zPosition != null); | 119 assert(zPosition != null); |
| 79 _zPosition = zPosition; | 120 _zPosition = zPosition; |
| 80 if (_parent != null) { | 121 if (_parent != null) { |
| 81 _parent._childrenNeedSorting = true; | 122 _parent._childrenNeedSorting = true; |
| 82 } | 123 } |
| 83 } | 124 } |
| 84 | 125 |
| 126 /// The scale of this node relative its parent. | |
| 127 /// | |
| 128 /// The [scale] property is only valid if [scaleX] and [scaleY] are equal valu es. | |
| 129 /// | |
| 130 /// myNode.scale = 5.0; | |
| 85 double get scale { | 131 double get scale { |
| 86 assert(_scaleX == _scaleY); | 132 assert(_scaleX == _scaleY); |
| 87 return _scaleX; | 133 return _scaleX; |
| 88 } | 134 } |
| 89 | 135 |
| 90 void set scale(double scale) { | 136 void set scale(double scale) { |
| 91 assert(scale != null); | 137 assert(scale != null); |
| 92 _scaleX = _scaleY = scale; | 138 _scaleX = _scaleY = scale; |
| 93 _invalidateTransformMatrix(); | 139 _invalidateTransformMatrix(); |
| 94 } | 140 } |
| 95 | 141 |
| 142 /// The horizontal scale of this node relative its parent. | |
| 143 /// | |
| 144 /// myNode.scaleX = 5.0; | |
| 96 double get scaleX => _scaleX; | 145 double get scaleX => _scaleX; |
| 97 | 146 |
| 98 void set scaleX(double scaleX) { | 147 void set scaleX(double scaleX) { |
| 99 assert(scaleX != null); | 148 assert(scaleX != null); |
| 100 _scaleX = scaleX; | 149 _scaleX = scaleX; |
| 101 _invalidateTransformMatrix(); | 150 _invalidateTransformMatrix(); |
| 102 } | 151 } |
| 103 | 152 |
| 153 /// The vertical scale of this node relative its parent. | |
| 154 /// | |
| 155 /// myNode.scaleY = 5.0; | |
| 104 double get scaleY => _scaleY; | 156 double get scaleY => _scaleY; |
| 105 | 157 |
| 106 void set scaleY(double scaleY) { | 158 void set scaleY(double scaleY) { |
| 107 assert(scaleY != null); | 159 assert(scaleY != null); |
| 108 _scaleY = scaleY; | 160 _scaleY = scaleY; |
| 109 _invalidateTransformMatrix(); | 161 _invalidateTransformMatrix(); |
| 110 } | 162 } |
| 111 | 163 |
| 164 /// A list of the children of this node. | |
| 165 /// | |
| 166 /// This list should only be modified by using the [addChild] and [removeChild ] methods. | |
| 167 /// | |
| 168 /// // Iterate over a nodes children | |
| 169 /// for (Node child in myNode.children) { | |
| 170 /// // Do something with the child | |
| 171 /// } | |
| 112 List<Node> get children { | 172 List<Node> get children { |
| 113 _sortChildren(); | 173 _sortChildren(); |
| 114 return _children; | 174 return _children; |
| 115 } | 175 } |
| 116 | 176 |
| 117 // Adding and removing children | 177 // Adding and removing children |
| 118 | 178 |
| 179 /// Adds a child to this node. | |
| 180 /// | |
| 181 /// The same node cannot be added to multiple nodes. | |
| 182 /// | |
| 183 /// addChild(new Sprite(myImage)); | |
| 119 void addChild(Node child) { | 184 void addChild(Node child) { |
| 120 assert(child != null); | 185 assert(child != null); |
| 121 assert(child._parent == null); | 186 assert(child._parent == null); |
| 122 | 187 |
| 123 _childrenNeedSorting = true; | 188 _childrenNeedSorting = true; |
| 124 _children.add(child); | 189 _children.add(child); |
| 125 child._parent = this; | 190 child._parent = this; |
| 126 child._spriteBox = this._spriteBox; | 191 child._spriteBox = this._spriteBox; |
| 127 _childrenLastAddedOrder += 1; | 192 _childrenLastAddedOrder += 1; |
| 128 child._addedOrder = _childrenLastAddedOrder; | 193 child._addedOrder = _childrenLastAddedOrder; |
| 129 if (_spriteBox != null) _spriteBox._eventTargets = null; | 194 if (_spriteBox != null) _spriteBox._eventTargets = null; |
| 130 } | 195 } |
| 131 | 196 |
| 197 /// Removes a child from this node. | |
| 198 /// | |
| 199 /// removeChild(myChildNode); | |
| 132 void removeChild(Node child) { | 200 void removeChild(Node child) { |
| 133 assert(child != null); | 201 assert(child != null); |
| 134 if (_children.remove(child)) { | 202 if (_children.remove(child)) { |
| 135 child._parent = null; | 203 child._parent = null; |
| 136 child._spriteBox = null; | 204 child._spriteBox = null; |
| 137 if (_spriteBox != null) _spriteBox._eventTargets = null; | 205 if (_spriteBox != null) _spriteBox._eventTargets = null; |
| 138 } | 206 } |
| 139 } | 207 } |
| 140 | 208 |
| 209 /// Removes this node from its parent node. | |
| 210 /// | |
| 211 /// removeFromParent(); | |
| 141 void removeFromParent() { | 212 void removeFromParent() { |
| 142 assert(_parent != null); | 213 assert(_parent != null); |
| 143 _parent.removeChild(this); | 214 _parent.removeChild(this); |
| 144 } | 215 } |
| 145 | 216 |
| 217 /// Removes all children of this node. | |
| 218 /// | |
| 219 /// removeAllChildren(); | |
| 146 void removeAllChildren() { | 220 void removeAllChildren() { |
| 147 for (Node child in _children) { | 221 for (Node child in _children) { |
| 148 child._parent = null; | 222 child._parent = null; |
| 149 child._spriteBox = null; | 223 child._spriteBox = null; |
| 150 } | 224 } |
| 151 _children = []; | 225 _children = []; |
| 152 _childrenNeedSorting = false; | 226 _childrenNeedSorting = false; |
| 153 if (_spriteBox != null) _spriteBox._eventTargets = null; | 227 if (_spriteBox != null) _spriteBox._eventTargets = null; |
| 154 } | 228 } |
| 155 | 229 |
| 156 void _sortChildren() { | 230 void _sortChildren() { |
| 157 // Sort children primarily by zPosition, secondarily by added order | 231 // Sort children primarily by zPosition, secondarily by added order |
| 158 if (_childrenNeedSorting) { | 232 if (_childrenNeedSorting) { |
| 159 _children.sort((Node a, Node b) { | 233 _children.sort((Node a, Node b) { |
| 160 if (a._zPosition == b._zPosition) { | 234 if (a._zPosition == b._zPosition) { |
| 161 return a._addedOrder - b._addedOrder; | 235 return a._addedOrder - b._addedOrder; |
| 162 } | 236 } |
| 163 else if (a._zPosition > b._zPosition) { | 237 else if (a._zPosition > b._zPosition) { |
| 164 return 1; | 238 return 1; |
| 165 } | 239 } |
| 166 else { | 240 else { |
| 167 return -1; | 241 return -1; |
| 168 } | 242 } |
| 169 }); | 243 }); |
| 170 _childrenNeedSorting = false; | 244 _childrenNeedSorting = false; |
| 171 } | 245 } |
| 172 } | 246 } |
| 173 | 247 |
| 174 // Calculating the transformation matrix | 248 // Calculating the transformation matrix |
| 175 | 249 |
| 250 /// The transformMatrix describes the transformation from the node's parent. | |
| 251 /// | |
| 252 /// You cannot set the transformMatrix directly, instead use the position, rot ation and scale properties. | |
| 253 /// | |
| 254 /// Matrix4 matrix = myNode.transformMatrix; | |
| 176 Matrix4 get transformMatrix { | 255 Matrix4 get transformMatrix { |
| 177 if (_transformMatrix != null) { | 256 if (_transformMatrix != null) { |
| 178 return _transformMatrix; | 257 return _transformMatrix; |
| 179 } | 258 } |
| 180 | 259 |
| 181 double cx, sx, cy, sy; | 260 double cx, sx, cy, sy; |
| 182 | 261 |
| 183 if (_rotation == 0.0) { | 262 if (_rotation == 0.0) { |
| 184 cx = 1.0; | 263 cx = 1.0; |
| 185 sx = 0.0; | 264 sx = 0.0; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 if (_transformMatrixBoxToNode != null) { | 323 if (_transformMatrixBoxToNode != null) { |
| 245 return _transformMatrixBoxToNode; | 324 return _transformMatrixBoxToNode; |
| 246 } | 325 } |
| 247 | 326 |
| 248 _transformMatrixBoxToNode = new Matrix4.copy(_nodeToBoxMatrix()); | 327 _transformMatrixBoxToNode = new Matrix4.copy(_nodeToBoxMatrix()); |
| 249 _transformMatrixBoxToNode.invert(); | 328 _transformMatrixBoxToNode.invert(); |
| 250 | 329 |
| 251 return _transformMatrixBoxToNode; | 330 return _transformMatrixBoxToNode; |
| 252 } | 331 } |
| 253 | 332 |
| 333 /// Converts a point from the coordinate system of the [SpriteBox] to the loca l coordinate system of the node. | |
| 334 /// | |
| 335 /// This method is particularly useful when handling pointer events and need t he pointers position in a local | |
| 336 /// coordinate space. | |
| 337 /// | |
| 338 /// Point localPoint = myNode.convertPointToNodeSpace(pointInBoxCoordinate s); | |
| 254 Point convertPointToNodeSpace(Point boxPoint) { | 339 Point convertPointToNodeSpace(Point boxPoint) { |
| 255 assert(boxPoint != null); | 340 assert(boxPoint != null); |
| 256 assert(_spriteBox != null); | 341 assert(_spriteBox != null); |
| 257 | 342 |
| 258 Vector4 v =_boxToNodeMatrix().transform(new Vector4(boxPoint.x, boxPoint.y, 0.0, 1.0)); | 343 Vector4 v =_boxToNodeMatrix().transform(new Vector4(boxPoint.x, boxPoint.y, 0.0, 1.0)); |
| 259 return new Point(v[0], v[1]); | 344 return new Point(v[0], v[1]); |
| 260 } | 345 } |
| 261 | 346 |
| 347 /// Converts a point from the local coordinate system of the node to the coord inate system of the [SpriteBox]. | |
| 348 /// | |
| 349 /// Point pointInBoxCoordinates = myNode.convertPointToBoxSpace(localPoint ); | |
| 262 Point convertPointToBoxSpace(Point nodePoint) { | 350 Point convertPointToBoxSpace(Point nodePoint) { |
| 263 assert(nodePoint != null); | 351 assert(nodePoint != null); |
| 264 assert(_spriteBox != null); | 352 assert(_spriteBox != null); |
| 265 | 353 |
| 266 Vector4 v =_nodeToBoxMatrix().transform(new Vector4(nodePoint.x, nodePoint.y , 0.0, 1.0)); | 354 Vector4 v =_nodeToBoxMatrix().transform(new Vector4(nodePoint.x, nodePoint.y , 0.0, 1.0)); |
| 267 return new Point(v[0], v[1]); | 355 return new Point(v[0], v[1]); |
| 268 } | 356 } |
| 269 | 357 |
| 358 /// Converts a [point] from another [node]s coordinate system into the local c oordinate system of this node. | |
| 359 /// | |
| 360 /// Point pointInNodeASpace = nodeA.convertPointFromNode(pointInNodeBSpace , nodeB); | |
| 270 Point convertPointFromNode(Point point, Node node) { | 361 Point convertPointFromNode(Point point, Node node) { |
| 271 assert(node != null); | 362 assert(node != null); |
| 272 assert(point != null); | 363 assert(point != null); |
| 273 assert(_spriteBox != null); | 364 assert(_spriteBox != null); |
| 274 assert(_spriteBox == node._spriteBox); | 365 assert(_spriteBox == node._spriteBox); |
| 275 | 366 |
| 276 Point boxPoint = node.convertPointToBoxSpace(point); | 367 Point boxPoint = node.convertPointToBoxSpace(point); |
| 277 Point localPoint = convertPointToNodeSpace(boxPoint); | 368 Point localPoint = convertPointToNodeSpace(boxPoint); |
| 278 | 369 |
| 279 return localPoint; | 370 return localPoint; |
| 280 } | 371 } |
| 281 | 372 |
| 282 // Hit test | 373 // Hit test |
| 283 | 374 |
| 284 bool isPointInside(Point nodePoint) { | 375 /// Returns true if the [point] is inside the node, the [point] is in the loca l coordinate system of the node. |
| 285 assert(nodePoint != null); | 376 /// |
| 377 /// myNode.isPointInside(localPoint); | |
| 378 /// | |
| 379 /// [NodeWithSize] provides a basic bounding box check for this method, if you require a more detailed check this | |
| 380 /// method can be overridden. | |
| 381 /// | |
| 382 /// bool isPointInside (Point nodePoint) { | |
| 383 /// double minX = -size.width * pivot.x; | |
| 384 /// double minY = -size.height * pivot.y; | |
| 385 /// double maxX = minX + size.width; | |
| 386 /// double maxY = minY + size.height; | |
| 387 /// return (nodePoint.x >= minX && nodePoint.x < maxX && | |
| 388 /// nodePoint.y >= minY && nodePoint.y < maxY); | |
| 389 /// } | |
| 390 bool isPointInside(Point point) { | |
| 391 assert(point != null); | |
| 286 | 392 |
| 287 return false; | 393 return false; |
| 288 } | 394 } |
| 289 | 395 |
| 290 // Rendering | 396 // Rendering |
| 291 | 397 |
| 292 void _visit(PictureRecorder canvas) { | 398 void _visit(PictureRecorder canvas) { |
| 293 assert(canvas != null); | 399 assert(canvas != null); |
| 294 if (!visible) return; | 400 if (!visible) return; |
| 295 | 401 |
| 296 _prePaint(canvas); | 402 _prePaint(canvas); |
| 297 _visitChildren(canvas); | 403 _visitChildren(canvas); |
| 298 _postPaint(canvas); | 404 _postPaint(canvas); |
| 299 } | 405 } |
| 300 | 406 |
| 301 void _prePaint(PictureRecorder canvas) { | 407 void _prePaint(PictureRecorder canvas) { |
| 302 canvas.save(); | 408 canvas.save(); |
| 303 | 409 |
| 304 // Get the transformation matrix and apply transform | 410 // Get the transformation matrix and apply transform |
| 305 canvas.concat(transformMatrix.storage); | 411 canvas.concat(transformMatrix.storage); |
| 306 } | 412 } |
| 307 | 413 |
| 414 /// Paints this node to the canvas. | |
| 415 /// | |
| 416 /// Subclasses, such as [Sprite], override this method to do the actual painti ng of the node. To do custom | |
| 417 /// drawing override this method and make calls to the [canvas] object. All dr awing is done in the node's local | |
| 418 /// coordinate system, relative to the node's position. If you want to make th e drawing relative to the node's | |
| 419 /// bounding box's origin, override [NodeWithSize] and call the applyTransform ForPivot method before making calls for | |
| 420 /// drawing. | |
| 421 /// | |
| 422 /// void paint(PictureRecorder canvas) { | |
| 423 /// canvas.save(); | |
| 424 /// applyTransformForPivot(canvas); | |
|
Hixie
2015/06/22 17:08:42
note that save/transform/restore is expensive (exp
| |
| 425 /// | |
| 426 /// // Do painting here | |
| 427 /// | |
| 428 /// canvas.restore(); | |
| 429 /// } | |
| 308 void paint(PictureRecorder canvas) { | 430 void paint(PictureRecorder canvas) { |
| 309 } | 431 } |
| 310 | 432 |
| 311 void _visitChildren(PictureRecorder canvas) { | 433 void _visitChildren(PictureRecorder canvas) { |
| 312 // Sort children if needed | 434 // Sort children if needed |
| 313 _sortChildren(); | 435 _sortChildren(); |
| 314 | 436 |
| 315 int i = 0; | 437 int i = 0; |
| 316 | 438 |
| 317 // Visit children behind this node | 439 // Visit children behind this node |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 332 i++; | 454 i++; |
| 333 } | 455 } |
| 334 } | 456 } |
| 335 | 457 |
| 336 void _postPaint(PictureRecorder canvas) { | 458 void _postPaint(PictureRecorder canvas) { |
| 337 canvas.restore(); | 459 canvas.restore(); |
| 338 } | 460 } |
| 339 | 461 |
| 340 // Receiving update calls | 462 // Receiving update calls |
| 341 | 463 |
| 464 /// Called before a frame is drawn. | |
| 465 /// | |
| 466 /// Override this method to do any updates to the node or node tree before it' s drawn to screen. | |
| 467 /// | |
| 468 /// // Make the node rotate at a fixed speed | |
| 469 /// void update(double dt) { | |
| 470 /// rotation = rotation * 10.0 * dt; | |
| 471 /// } | |
| 342 void update(double dt) { | 472 void update(double dt) { |
| 343 } | 473 } |
| 344 | 474 |
| 475 /// Called whenever the [SpriteBox] is modified or resized, or if the device i s rotated. | |
| 476 /// | |
| 477 /// Override this method to do any updates that may be necessary to correctly display the node or node tree with the | |
| 478 /// new layout of the [SpriteBox]. | |
| 479 /// | |
| 480 /// void spriteBoxPerformedLayout() { | |
| 481 /// // Move some stuff around here | |
| 482 /// } | |
| 345 void spriteBoxPerformedLayout() { | 483 void spriteBoxPerformedLayout() { |
| 346 } | 484 } |
| 347 | 485 |
| 348 // Handling user interaction | 486 // Handling user interaction |
| 349 | 487 |
| 488 /// The node will receive user interactions, such as pointer (touch or mouse) events. | |
| 489 /// | |
| 490 /// class MyCustomNode extends NodeWithSize { | |
| 491 /// userInteractionEnabled = true; | |
| 492 /// } | |
| 350 bool get userInteractionEnabled => _userInteractionEnabled; | 493 bool get userInteractionEnabled => _userInteractionEnabled; |
| 351 | 494 |
| 352 void set userInteractionEnabled(bool userInteractionEnabled) { | 495 void set userInteractionEnabled(bool userInteractionEnabled) { |
| 353 _userInteractionEnabled = userInteractionEnabled; | 496 _userInteractionEnabled = userInteractionEnabled; |
| 354 if (_spriteBox != null) _spriteBox._eventTargets = null; | 497 if (_spriteBox != null) _spriteBox._eventTargets = null; |
| 355 } | 498 } |
| 356 | 499 |
| 500 /// Handles an event, such as a pointer (touch or mouse) event. | |
| 501 /// | |
| 502 /// Override this method to handle events. The node will only receive events i f the [userInteractionEnabled] property | |
| 503 /// is set to true and the [isPointInside] method returns true for the positio n of the pointer down event (default | |
| 504 /// behavior provided by [NodeWithSize]). Unless [handleMultiplePointers] is s et to true, the node will only receive | |
| 505 /// events for the first pointer that is down. | |
| 506 /// | |
| 507 /// Return true if the node has consumed the event, if an event is consumed it will not be passed on to nodes behind | |
| 508 /// the current node. | |
| 509 /// | |
| 510 /// // MyTouchySprite gets transparent when we touch it | |
| 511 /// class MyTouchySprite extends Sprite { | |
| 512 /// | |
| 513 /// MyTouchySprite(Image img) : super (img) { | |
| 514 /// userInteractionEnabled = true; | |
| 515 /// } | |
| 516 /// | |
| 517 /// bool handleEvent(SpriteBoxEvent event) { | |
| 518 /// if (event.type == 'pointerdown) { | |
| 519 /// opacity = 0.5; | |
| 520 /// } | |
| 521 /// else if (event.type == 'pointerup') { | |
| 522 /// opacity = 1.0; | |
| 523 /// } | |
| 524 /// return true; | |
| 525 /// } | |
| 526 /// } | |
| 357 bool handleEvent(SpriteBoxEvent event) { | 527 bool handleEvent(SpriteBoxEvent event) { |
| 358 return false; | 528 return false; |
| 359 } | 529 } |
| 360 } | 530 } |
| OLD | NEW |