提交 09172e88 编写于 作者: V Viktor Lidholt

Adds support for zOrder and references to parent nodes in sprites, also start of new test app.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/1177563004.
上级 57df667f
......@@ -7,4 +7,5 @@ import 'sprites.dart';
import 'package:box2d/box2d.dart';
part 'game_world.dart';
part 'game_box.dart';
\ No newline at end of file
part 'game_box.dart';
part 'game_tests.dart';
part of game;
Math.Random _rand;
class GameTests extends TransformNode{
Image _imgAsteroid;
Image _imgBg;
Image _imgShip;
GameTests(ImageMap images) {
// Setup random number generator
_rand = new Math.Random();
// Fetch images
_imgBg = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/resources-auto/BurnTexture.png"];
_imgAsteroid = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/asteroid_big_002.png"];
_imgShip = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/GG_blueship_Lv3.png"];
for (int i = 0; i < 100; i++) {
addSprite(i/100.0);
}
}
void addSprite([double scale = null]) {
TestAsteroidSprite sprt = new TestAsteroidSprite.withImage(_imgAsteroid);
sprt.width = 64.0;
sprt.height = 64.0;
if (scale == null) {
scale = _rand.nextDouble();
}
sprt.zPosition = scale;
sprt.scale = scale;
sprt.position = new Vector2(_rand.nextDouble()*1024.0, _rand.nextDouble()*1024.0);
this.addChild(sprt);
}
void update(double dt) {
for (TransformNode child in children) {
child.update(dt);
}
}
}
class TestAsteroidSprite extends SpriteNode {
Vector2 _movementVector;
double _rotationalSpeed;
TestAsteroidSprite.withImage(Image img) : super.withImage(img) {
_movementVector = new Vector2(_rand.nextDouble() * 4.0 - 2.0, _rand.nextDouble() * 4.0 - 2.0);
_rotationalSpeed = _rand.nextDouble() * 2.0 - 1.0;
}
void update(double dt) {
position = position + _movementVector * scale;
// Bounce at edges
if (position[0] < 0 || position[0] > 1024.0) _movementVector[0] = -_movementVector[0];
if (position[1] < 0 || position[1] > 1024.0) _movementVector[1] = -_movementVector[1];
rotation += _rotationalSpeed;
}
}
......@@ -30,10 +30,10 @@ class GameWorld extends TransformNode {
addBackground();
// Add some asteroids to the game world
for (int i = 0; i < 5; i++) {
for (int i = 0; i < 50; i++) {
addAsteroid(10.0);
}
for (int i = 0; i < 5; i++) {
for (int i = 0; i < 50; i++) {
addAsteroid(20.0);
}
......@@ -46,7 +46,7 @@ class GameWorld extends TransformNode {
sprtBg.width = width;
sprtBg.height = height;
sprtBg.pivot = new Vector2(0.0, 0.0);
this.children.add(sprtBg);
this.addChild(sprtBg);
}
void addAsteroid([double radius=20.0]) {
......@@ -87,7 +87,7 @@ class GameWorld extends TransformNode {
// sprt.colorOverlay = new Color(0x33ff0000);
// sprt.transferMode = TransferMode.plusMode;
body.userData = sprt;
this.children.add(sprt);
this.addChild(sprt);
}
void addShip() {
......@@ -127,7 +127,7 @@ class GameWorld extends TransformNode {
sprt.height = radius*2;
sprt.position = new Vector2(width/2.0, height/2.0);
body.userData = sprt;
this.children.add(sprt);
this.addChild(sprt);
}
void update(double dt) {
......
......@@ -23,9 +23,15 @@ class SpriteBox extends RenderBox {
double _systemHeight;
SpriteBox(TransformNode rootNode, [SpriteBoxTransformMode mode = SpriteBoxTransformMode.nativePoints, double width=1024.0, double height=1024.0]) {
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;
_systemWidth = width;
......@@ -34,6 +40,13 @@ class SpriteBox extends RenderBox {
_scheduleTick();
}
void _addSpriteBoxReference(TransformNode node) {
node._spriteBox = this;
for (TransformNode child in node._children) {
_addSpriteBoxReference(child);
}
}
double get systemWidth => _systemWidth;
double get systemHeight => _systemHeight;
......
......@@ -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) {
}
}
}
\ No newline at end of file
......@@ -17,5 +17,7 @@ void main() {
void allLoaded(ImageMap loader) {
// Create a new app with the sprite box that contains our game world
app = new AppView(new GameBox(new GameWorld(loader)));
//app = new AppView(new GameBox(new GameWorld(loader)));
//print("hello");
app = new AppView((new SpriteBox(new GameTests(loader), SpriteBoxTransformMode.letterbox)));
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册