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

Unified Diff: sky/examples/game/lib/sprite_box.dart

Issue 1218593002: Move sky/examples to sky/sdk/lib/example, and code changes to support that change. Fixes T277. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 6 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
Index: sky/examples/game/lib/sprite_box.dart
diff --git a/sky/examples/game/lib/sprite_box.dart b/sky/examples/game/lib/sprite_box.dart
deleted file mode 100644
index f3020316b9017cf292328d31ddffb5c288acba67..0000000000000000000000000000000000000000
--- a/sky/examples/game/lib/sprite_box.dart
+++ /dev/null
@@ -1,381 +0,0 @@
-part of sprites;
-
-/// Options for setting up a [SpriteBox].
-///
-/// * [nativePoints], use the same points as the parent [Widget].
-/// * [letterbox], use the size of the root node for the coordinate system, constrain the aspect ratio and trim off
-/// areas that end up outside the screen.
-/// * [stretch], use the size of the root node for the coordinate system, scale it to fit the size of the box.
-/// * [scaleToFit], similar to the letterbox option, but instead of trimming areas the sprite system will be scaled
-/// down to fit the box.
-/// * [fixedWidth], uses the width of the root node to set the size of the coordinate system, this option will change
-/// the height of the root node to fit the box.
-/// * [fixedHeight], uses the height of the root node to set the size of the coordinate system, this option will change
-/// the width of the root node to fit the box.
-enum SpriteBoxTransformMode {
- nativePoints,
- letterbox,
- stretch,
- scaleToFit,
- fixedWidth,
- fixedHeight,
-}
-
-class SpriteBox extends RenderBox {
-
- // Member variables
-
- // Root node for drawing
- NodeWithSize _rootNode;
-
- // Tracking of frame rate and updates
- double _lastTimeStamp;
- int _numFrames = 0;
- double _frameRate = 0.0;
-
- // Transformation mode
- SpriteBoxTransformMode _transformMode;
-
- /// The transform mode used by the [SpriteBox].
- SpriteBoxTransformMode get transformMode => _transformMode;
-
- // Cached transformation matrix
- Matrix4 _transformMatrix;
-
- List<Node> _eventTargets;
-
- // Setup
-
- /// Creates a new SpriteBox with a node as its content, by default uses letterboxing.
- ///
- /// The [rootNode] provides the content of the node tree, typically it's a custom subclass of [NodeWithSize]. The
- /// [mode] provides different ways to scale the content to best fit it to the screen. In most cases it's preferred to
- /// use a [SpriteWidget] that automatically wraps the SpriteBox.
- ///
- /// var spriteBox = new SpriteBox(myNode, SpriteBoxTransformMode.fixedHeight);
- SpriteBox(NodeWithSize rootNode, [SpriteBoxTransformMode mode = SpriteBoxTransformMode.letterbox]) {
- assert(rootNode != null);
- assert(rootNode._spriteBox == null);
-
- // Setup root node
- _rootNode = rootNode;
-
- // Assign SpriteBox reference to all the nodes
- _addSpriteBoxReference(_rootNode);
-
- // Setup transform mode
- _transformMode = mode;
-
- _scheduleTick();
- }
-
- void _addSpriteBoxReference(Node node) {
- node._spriteBox = this;
- for (Node child in node._children) {
- _addSpriteBoxReference(child);
- }
- }
-
- // Properties
-
- /// The root node of the node tree that is rendered by this box.
- ///
- /// var rootNode = mySpriteBox.rootNode;
- NodeWithSize get rootNode => _rootNode;
-
- void performLayout() {
- size = constraints.constrain(Size.infinite);
- _invalidateTransformMatrix();
- _callSpriteBoxPerformedLayout(_rootNode);
- }
-
- // Event handling
-
- void _addEventTargets(Node node, List<Node> eventTargets) {
- List children = node.children;
- int i = 0;
-
- // Add childrens that are behind this node
- while (i < children.length) {
- Node child = children[i];
- if (child.zPosition >= 0.0) break;
- _addEventTargets(child, eventTargets);
- i++;
- }
-
- // Add this node
- if (node.userInteractionEnabled) {
- eventTargets.add(node);
- }
-
- // Add children in front of this node
- while (i < children.length) {
- Node child = children[i];
- _addEventTargets(child, eventTargets);
- i++;
- }
- }
-
- void handleEvent(Event event, _SpriteBoxHitTestEntry entry) {
- if (event is PointerEvent) {
-
- if (event.type == 'pointerdown') {
- // Build list of event targets
- if (_eventTargets == null) {
- _eventTargets = [];
- _addEventTargets(_rootNode, _eventTargets);
- }
-
- // Find the once that are hit by the pointer
- List<Node> nodeTargets = [];
- for (int i = _eventTargets.length - 1; i >= 0; i--) {
- Node node = _eventTargets[i];
-
- // Check if the node is ready to handle a pointer
- if (node.handleMultiplePointers || node._handlingPointer == null) {
- // Do the hit test
- Point posInNodeSpace = node.convertPointToNodeSpace(entry.localPosition);
- if (node.isPointInside(posInNodeSpace)) {
- nodeTargets.add(node);
- node._handlingPointer = event.pointer;
- }
- }
- }
-
- entry.nodeTargets = nodeTargets;
- }
-
- // Pass the event down to nodes that were hit by the pointerdown
- List<Node> targets = entry.nodeTargets;
- for (Node node in targets) {
- // Check if this event should be dispatched
- if (node.handleMultiplePointers || event.pointer == node._handlingPointer) {
- // Dispatch event
- bool consumedEvent = node.handleEvent(new SpriteBoxEvent(new Point(event.x, event.y), event.type, event.pointer));
- if (consumedEvent == null || consumedEvent) break;
- }
- }
-
- // De-register pointer for nodes that doesn't handle multiple pointers
- for (Node node in targets) {
- if (event.type == 'pointerup' || event.type == 'pointercancel') {
- node._handlingPointer = null;
- }
- }
- }
- }
-
- bool hitTest(HitTestResult result, { Point position }) {
- result.add(new _SpriteBoxHitTestEntry(this, position));
- return true;
- }
-
- // Rendering
-
- /// The transformation matrix used to transform the root node to the space of the box.
- ///
- /// It's uncommon to need access to this property.
- ///
- /// var matrix = mySpriteBox.transformMatrix;
- Matrix4 get transformMatrix {
- // Get cached matrix if available
- if (_transformMatrix != null) {
- return _transformMatrix;
- }
-
- _transformMatrix = new Matrix4.identity();
-
- // Calculate matrix
- double scaleX = 1.0;
- double scaleY = 1.0;
- double offsetX = 0.0;
- double offsetY = 0.0;
-
- double systemWidth = rootNode.size.width;
- double systemHeight = rootNode.size.height;
-
- switch(_transformMode) {
- case SpriteBoxTransformMode.stretch:
- scaleX = size.width/systemWidth;
- scaleY = size.height/systemHeight;
- break;
- case SpriteBoxTransformMode.letterbox:
- scaleX = size.width/systemWidth;
- scaleY = size.height/systemHeight;
- if (scaleX > scaleY) {
- scaleY = scaleX;
- offsetY = (size.height - scaleY * systemHeight)/2.0;
- } else {
- scaleX = scaleY;
- offsetX = (size.width - scaleX * systemWidth)/2.0;
- }
- break;
- case SpriteBoxTransformMode.scaleToFit:
- scaleX = size.width/systemWidth;
- scaleY = size.height/systemHeight;
- if (scaleX < scaleY) {
- scaleY = scaleX;
- offsetY = (size.height - scaleY * systemHeight)/2.0;
- } else {
- scaleX = scaleY;
- offsetX = (size.width - scaleX * systemWidth)/2.0;
- }
- break;
- case SpriteBoxTransformMode.fixedWidth:
- scaleX = size.width/systemWidth;
- scaleY = scaleX;
- systemHeight = size.height/scaleX;
- rootNode.size = new Size(systemWidth, systemHeight);
- break;
- case SpriteBoxTransformMode.fixedHeight:
- scaleY = size.height/systemHeight;
- scaleX = scaleY;
- systemWidth = size.width/scaleY;
- rootNode.size = new Size(systemWidth, systemHeight);
- break;
- case SpriteBoxTransformMode.nativePoints:
- break;
- default:
- assert(false);
- break;
- }
-
- _transformMatrix.translate(offsetX, offsetY);
- _transformMatrix.scale(scaleX, scaleY);
-
- return _transformMatrix;
- }
-
- void _invalidateTransformMatrix() {
- _transformMatrix = null;
- _rootNode._invalidateToBoxTransformMatrix();
- }
-
- void paint(RenderCanvas canvas) {
- canvas.save();
-
- // Move to correct coordinate space before drawing
- canvas.concat(transformMatrix.storage);
-
- // Draw the sprite tree
- _rootNode._visit(canvas);
-
- canvas.restore();
- }
-
- // Updates
-
- int _animationId = 0;
-
- void _scheduleTick() {
- _animationId = scheduler.requestAnimationFrame(_tick);
- }
-
- void _tick(double timeStamp) {
-
- // Calculate the time between frames in seconds
- if (_lastTimeStamp == null) _lastTimeStamp = timeStamp;
- double delta = (timeStamp - _lastTimeStamp) / 1000;
- _lastTimeStamp = timeStamp;
-
- // Count the number of frames we've been running
- _numFrames += 1;
-
- _frameRate = 1.0/delta;
-
- // Print frame rate
- if (_numFrames % 60 == 0) print("delta: $delta fps: $_frameRate");
-
- _callUpdate(_rootNode, delta);
- _scheduleTick();
- }
-
- void _callUpdate(Node node, double dt) {
- node.update(dt);
- for (Node child in node.children) {
- if (!child.paused) {
- _callUpdate(child, dt);
- }
- }
- }
-
- void _callSpriteBoxPerformedLayout(Node node) {
- node.spriteBoxPerformedLayout();
- for (Node child in node.children) {
- _callSpriteBoxPerformedLayout(child);
- }
- }
-
- // Hit tests
-
- /// Finds all nodes at a position defined in the box's coordinates.
- ///
- /// Use this method with caution. It searches the complete node tree to locate the nodes, which can be slow if the
- /// node tree is large.
- ///
- /// List nodes = mySpriteBox.findNodesAtPosition(new Point(50.0, 50.0));
- List<Node> findNodesAtPosition(Point position) {
- assert(position != null);
-
- List<Node> nodes = [];
-
- // Traverse the render tree and find objects at the position
- _addNodesAtPosition(_rootNode, position, nodes);
-
- return nodes;
- }
-
- _addNodesAtPosition(Node node, Point position, List<Node> list) {
- // Visit children first
- for (Node child in node.children) {
- _addNodesAtPosition(child, position, list);
- }
- // Do the hit test
- Point posInNodeSpace = node.convertPointToNodeSpace(position);
- if (node.isPointInside(posInNodeSpace)) {
- list.add(node);
- }
- }
-}
-
-class _SpriteBoxHitTestEntry extends BoxHitTestEntry {
- List<Node> nodeTargets;
- _SpriteBoxHitTestEntry(RenderBox target, Point localPosition) : super(target, localPosition);
-}
-
-/// An event that is passed down the node tree when pointer events occur. The SpriteBoxEvent is typically handled in
-/// the handleEvent method of [Node].
-class SpriteBoxEvent {
-
- /// The position of the event in box coordinates.
- ///
- /// You can use the convertPointToNodeSpace of [Node] to convert the position to local coordinates.
- ///
- /// bool handleEvent(SpriteBoxEvent event) {
- /// Point localPosition = convertPointToNodeSpace(event.boxPosition);
- /// if (event.type == 'pointerdown') {
- /// // Do something!
- /// }
- /// }
- final Point boxPosition;
-
- /// The type of event, there are currently four valid types, 'pointerdown', 'pointermoved', 'pointerup', and
- /// 'pointercancel'.
- ///
- /// if (event.type == 'pointerdown') {
- /// // Do something!
- /// }
- final String type;
-
- /// The id of the pointer. Each pointer on the screen will have a unique pointer id.
- ///
- /// if (event.pointer == firstPointerId) {
- /// // Do something
- /// }
- final int pointer;
-
- /// Creates a new SpriteBoxEvent, typically this is done internally inside the SpriteBox.
- ///
- /// var event = new SpriteBoxEvent(new Point(50.0, 50.0), 'pointerdown', 0);
- SpriteBoxEvent(this.boxPosition, this.type, this.pointer);
-}

Powered by Google App Engine
This is Rietveld 408576698