提交 e90de2b6 编写于 作者: V Viktor Lidholt

Adds API documentation, improves the API names, and cleans up code.

R=ianh@google.com

Review URL: https://codereview.chromium.org/1201983004.
上级 0aca63c7
......@@ -42,7 +42,7 @@ class GameDemoWorld extends NodeWithSize {
StarField _starField;
Nebula _nebula;
GameDemoWorld(ImageMap images) : super.withSize(new Size(_gameSizeWidth, _gameSizeHeight)) {
GameDemoWorld(ImageMap images) : super(new Size(_gameSizeWidth, _gameSizeHeight)) {
// Fetch images
_imgBg = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/resources-auto/BurnTexture.png"];
......@@ -81,7 +81,7 @@ class GameDemoWorld extends NodeWithSize {
// Methods for adding game objects
void addBackground() {
Sprite sprtBg = new Sprite.withImage(_imgBg);
Sprite sprtBg = new Sprite(_imgBg);
sprtBg.size = new Size(_gameSizeWidth, _gameSizeHeight);
sprtBg.pivot = Point.origin;
_gameLayer.addChild(sprtBg);
......@@ -296,7 +296,7 @@ class Asteroid extends Sprite {
return _radius;
}
Asteroid.withImage(Image img, AsteroidSize this._asteroidSize) : super.withImage(img) {
Asteroid.withImage(Image img, AsteroidSize this._asteroidSize) : super(img) {
size = new Size(radius * 2.0, radius * 2.0);
position = new Point(_gameSizeWidth * _rand.nextDouble(), _gameSizeHeight * _rand.nextDouble());
rotation = 360.0 * _rand.nextDouble();
......@@ -322,7 +322,7 @@ class Ship extends Sprite {
Vector2 _movementVector;
double _rotationTarget;
Ship.withImage(Image img) : super.withImage(img) {
Ship.withImage(Image img) : super(img) {
_movementVector = new Vector2.zero();
rotation = _rotationTarget = 270.0;
......@@ -350,7 +350,7 @@ class Laser extends Sprite {
Point _movementVector;
double radius = 10.0;
Laser.withImage(Image img, Ship ship) : super.withImage(img) {
Laser.withImage(Image img, Ship ship) : super(img) {
size = new Size(20.0, 20.0);
position = ship.position;
rotation = ship.rotation + 90.0;
......@@ -436,7 +436,7 @@ class Nebula extends Node {
Nebula.withImage(Image img) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Sprite sprt = new Sprite.withImage(img);
Sprite sprt = new Sprite(img);
sprt.pivot = Point.origin;
sprt.position = new Point(i * _gameSizeWidth - _gameSizeWidth, j * _gameSizeHeight - _gameSizeHeight);
addChild(sprt);
......
......@@ -4,6 +4,15 @@ double convertDegrees2Radians(double degrees) => degrees * Math.PI/180.8;
double convertRadians2Degrees(double radians) => radians * 180.0/Math.PI;
/// A base class for all objects that can be added to the sprite node tree and rendered to screen using [SpriteBox] and
/// [SpriteWidget].
///
/// The [Node] class itself doesn't render any content, but provides the basic functions of any type of node, such as
/// handling transformations and user input. To render the node tree, a root node must be added to a [SpriteBox] or a
/// [SpriteWidget]. Commonly used sub-classes of [Node] are [Sprite], [NodeWithSize], and many more upcoming subclasses.
///
/// Nodes form a hierarchical tree. Each node can have a number of children, and the transformation (positioning,
/// rotation, and scaling) of a node also affects its children.
class Node {
// Member variables
......@@ -11,51 +20,72 @@ class Node {
SpriteBox _spriteBox;
Node _parent;
Point _position;
double _rotation;
Point _position = Point.origin;
double _rotation = 0.0;
Matrix4 _transformMatrix;
Matrix4 _transformMatrix = new Matrix4.identity();
Matrix4 _transformMatrixNodeToBox;
Matrix4 _transformMatrixBoxToNode;
double _scaleX;
double _scaleY;
double _scaleX = 1.0;
double _scaleY = 1.0;
bool visible;
/// The visibility of this node and its children.
bool visible = true;
double _zPosition;
double _zPosition = 0.0;
int _addedOrder;
int _childrenLastAddedOrder;
bool _childrenNeedSorting;
int _childrenLastAddedOrder = 0;
bool _childrenNeedSorting = false;
/// Decides if the node and its children is currently paused.
///
/// A paused node will not receive any input events, update calls, or run any animations.
///
/// myNodeTree.paused = true;
bool paused = false;
bool _userInteractionEnabled = false;
/// If set to true the node will receive multiple pointers, otherwise it will only receive events the first pointer.
///
/// This property is only meaningful if [userInteractionEnabled] is set to true. Default value is false.
///
/// class MyCustomNode extends Node {
/// handleMultiplePointers = true;
/// }
bool handleMultiplePointers = false;
int _handlingPointer;
List<Node>_children;
List<Node>_children = [];
// Constructors
/// Creates a new [Node] without any transformation.
///
/// var myNode = new Node();
Node() {
_rotation = 0.0;
_position = Point.origin;
_scaleX = _scaleY = 1.0;
_transformMatrix = new Matrix4.identity();
_children = [];
_childrenNeedSorting = false;
_childrenLastAddedOrder = 0;
_zPosition = 0.0;
visible = true;
}
// Property setters and getters
/// The [SpriteBox] this node is added to, or null if it's not currently added to a [SpriteBox].
///
/// For most applications it's not necessary to access the [SpriteBox] directly.
///
/// // Get the transformMode of the sprite box
/// var transformMode = myNode.spriteBox.transformMode;
SpriteBox get spriteBox => _spriteBox;
/// The parent of this node, or null if it doesn't have a parent.
///
/// // Hide the parent
/// myNode.parent.visible = false;
Node get parent => _parent;
/// The rotation of this node in degrees.
///
/// myNode.rotation = 45.0;
double get rotation => _rotation;
void set rotation(double rotation) {
......@@ -64,6 +94,9 @@ class Node {
_invalidateTransformMatrix();
}
/// The position of this node relative to its parent.
///
/// myNode.position = new Point(42.0, 42.0);
Point get position => _position;
void set position(Point position) {
......@@ -72,6 +105,14 @@ class Node {
_invalidateTransformMatrix();
}
/// The draw order of this node compared to its parent and its siblings.
///
/// By default nodes are drawn in the order that they have been added to a parent. To override this behavior the
/// [zPosition] property can be used. A higher value of this property will force the node to be drawn in front of
/// siblings that have a lower value. If a negative value is used the node will be drawn behind its parent.
///
/// nodeInFront.zPosition = 1.0;
/// nodeBehind.zPosition = -1.0;
double get zPosition => _zPosition;
void set zPosition(double zPosition) {
......@@ -82,6 +123,11 @@ class Node {
}
}
/// The scale of this node relative its parent.
///
/// The [scale] property is only valid if [scaleX] and [scaleY] are equal values.
///
/// myNode.scale = 5.0;
double get scale {
assert(_scaleX == _scaleY);
return _scaleX;
......@@ -93,6 +139,9 @@ class Node {
_invalidateTransformMatrix();
}
/// The horizontal scale of this node relative its parent.
///
/// myNode.scaleX = 5.0;
double get scaleX => _scaleX;
void set scaleX(double scaleX) {
......@@ -101,6 +150,9 @@ class Node {
_invalidateTransformMatrix();
}
/// The vertical scale of this node relative its parent.
///
/// myNode.scaleY = 5.0;
double get scaleY => _scaleY;
void set scaleY(double scaleY) {
......@@ -109,6 +161,14 @@ class Node {
_invalidateTransformMatrix();
}
/// A list of the children of this node.
///
/// This list should only be modified by using the [addChild] and [removeChild] methods.
///
/// // Iterate over a nodes children
/// for (Node child in myNode.children) {
/// // Do something with the child
/// }
List<Node> get children {
_sortChildren();
return _children;
......@@ -116,6 +176,11 @@ class Node {
// Adding and removing children
/// Adds a child to this node.
///
/// The same node cannot be added to multiple nodes.
///
/// addChild(new Sprite(myImage));
void addChild(Node child) {
assert(child != null);
assert(child._parent == null);
......@@ -129,6 +194,9 @@ class Node {
if (_spriteBox != null) _spriteBox._eventTargets = null;
}
/// Removes a child from this node.
///
/// removeChild(myChildNode);
void removeChild(Node child) {
assert(child != null);
if (_children.remove(child)) {
......@@ -138,11 +206,17 @@ class Node {
}
}
/// Removes this node from its parent node.
///
/// removeFromParent();
void removeFromParent() {
assert(_parent != null);
_parent.removeChild(this);
}
/// Removes all children of this node.
///
/// removeAllChildren();
void removeAllChildren() {
for (Node child in _children) {
child._parent = null;
......@@ -173,6 +247,11 @@ class Node {
// Calculating the transformation matrix
/// The transformMatrix describes the transformation from the node's parent.
///
/// You cannot set the transformMatrix directly, instead use the position, rotation and scale properties.
///
/// Matrix4 matrix = myNode.transformMatrix;
Matrix4 get transformMatrix {
if (_transformMatrix != null) {
return _transformMatrix;
......@@ -251,6 +330,12 @@ class Node {
return _transformMatrixBoxToNode;
}
/// Converts a point from the coordinate system of the [SpriteBox] to the local coordinate system of the node.
///
/// This method is particularly useful when handling pointer events and need the pointers position in a local
/// coordinate space.
///
/// Point localPoint = myNode.convertPointToNodeSpace(pointInBoxCoordinates);
Point convertPointToNodeSpace(Point boxPoint) {
assert(boxPoint != null);
assert(_spriteBox != null);
......@@ -259,6 +344,9 @@ class Node {
return new Point(v[0], v[1]);
}
/// Converts a point from the local coordinate system of the node to the coordinate system of the [SpriteBox].
///
/// Point pointInBoxCoordinates = myNode.convertPointToBoxSpace(localPoint);
Point convertPointToBoxSpace(Point nodePoint) {
assert(nodePoint != null);
assert(_spriteBox != null);
......@@ -267,6 +355,9 @@ class Node {
return new Point(v[0], v[1]);
}
/// Converts a [point] from another [node]s coordinate system into the local coordinate system of this node.
///
/// Point pointInNodeASpace = nodeA.convertPointFromNode(pointInNodeBSpace, nodeB);
Point convertPointFromNode(Point point, Node node) {
assert(node != null);
assert(point != null);
......@@ -281,8 +372,23 @@ class Node {
// Hit test
bool isPointInside(Point nodePoint) {
assert(nodePoint != null);
/// Returns true if the [point] is inside the node, the [point] is in the local coordinate system of the node.
///
/// myNode.isPointInside(localPoint);
///
/// [NodeWithSize] provides a basic bounding box check for this method, if you require a more detailed check this
/// method can be overridden.
///
/// bool isPointInside (Point nodePoint) {
/// double minX = -size.width * pivot.x;
/// double minY = -size.height * pivot.y;
/// double maxX = minX + size.width;
/// double maxY = minY + size.height;
/// return (nodePoint.x >= minX && nodePoint.x < maxX &&
/// nodePoint.y >= minY && nodePoint.y < maxY);
/// }
bool isPointInside(Point point) {
assert(point != null);
return false;
}
......@@ -305,6 +411,22 @@ class Node {
canvas.concat(transformMatrix.storage);
}
/// Paints this node to the canvas.
///
/// Subclasses, such as [Sprite], override this method to do the actual painting of the node. To do custom
/// drawing override this method and make calls to the [canvas] object. All drawing is done in the node's local
/// coordinate system, relative to the node's position. If you want to make the drawing relative to the node's
/// bounding box's origin, override [NodeWithSize] and call the applyTransformForPivot method before making calls for
/// drawing.
///
/// void paint(PictureRecorder canvas) {
/// canvas.save();
/// applyTransformForPivot(canvas);
///
/// // Do painting here
///
/// canvas.restore();
/// }
void paint(PictureRecorder canvas) {
}
......@@ -339,14 +461,35 @@ class Node {
// Receiving update calls
/// Called before a frame is drawn.
///
/// Override this method to do any updates to the node or node tree before it's drawn to screen.
///
/// // Make the node rotate at a fixed speed
/// void update(double dt) {
/// rotation = rotation * 10.0 * dt;
/// }
void update(double dt) {
}
/// Called whenever the [SpriteBox] is modified or resized, or if the device is rotated.
///
/// Override this method to do any updates that may be necessary to correctly display the node or node tree with the
/// new layout of the [SpriteBox].
///
/// void spriteBoxPerformedLayout() {
/// // Move some stuff around here
/// }
void spriteBoxPerformedLayout() {
}
// Handling user interaction
/// The node will receive user interactions, such as pointer (touch or mouse) events.
///
/// class MyCustomNode extends NodeWithSize {
/// userInteractionEnabled = true;
/// }
bool get userInteractionEnabled => _userInteractionEnabled;
void set userInteractionEnabled(bool userInteractionEnabled) {
......@@ -354,6 +497,33 @@ class Node {
if (_spriteBox != null) _spriteBox._eventTargets = null;
}
/// Handles an event, such as a pointer (touch or mouse) event.
///
/// Override this method to handle events. The node will only receive events if the [userInteractionEnabled] property
/// is set to true and the [isPointInside] method returns true for the position of the pointer down event (default
/// behavior provided by [NodeWithSize]). Unless [handleMultiplePointers] is set to true, the node will only receive
/// events for the first pointer that is down.
///
/// Return true if the node has consumed the event, if an event is consumed it will not be passed on to nodes behind
/// the current node.
///
/// // MyTouchySprite gets transparent when we touch it
/// class MyTouchySprite extends Sprite {
///
/// MyTouchySprite(Image img) : super (img) {
/// userInteractionEnabled = true;
/// }
///
/// bool handleEvent(SpriteBoxEvent event) {
/// if (event.type == 'pointerdown) {
/// opacity = 0.5;
/// }
/// else if (event.type == 'pointerup') {
/// opacity = 1.0;
/// }
/// return true;
/// }
/// }
bool handleEvent(SpriteBoxEvent event) {
return false;
}
......
part of sprites;
/// The super class of any [Node] that has a size.
///
/// NodeWithSize adds the ability for a node to have a size and a pivot point.
abstract class NodeWithSize extends Node {
/// Changing the size will affect the size of the rendering of the node.
///
/// myNode.size = new Size(1024.0, 1024.0);
Size size;
Point pivot;
NodeWithSize() {
size = Size.zero;
pivot = Point.origin;
}
/// The normalized point which the node is transformed around.
///
/// // Position myNode from is middle top
/// myNode.pivot = new Point(0.5, 0.0);
Point pivot;
NodeWithSize.withSize(Size this.size, [Point this.pivot]) {
/// Creates a new NodeWithSize.
///
/// The default [size] is zero and the default [pivot] point is the origin. Subclasses may change the default values.
///
/// var myNodeWithSize = new NodeWithSize(new Size(1024.0, 1024.0));
NodeWithSize([Size this.size, Point this.pivot]) {
if (size == null) size = Size.zero;
if (pivot == null) pivot = Point.origin;
}
/// Call this method in your [paint] method if you want the origin of your drawing to be the top left corner of the
/// node's bounding box.
///
/// If you use this method you will need to save and restore your canvas at the beginning and
/// end of your [paint] method.
///
/// void paint(PictureRecorder canvas) {
/// canvas.save();
/// applyTransformForPivot(canvas);
///
/// // Do painting here
///
/// canvas.restore();
/// }
void applyTransformForPivot(PictureRecorder canvas) {
if (pivot.x != 0 || pivot.y != 0) {
double pivotInPointsX = size.width * pivot.x;
......
part of sprites;
// TODO: Actually draw images
/// A Sprite is a [Node] that renders a bitmap image to the screen.
class Sprite extends NodeWithSize {
Image _image;
/// The image that the sprite will render to screen.
///
/// If the image is null, the sprite will be rendered as a red square
/// marking the bounds of the sprite.
///
/// mySprite.image = myImage;
Image image;
/// If true, constrains the proportions of the image by scaling it down, if its proportions doesn't match the [size].
///
/// mySprite.constrainProportions = true;
bool constrainProportions = false;
double _opacity = 1.0;
/// The color to draw on top of the sprite, null if no color overlay is used.
///
/// // Color the sprite red
/// mySprite.colorOverlay = new Color(0x77ff0000);
Color colorOverlay;
TransferMode transferMode;
Sprite() {
}
/// The transfer mode used when drawing the sprite to screen.
///
/// // Add the colors of the sprite with the colors of the background
/// mySprite.transferMode = TransferMode.plusMode;
TransferMode transferMode;
Sprite.withImage(Image image) {
/// Creates a new sprite from the provided [image].
///
/// var mySprite = new Sprite(myImage);
Sprite([Image this.image]) {
pivot = new Point(0.5, 0.5);
if (image != null) {
size = new Size(image.width.toDouble(), image.height.toDouble());
_image = image;
}
}
/// The opacity of the sprite in the range 0.0 to 1.0.
///
/// mySprite.opacity = 0.5;
double get opacity => _opacity;
void set opacity(double opacity) {
......@@ -33,19 +56,19 @@ class Sprite extends NodeWithSize {
// Account for pivot point
applyTransformForPivot(canvas);
if (_image != null && _image.width > 0 && _image.height > 0) {
if (image != null && image.width > 0 && image.height > 0) {
double scaleX = size.width/_image.width;
double scaleY = size.height/_image.height;
double scaleX = size.width/image.width;
double scaleY = size.height/image.height;
if (constrainProportions) {
// Constrain proportions, using the smallest scale and by centering the image
if (scaleX < scaleY) {
canvas.translate(0.0, (size.height - scaleX * _image.height)/2.0);
canvas.translate(0.0, (size.height - scaleX * image.height)/2.0);
scaleY = scaleX;
}
else {
canvas.translate((size.width - scaleY * _image.width)/2.0, 0.0);
canvas.translate((size.width - scaleY * image.width)/2.0, 0.0);
scaleX = scaleY;
}
}
......@@ -62,7 +85,7 @@ class Sprite extends NodeWithSize {
paint.setTransferMode(transferMode);
}
canvas.drawImage(_image, 0.0, 0.0, paint);
canvas.drawImage(image, 0.0, 0.0, paint);
}
else {
// Paint a red square for missing texture
......
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,
......@@ -22,9 +34,10 @@ class SpriteBox extends RenderBox {
double _frameRate = 0.0;
// Transformation mode
SpriteBoxTransformMode transformMode;
// double _systemWidth;
// double _systemHeight;
SpriteBoxTransformMode _transformMode;
/// The transform mode used by the [SpriteBox].
SpriteBoxTransformMode get transformMode => _transformMode;
// Cached transformation matrix
Matrix4 _transformMatrix;
......@@ -33,7 +46,14 @@ class SpriteBox extends RenderBox {
// Setup
SpriteBox(NodeWithSize rootNode, [SpriteBoxTransformMode mode = SpriteBoxTransformMode.nativePoints]) {
/// 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);
......@@ -44,9 +64,7 @@ class SpriteBox extends RenderBox {
_addSpriteBoxReference(_rootNode);
// Setup transform mode
transformMode = mode;
// _systemWidth = rootNode.size.width;
// _systemHeight = rootNode.size.height;
_transformMode = mode;
_scheduleTick();
}
......@@ -60,9 +78,9 @@ class SpriteBox extends RenderBox {
// Properties
double get systemWidth => rootNode.size.width;
double get systemHeight => rootNode.size.height;
/// The root node of the node tree that is rendered by this box.
///
/// var rootNode = mySpriteBox.rootNode;
NodeWithSize get rootNode => _rootNode;
void performLayout() {
......@@ -98,7 +116,7 @@ class SpriteBox extends RenderBox {
}
}
void handleEvent(Event event, SpriteBoxHitTestEntry entry) {
void handleEvent(Event event, _SpriteBoxHitTestEntry entry) {
if (event is PointerEvent) {
if (event.type == 'pointerdown') {
......@@ -148,12 +166,17 @@ class SpriteBox extends RenderBox {
}
bool hitTest(HitTestResult result, { Point position }) {
result.add(new SpriteBoxHitTestEntry(this, 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) {
......@@ -171,7 +194,7 @@ class SpriteBox extends RenderBox {
double systemWidth = rootNode.size.width;
double systemHeight = rootNode.size.height;
switch(transformMode) {
switch(_transformMode) {
case SpriteBoxTransformMode.stretch:
scaleX = size.width/systemWidth;
scaleY = size.height/systemHeight;
......@@ -287,6 +310,12 @@ class SpriteBox extends RenderBox {
// 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);
......@@ -311,15 +340,44 @@ class SpriteBox extends RenderBox {
}
}
class SpriteBoxHitTestEntry extends BoxHitTestEntry {
class _SpriteBoxHitTestEntry extends BoxHitTestEntry {
List<Node> nodeTargets;
SpriteBoxHitTestEntry(RenderBox target, Point localPosition) : super(target, localPosition);
_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 {
Point boxPosition;
String type;
int pointer;
/// 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);
}
\ No newline at end of file
part of sprites;
/// A widget that uses a [SpriteBox] to render a sprite node tree to the screen.
class SpriteWidget extends OneChildRenderObjectWrapper {
/// The rootNode of the sprite node tree.
///
/// var node = mySpriteWidget.rootNode;
final NodeWithSize rootNode;
/// The transform mode used to fit the sprite node tree to the size of the widget.
final SpriteBoxTransformMode transformMode;
/// Creates a new sprite widget with [rootNode] as its content.
///
/// The widget will setup the coordinate space for the sprite node tree using the size of the [rootNode] in
/// combination with the supplied [transformMode]. By default the letterbox transform mode is used. See
/// [SpriteBoxTransformMode] for more details on the different modes.
///
/// The most common way to setup the sprite node graph is to subclass [NodeWithSize] and pass it to the sprite widget.
/// In the custom subclass it's possible to build the node graph, do animations and handle user events.
///
/// var mySpriteTree = new MyCustomNodeWithSize();
/// var mySpriteWidget = new SpriteWidget(mySpriteTree, SpriteBoxTransformMode.fixedHeight);
SpriteWidget(this.rootNode, [this.transformMode = SpriteBoxTransformMode.letterbox]);
SpriteBox get root => super.root;
......@@ -16,6 +33,6 @@ class SpriteWidget extends OneChildRenderObjectWrapper {
// SpriteBox doesn't allow mutation of these properties
assert(rootNode == root.rootNode);
assert(transformMode == root.transformMode);
assert(transformMode == root._transformMode);
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册