diff --git a/examples/game/lib/explosions.dart b/examples/game/lib/explosions.dart new file mode 100644 index 00000000000..8bfb97ada0d --- /dev/null +++ b/examples/game/lib/explosions.dart @@ -0,0 +1,71 @@ +part of game; + +class Explosion extends Node { + Explosion(SpriteSheet sheet) { + // Add particles + ParticleSystem particlesDebris = new ParticleSystem( + sheet["explosion_particle.png"], + rotateToMovement: true, + startRotation:90.0, + startRotationVar: 0.0, + endRotation: 90.0, + startSize: 0.3, + startSizeVar: 0.1, + endSize: 0.3, + endSizeVar: 0.1, + numParticlesToEmit: 25, + emissionRate:1000.0, + greenVar: 127, + redVar: 127 + ); + particlesDebris.zPosition = 1010.0; + addChild(particlesDebris); + + ParticleSystem particlesFire = new ParticleSystem( + sheet["fire_particle.png"], + colorSequence: new ColorSequence([new Color(0xffffff33), new Color(0xffff3333), new Color(0x00ff3333)], [0.0, 0.5, 1.0]), + numParticlesToEmit: 25, + emissionRate: 1000.0, + startSize: 0.5, + startSizeVar: 0.1, + endSize: 0.5, + endSizeVar: 0.1, + posVar: new Point(10.0, 10.0), + speed: 10.0, + speedVar: 5.0 + ); + particlesFire.zPosition = 1011.0; + addChild(particlesFire); + + // Add ring + Sprite sprtRing = new Sprite(sheet["explosion_ring.png"]); + sprtRing.transferMode = sky.TransferMode.plus; + addChild(sprtRing); + + Action scale = new ActionTween( (a) => sprtRing.scale = a, 0.2, 1.0, 1.5); + Action scaleAndRemove = new ActionSequence([scale, new ActionRemoveNode(sprtRing)]); + Action fade = new ActionTween( (a) => sprtRing.opacity = a, 1.0, 0.0, 1.5); + actions.run(scaleAndRemove); + actions.run(fade); + + // Add streaks + for (int i = 0; i < 5; i++) { + Sprite sprtFlare = new Sprite(sheet["explosion_flare.png"]); + sprtFlare.pivot = new Point(0.3, 1.0); + sprtFlare.scaleX = 0.3; + sprtFlare.transferMode = sky.TransferMode.plus; + sprtFlare.rotation = randomDouble() * 360.0; + addChild(sprtFlare); + + double multiplier = randomDouble() * 0.3 + 1.0; + + Action scale = new ActionTween( (a) => sprtFlare.scaleY = a, 0.3 * multiplier, 0.8, 1.5 * multiplier); + Action scaleAndRemove = new ActionSequence([scale, new ActionRemoveNode(sprtFlare)]); + Action fadeIn = new ActionTween( (a) => sprtFlare.opacity = a, 0.0, 1.0, 0.5 * multiplier); + Action fadeOut = new ActionTween( (a) => sprtFlare.opacity = a, 1.0, 0.0, 1.0 * multiplier); + Action fadeInOut = new ActionSequence([fadeIn, fadeOut]); + actions.run(scaleAndRemove); + actions.run(fadeInOut); + } + } +} diff --git a/examples/game/lib/flash.dart b/examples/game/lib/flash.dart new file mode 100644 index 00000000000..064958cf326 --- /dev/null +++ b/examples/game/lib/flash.dart @@ -0,0 +1,23 @@ +part of game; + +class Flash extends NodeWithSize { + Flash(Size size, this.duration) : super(size) { + ActionTween fade = new ActionTween((a) => _opacity = a, 1.0, 0.0, duration); + ActionSequence seq = new ActionSequence([fade, new ActionRemoveNode(this)]); + actions.run(seq); + } + + double duration; + double _opacity = 1.0; + Paint _cachedPaint = new Paint(); + + void paint(PaintingCanvas canvas) { + // Update the color + _cachedPaint.color = new Color.fromARGB((255.0 * _opacity).toInt(), + 255, 255, 255); + // Fill the area + applyTransformForPivot(canvas); + canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height), + _cachedPaint); + } +} diff --git a/examples/game/lib/game_demo.dart b/examples/game/lib/game_demo.dart index cba7e05fb47..6e53c6a028b 100644 --- a/examples/game/lib/game_demo.dart +++ b/examples/game/lib/game_demo.dart @@ -8,4 +8,9 @@ import 'package:sky/rendering/object.dart'; import 'package:sky/widgets/framework.dart'; import 'package:skysprites/skysprites.dart'; +part 'explosions.dart'; +part 'flash.dart'; part 'game_demo_node.dart'; +part 'game_objects.dart'; +part 'repeated_image.dart'; +part 'star_field.dart'; diff --git a/examples/game/lib/game_demo_node.dart b/examples/game/lib/game_demo_node.dart index 93ceeaedf85..ca482d2ca85 100644 --- a/examples/game/lib/game_demo_node.dart +++ b/examples/game/lib/game_demo_node.dart @@ -252,238 +252,6 @@ class Level extends Node { } } -abstract class GameObject extends Node { - double radius = 0.0; - double removeLimit = 1280.0; - bool canDamageShip = true; - bool canBeDamaged = true; - double maxDamage = 3.0; - double damage = 0.0; - - Paint _paintDebug = new Paint() - ..color=new Color(0xffff0000) - ..strokeWidth = 1.0 - ..setStyle(sky.PaintingStyle.stroke); - - bool collidingWith(GameObject obj) { - return (GameMath.pointQuickDist(position, obj.position) - < radius + obj.radius); - } - - void move() { - } - - void removeIfOffscreen(double scroll) { - ; - if (-position.y > scroll + removeLimit || - -position.y < scroll - 50.0) { - removeFromParent(); - } - } - - void destroy() { - if (parent != null) { - Explosion explo = createExplosion(); - if (explo != null) { - explo.position = position; - parent.addChild(explo); - } - - removeFromParent(); - } - } - - int addDamage(double d) { - if (!canBeDamaged) return 0; - - damage += d; - if (damage >= maxDamage) { - destroy(); - return (maxDamage * 10).ceil(); - } - return 10; - } - - Explosion createExplosion() { - return null; - } - - void paint(PaintingCanvas canvas) { - if (_drawDebug) { - canvas.drawCircle(Point.origin, radius, _paintDebug); - } - super.paint(canvas); - } - - void setupActions() { - } -} - -class Ship extends GameObject { - Ship(GameObjectFactory f) { - // Add main ship sprite - _sprt = new Sprite(f.sheet["ship.png"]); - _sprt.scale = 0.3; - _sprt.rotation = -90.0; - addChild(_sprt); - radius = 20.0; - - canBeDamaged = false; - canDamageShip = false; - - // Set start position - position = new Point(0.0, 50.0); - } - - Sprite _sprt; - - void applyThrust(Point joystickValue, double scroll) { - Point oldPos = position; - Point target = new Point(joystickValue.x * 160.0, joystickValue.y * 220.0 - 250.0 - scroll); - double filterFactor = 0.2; - - position = new Point( - GameMath.filter(oldPos.x, target.x, filterFactor), - GameMath.filter(oldPos.y, target.y, filterFactor)); - } -} - -class Laser extends GameObject { - double impact = 1.0; - - Laser(GameObjectFactory f) { - // Add sprite - _sprt = new Sprite(f.sheet["laser.png"]); - _sprt.scale = 0.3; - _sprt.transferMode = sky.TransferMode.plus; - addChild(_sprt); - radius = 10.0; - removeLimit = 640.0; - - canDamageShip = false; - canBeDamaged = false; - } - - Sprite _sprt; - - void move() { - position += new Offset(0.0, -10.0); - } -} - -abstract class Obstacle extends GameObject { - - Obstacle(this._f); - - double explosionScale = 1.0; - GameObjectFactory _f; - - Explosion createExplosion() { - SoundEffectPlayer.sharedInstance().play(_f.sounds["explosion"]); - Explosion explo = new Explosion(_f.sheet); - explo.scale = explosionScale; - return explo; - } -} - -abstract class Asteroid extends Obstacle { - Asteroid(GameObjectFactory f) : super(f); - - Sprite _sprt; - - void setupActions() { - // Rotate obstacle - int direction = 1; - if (randomBool()) direction = -1; - ActionTween rotate = new ActionTween( - (a) => _sprt.rotation = a, - 0.0, 360.0 * direction, 5.0 + 5.0 * randomDouble()); - _sprt.actions.run(new ActionRepeatForever(rotate)); - } - - set damage(double d) { - super.damage = d; - int alpha = ((200.0 * d) ~/ maxDamage).clamp(0, 200); - _sprt.colorOverlay = new Color.fromARGB(alpha, 255, 3, 86); - } -} - -class AsteroidBig extends Asteroid { - AsteroidBig(GameObjectFactory f) : super(f) { - _sprt = new Sprite(f.sheet["asteroid_big_${randomInt(3)}.png"]); - _sprt.scale = 0.3; - radius = 25.0; - maxDamage = 5.0; - addChild(_sprt); - } -} - -class AsteroidSmall extends Asteroid { - AsteroidSmall(GameObjectFactory f) : super(f) { - _sprt = new Sprite(f.sheet["asteroid_small_${randomInt(3)}.png"]); - _sprt.scale = 0.3; - radius = 12.0; - maxDamage = 3.0; - addChild(_sprt); - } -} - -class MovingEnemy extends Obstacle { - MovingEnemy(GameObjectFactory f) : super(f) { - _sprt = new Sprite(f.sheet["ship.png"]); - _sprt.scale = 0.2; - radius = 12.0; - maxDamage = 2.0; - addChild(_sprt); - - constraints = [new ConstraintRotationToMovement(dampening: 0.5)]; - } - - final double _swirlSpacing = 80.0; - - _addRandomSquare(List offsets, double x, double y) { - double xMove = (randomBool()) ? _swirlSpacing : -_swirlSpacing; - double yMove = (randomBool()) ? _swirlSpacing : -_swirlSpacing; - - if (randomBool()) { - offsets.addAll([ - new Offset(x, y), - new Offset(xMove + x, y), - new Offset(xMove + x, yMove + y), - new Offset(x, yMove + y), - new Offset(x, y) - ]); - } else { - offsets.addAll([ - new Offset(x, y), - new Offset(x, y + yMove), - new Offset(xMove + x, yMove + y), - new Offset(xMove + x, y), - new Offset(x, y) - ]); - } - } - - void setupActions() { - - List offsets = []; - _addRandomSquare(offsets, -_swirlSpacing, 0.0); - _addRandomSquare(offsets, _swirlSpacing, 0.0); - offsets.add(new Offset(-_swirlSpacing, 0.0)); - - List points = []; - for (Offset offset in offsets) { - points.add(position + offset); - } - - ActionSpline spline = new ActionSpline((a) => position = a, points, 6.0); - spline.tension = 0.7; - actions.run(new ActionRepeatForever(spline)); - } - - Sprite _sprt; -} - enum GameObjectType { asteroidBig, asteroidSmall, @@ -530,192 +298,6 @@ class GameObjectFactory { } } -class StarField extends NodeWithSize { - sky.Image _image; - SpriteSheet _spriteSheet; - int _numStars; - bool _autoScroll; - - List _starPositions; - List _starScales; - List _rects; - List _colors; - - final double _padding = 50.0; - Size _paddedSize = Size.zero; - - Paint _paint = new Paint() - ..setFilterQuality(sky.FilterQuality.low) - ..isAntiAlias = false - ..setTransferMode(sky.TransferMode.plus); - - StarField(this._spriteSheet, this._numStars, [this._autoScroll = false]) : super(Size.zero) { - _image = _spriteSheet.image; - } - - void addStars() { - _starPositions = []; - _starScales = []; - _colors = []; - _rects = []; - - size = spriteBox.visibleArea.size; - _paddedSize = new Size(size.width + _padding * 2.0, - size.height + _padding * 2.0); - - for (int i = 0; i < _numStars; i++) { - _starPositions.add(new Point(randomDouble() * _paddedSize.width, - randomDouble() * _paddedSize.height)); - _starScales.add(randomDouble() * 0.4); - _colors.add(new Color.fromARGB((255.0 * (randomDouble() * 0.5 + 0.5)).toInt(), 255, 255, 255)); - _rects.add(_spriteSheet["star_${randomInt(2)}.png"].frame); - } - } - - void spriteBoxPerformedLayout() { - addStars(); - } - - void paint(PaintingCanvas canvas) { - // Create a transform for each star - List transforms = []; - for (int i = 0; i < _numStars; i++) { - sky.RSTransform transform = new sky.RSTransform( - _starScales[i], - 0.0, - _starPositions[i].x - _padding, - _starPositions[i].y - _padding); - - transforms.add(transform); - } - - // Draw the stars - canvas.drawAtlas(_image, transforms, _rects, _colors, sky.TransferMode.modulate, null, _paint); - } - - void move(double dx, double dy) { - for (int i = 0; i < _numStars; i++) { - double xPos = _starPositions[i].x; - double yPos = _starPositions[i].y; - double scale = _starScales[i]; - - xPos += dx * scale; - yPos += dy * scale; - - if (xPos >= _paddedSize.width) xPos -= _paddedSize.width; - if (xPos < 0) xPos += _paddedSize.width; - if (yPos >= _paddedSize.height) yPos -= _paddedSize.height; - if (yPos < 0) yPos += _paddedSize.height; - - _starPositions[i] = new Point(xPos, yPos); - } - } - - void update(double dt) { - if (_autoScroll) { - move(0.0, dt * 100.0); - } - } -} - -class RepeatedImage extends Node { - Sprite _sprt0; - Sprite _sprt1; - - RepeatedImage(sky.Image image, [sky.TransferMode mode = null]) { - _sprt0 = new Sprite.fromImage(image); - _sprt0.size = new Size(1024.0, 1024.0); - _sprt0.pivot = Point.origin; - _sprt1 = new Sprite.fromImage(image); - _sprt1.size = new Size(1024.0, 1024.0); - _sprt1.pivot = Point.origin; - _sprt1.position = new Point(0.0, -1024.0); - - if (mode != null) { - _sprt0.transferMode = mode; - _sprt1.transferMode = mode; - } - - addChild(_sprt0); - addChild(_sprt1); - } - - void move(double dy) { - double yPos = (position.y + dy) % 1024.0; - position = new Point(0.0, yPos); - } -} - -class Explosion extends Node { - Explosion(SpriteSheet sheet) { - // Add particles - ParticleSystem particlesDebris = new ParticleSystem( - sheet["explosion_particle.png"], - rotateToMovement: true, - startRotation:90.0, - startRotationVar: 0.0, - endRotation: 90.0, - startSize: 0.3, - startSizeVar: 0.1, - endSize: 0.3, - endSizeVar: 0.1, - numParticlesToEmit: 25, - emissionRate:1000.0, - greenVar: 127, - redVar: 127 - ); - particlesDebris.zPosition = 1010.0; - addChild(particlesDebris); - - ParticleSystem particlesFire = new ParticleSystem( - sheet["fire_particle.png"], - colorSequence: new ColorSequence([new Color(0xffffff33), new Color(0xffff3333), new Color(0x00ff3333)], [0.0, 0.5, 1.0]), - numParticlesToEmit: 25, - emissionRate: 1000.0, - startSize: 0.5, - startSizeVar: 0.1, - endSize: 0.5, - endSizeVar: 0.1, - posVar: new Point(10.0, 10.0), - speed: 10.0, - speedVar: 5.0 - ); - particlesFire.zPosition = 1011.0; - addChild(particlesFire); - - // Add ring - Sprite sprtRing = new Sprite(sheet["explosion_ring.png"]); - sprtRing.transferMode = sky.TransferMode.plus; - addChild(sprtRing); - - Action scale = new ActionTween( (a) => sprtRing.scale = a, 0.2, 1.0, 1.5); - Action scaleAndRemove = new ActionSequence([scale, new ActionRemoveNode(sprtRing)]); - Action fade = new ActionTween( (a) => sprtRing.opacity = a, 1.0, 0.0, 1.5); - actions.run(scaleAndRemove); - actions.run(fade); - - // Add streaks - for (int i = 0; i < 5; i++) { - Sprite sprtFlare = new Sprite(sheet["explosion_flare.png"]); - sprtFlare.pivot = new Point(0.3, 1.0); - sprtFlare.scaleX = 0.3; - sprtFlare.transferMode = sky.TransferMode.plus; - sprtFlare.rotation = randomDouble() * 360.0; - addChild(sprtFlare); - - double multiplier = randomDouble() * 0.3 + 1.0; - - Action scale = new ActionTween( (a) => sprtFlare.scaleY = a, 0.3 * multiplier, 0.8, 1.5 * multiplier); - Action scaleAndRemove = new ActionSequence([scale, new ActionRemoveNode(sprtFlare)]); - Action fadeIn = new ActionTween( (a) => sprtFlare.opacity = a, 0.0, 1.0, 0.5 * multiplier); - Action fadeOut = new ActionTween( (a) => sprtFlare.opacity = a, 1.0, 0.0, 1.0 * multiplier); - Action fadeInOut = new ActionSequence([fadeIn, fadeOut]); - actions.run(scaleAndRemove); - actions.run(fadeInOut); - } - } -} - class Hud extends Node { SpriteSheet sheet; Sprite sprtBgScore; @@ -759,25 +341,3 @@ class Hud extends Node { } } } - -class Flash extends NodeWithSize { - Flash(Size size, this.duration) : super(size) { - ActionTween fade = new ActionTween((a) => _opacity = a, 1.0, 0.0, duration); - ActionSequence seq = new ActionSequence([fade, new ActionRemoveNode(this)]); - actions.run(seq); - } - - double duration; - double _opacity = 1.0; - Paint _cachedPaint = new Paint(); - - void paint(PaintingCanvas canvas) { - // Update the color - _cachedPaint.color = new Color.fromARGB((255.0 * _opacity).toInt(), - 255, 255, 255); - // Fill the area - applyTransformForPivot(canvas); - canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height), - _cachedPaint); - } -} diff --git a/examples/game/lib/game_objects.dart b/examples/game/lib/game_objects.dart new file mode 100644 index 00000000000..422f158fac9 --- /dev/null +++ b/examples/game/lib/game_objects.dart @@ -0,0 +1,233 @@ +part of game; + +abstract class GameObject extends Node { + double radius = 0.0; + double removeLimit = 1280.0; + bool canDamageShip = true; + bool canBeDamaged = true; + double maxDamage = 3.0; + double damage = 0.0; + + Paint _paintDebug = new Paint() + ..color=new Color(0xffff0000) + ..strokeWidth = 1.0 + ..setStyle(sky.PaintingStyle.stroke); + + bool collidingWith(GameObject obj) { + return (GameMath.pointQuickDist(position, obj.position) + < radius + obj.radius); + } + + void move() { + } + + void removeIfOffscreen(double scroll) { + ; + if (-position.y > scroll + removeLimit || + -position.y < scroll - 50.0) { + removeFromParent(); + } + } + + void destroy() { + if (parent != null) { + Explosion explo = createExplosion(); + if (explo != null) { + explo.position = position; + parent.addChild(explo); + } + + removeFromParent(); + } + } + + int addDamage(double d) { + if (!canBeDamaged) return 0; + + damage += d; + if (damage >= maxDamage) { + destroy(); + return (maxDamage * 10).ceil(); + } + return 10; + } + + Explosion createExplosion() { + return null; + } + + void paint(PaintingCanvas canvas) { + if (_drawDebug) { + canvas.drawCircle(Point.origin, radius, _paintDebug); + } + super.paint(canvas); + } + + void setupActions() { + } +} + +class Ship extends GameObject { + Ship(GameObjectFactory f) { + // Add main ship sprite + _sprt = new Sprite(f.sheet["ship.png"]); + _sprt.scale = 0.3; + _sprt.rotation = -90.0; + addChild(_sprt); + radius = 20.0; + + canBeDamaged = false; + canDamageShip = false; + + // Set start position + position = new Point(0.0, 50.0); + } + + Sprite _sprt; + + void applyThrust(Point joystickValue, double scroll) { + Point oldPos = position; + Point target = new Point(joystickValue.x * 160.0, joystickValue.y * 220.0 - 250.0 - scroll); + double filterFactor = 0.2; + + position = new Point( + GameMath.filter(oldPos.x, target.x, filterFactor), + GameMath.filter(oldPos.y, target.y, filterFactor)); + } +} + +class Laser extends GameObject { + double impact = 1.0; + + Laser(GameObjectFactory f) { + // Add sprite + _sprt = new Sprite(f.sheet["laser.png"]); + _sprt.scale = 0.3; + _sprt.transferMode = sky.TransferMode.plus; + addChild(_sprt); + radius = 10.0; + removeLimit = 640.0; + + canDamageShip = false; + canBeDamaged = false; + } + + Sprite _sprt; + + void move() { + position += new Offset(0.0, -10.0); + } +} + +abstract class Obstacle extends GameObject { + + Obstacle(this._f); + + double explosionScale = 1.0; + GameObjectFactory _f; + + Explosion createExplosion() { + SoundEffectPlayer.sharedInstance().play(_f.sounds["explosion"]); + Explosion explo = new Explosion(_f.sheet); + explo.scale = explosionScale; + return explo; + } +} + +abstract class Asteroid extends Obstacle { + Asteroid(GameObjectFactory f) : super(f); + + Sprite _sprt; + + void setupActions() { + // Rotate obstacle + int direction = 1; + if (randomBool()) direction = -1; + ActionTween rotate = new ActionTween( + (a) => _sprt.rotation = a, + 0.0, 360.0 * direction, 5.0 + 5.0 * randomDouble()); + _sprt.actions.run(new ActionRepeatForever(rotate)); + } + + set damage(double d) { + super.damage = d; + int alpha = ((200.0 * d) ~/ maxDamage).clamp(0, 200); + _sprt.colorOverlay = new Color.fromARGB(alpha, 255, 3, 86); + } +} + +class AsteroidBig extends Asteroid { + AsteroidBig(GameObjectFactory f) : super(f) { + _sprt = new Sprite(f.sheet["asteroid_big_${randomInt(3)}.png"]); + _sprt.scale = 0.3; + radius = 25.0; + maxDamage = 5.0; + addChild(_sprt); + } +} + +class AsteroidSmall extends Asteroid { + AsteroidSmall(GameObjectFactory f) : super(f) { + _sprt = new Sprite(f.sheet["asteroid_small_${randomInt(3)}.png"]); + _sprt.scale = 0.3; + radius = 12.0; + maxDamage = 3.0; + addChild(_sprt); + } +} + +class MovingEnemy extends Obstacle { + MovingEnemy(GameObjectFactory f) : super(f) { + _sprt = new Sprite(f.sheet["ship.png"]); + _sprt.scale = 0.2; + radius = 12.0; + maxDamage = 2.0; + addChild(_sprt); + + constraints = [new ConstraintRotationToMovement(dampening: 0.5)]; + } + + final double _swirlSpacing = 80.0; + + _addRandomSquare(List offsets, double x, double y) { + double xMove = (randomBool()) ? _swirlSpacing : -_swirlSpacing; + double yMove = (randomBool()) ? _swirlSpacing : -_swirlSpacing; + + if (randomBool()) { + offsets.addAll([ + new Offset(x, y), + new Offset(xMove + x, y), + new Offset(xMove + x, yMove + y), + new Offset(x, yMove + y), + new Offset(x, y) + ]); + } else { + offsets.addAll([ + new Offset(x, y), + new Offset(x, y + yMove), + new Offset(xMove + x, yMove + y), + new Offset(xMove + x, y), + new Offset(x, y) + ]); + } + } + + void setupActions() { + + List offsets = []; + _addRandomSquare(offsets, -_swirlSpacing, 0.0); + _addRandomSquare(offsets, _swirlSpacing, 0.0); + offsets.add(new Offset(-_swirlSpacing, 0.0)); + + List points = []; + for (Offset offset in offsets) { + points.add(position + offset); + } + + ActionSpline spline = new ActionSpline((a) => position = a, points, 6.0); + spline.tension = 0.7; + actions.run(new ActionRepeatForever(spline)); + } + + Sprite _sprt; +} diff --git a/examples/game/lib/repeated_image.dart b/examples/game/lib/repeated_image.dart new file mode 100644 index 00000000000..23010129f7f --- /dev/null +++ b/examples/game/lib/repeated_image.dart @@ -0,0 +1,29 @@ +part of game; + +class RepeatedImage extends Node { + Sprite _sprt0; + Sprite _sprt1; + + RepeatedImage(sky.Image image, [sky.TransferMode mode = null]) { + _sprt0 = new Sprite.fromImage(image); + _sprt0.size = new Size(1024.0, 1024.0); + _sprt0.pivot = Point.origin; + _sprt1 = new Sprite.fromImage(image); + _sprt1.size = new Size(1024.0, 1024.0); + _sprt1.pivot = Point.origin; + _sprt1.position = new Point(0.0, -1024.0); + + if (mode != null) { + _sprt0.transferMode = mode; + _sprt1.transferMode = mode; + } + + addChild(_sprt0); + addChild(_sprt1); + } + + void move(double dy) { + double yPos = (position.y + dy) % 1024.0; + position = new Point(0.0, yPos); + } +} diff --git a/examples/game/lib/star_field.dart b/examples/game/lib/star_field.dart new file mode 100644 index 00000000000..026ad7b4199 --- /dev/null +++ b/examples/game/lib/star_field.dart @@ -0,0 +1,89 @@ +part of game; + +class StarField extends NodeWithSize { + sky.Image _image; + SpriteSheet _spriteSheet; + int _numStars; + bool _autoScroll; + + List _starPositions; + List _starScales; + List _rects; + List _colors; + + final double _padding = 50.0; + Size _paddedSize = Size.zero; + + Paint _paint = new Paint() + ..setFilterQuality(sky.FilterQuality.low) + ..isAntiAlias = false + ..setTransferMode(sky.TransferMode.plus); + + StarField(this._spriteSheet, this._numStars, [this._autoScroll = false]) : super(Size.zero) { + _image = _spriteSheet.image; + } + + void addStars() { + _starPositions = []; + _starScales = []; + _colors = []; + _rects = []; + + size = spriteBox.visibleArea.size; + _paddedSize = new Size(size.width + _padding * 2.0, + size.height + _padding * 2.0); + + for (int i = 0; i < _numStars; i++) { + _starPositions.add(new Point(randomDouble() * _paddedSize.width, + randomDouble() * _paddedSize.height)); + _starScales.add(randomDouble() * 0.4); + _colors.add(new Color.fromARGB((255.0 * (randomDouble() * 0.5 + 0.5)).toInt(), 255, 255, 255)); + _rects.add(_spriteSheet["star_${randomInt(2)}.png"].frame); + } + } + + void spriteBoxPerformedLayout() { + addStars(); + } + + void paint(PaintingCanvas canvas) { + // Create a transform for each star + List transforms = []; + for (int i = 0; i < _numStars; i++) { + sky.RSTransform transform = new sky.RSTransform( + _starScales[i], + 0.0, + _starPositions[i].x - _padding, + _starPositions[i].y - _padding); + + transforms.add(transform); + } + + // Draw the stars + canvas.drawAtlas(_image, transforms, _rects, _colors, sky.TransferMode.modulate, null, _paint); + } + + void move(double dx, double dy) { + for (int i = 0; i < _numStars; i++) { + double xPos = _starPositions[i].x; + double yPos = _starPositions[i].y; + double scale = _starScales[i]; + + xPos += dx * scale; + yPos += dy * scale; + + if (xPos >= _paddedSize.width) xPos -= _paddedSize.width; + if (xPos < 0) xPos += _paddedSize.width; + if (yPos >= _paddedSize.height) yPos -= _paddedSize.height; + if (yPos < 0) yPos += _paddedSize.height; + + _starPositions[i] = new Point(xPos, yPos); + } + } + + void update(double dt) { + if (_autoScroll) { + move(0.0, dt * 100.0); + } + } +}