Chromium Code Reviews| Index: sky/examples/game/lib/game_demo_world.dart |
| diff --git a/sky/examples/game/lib/game_demo_world.dart b/sky/examples/game/lib/game_demo_world.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4344df19f0f62ef90d7035c84f46f99ab4befd7d |
| --- /dev/null |
| +++ b/sky/examples/game/lib/game_demo_world.dart |
| @@ -0,0 +1,285 @@ |
| +part of game; |
| + |
| +// Random generator |
| +Math.Random _rand = new Math.Random(); |
| + |
| +const double _gameSizeWidth = 1024.0; |
| +const double _gameSizeHeight = 1024.0; |
| + |
| +const double _shipRadius = 30.0; |
| +const double _lrgAsteroidRadius = 40.0; |
| +const double _medAsteroidRadius = 20.0; |
| +const double _smlAsteroidRadius = 10.0; |
| +const double _maxAsteroidSpeed = 1.0; |
| + |
| +const int _lifeTimeLaser = 50; |
| + |
| +class GameDemoWorld extends NodeWithSize { |
| + |
| + // Images |
| + Image _imgBg; |
| + Image _imgAsteroid; |
| + Image _imgShip; |
| + Image _imgLaser; |
| + |
| + // Inputs |
| + double _joystickX = 0.0; |
| + double _joystickY = 0.0; |
| + bool _fire; |
| + |
| + Ship _ship; |
| + List<Asteroid> _asteroids = []; |
| + List<Laser> _lasers = []; |
| + |
| + GameDemoWorld(ImageMap images) : super.withSize(new Size(_gameSizeWidth, _gameSizeHeight)) { |
| + |
| + // 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"]; |
| + _imgLaser = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/laserBlue.png"]; |
| + |
| + // Add some asteroids to the game world |
| + for (int i = 0; i < 5; i++) { |
| + addAsteroid(AsteroidSize.large); |
| + } |
| + for (int i = 0; i < 5; i++) { |
| + addAsteroid(AsteroidSize.medium); |
| + } |
| + |
| + // Add ship |
| + addShip(); |
| + } |
| + |
| + // Methods for adding game objects |
| + |
| + void addBackground() { |
| + Sprite sprtBg = new Sprite.withImage(_imgBg); |
| + sprtBg.size = new Size(_gameSizeWidth, _gameSizeHeight); |
| + sprtBg.pivot = Point.origin; |
| + this.addChild(sprtBg); |
| + } |
| + |
| + void addAsteroid(AsteroidSize size, [Point pos]) { |
| + Asteroid asteroid = new Asteroid.withImage(_imgAsteroid, size); |
| + asteroid.zPosition = 1.0; |
| + if (pos != null) asteroid.position = pos; |
| + this.addChild(asteroid); |
| + _asteroids.add(asteroid); |
| + } |
| + |
| + void addShip() { |
| + Ship ship = new Ship.withImage(_imgShip); |
| + ship.zPosition = 10.0; |
| + this.addChild(ship); |
| + _ship = ship; |
| + } |
| + |
| + void addLaser() { |
| + Laser laser = new Laser.withImage(_imgLaser, _ship); |
| + laser.zPosition = 8.0; |
| + _lasers.add(laser); |
| + this.addChild(laser); |
| + } |
| + |
| + void update(double dt) { |
| + // Move asteroids |
| + for (Asteroid asteroid in _asteroids) { |
| + asteroid.position = pointAdd(asteroid.position, asteroid._movementVector); |
| + } |
| + |
| + // Move lasers and remove expired lasers |
| + for (int i = _lasers.length - 1; i >= 0; i--) { |
| + Laser laser = _lasers[i]; |
| + laser.move(); |
| + if (laser._frameCount > _lifeTimeLaser) { |
| + laser.removeFromParent(); |
| + _lasers.removeAt(i); |
| + } |
| + } |
| + |
| + // Apply thrust to ship |
| + if (_joystickX != 0.0 || _joystickY != 0.0) { |
| + _ship.thrust(_joystickX, _joystickY); |
| + } |
| + |
| + // Move ship |
| + _ship.move(); |
| + |
| + // Check collisions between asteroids and lasers |
| + for (int i = _lasers.length -1; i >= 0; i--) { |
| + // Iterate over all the lasers |
| + Laser laser = _lasers[i]; |
| + |
| + for (int j = _asteroids.length - 1; j >= 0; j--) { |
| + // Iterate over all the asteroids |
| + Asteroid asteroid = _asteroids[j]; |
| + |
| + // Check for collision |
| + if (pointQuickDist(laser.position, asteroid.position) < laser.radius + asteroid.radius) { |
| + // Remove laser |
| + laser.removeFromParent(); |
| + _lasers.removeAt(i); |
| + |
| + // Add asteroids |
| + if (asteroid._asteroidSize == AsteroidSize.large) { |
| + for (int a = 0; a < 3; a++) addAsteroid(AsteroidSize.medium, asteroid.position); |
| + } |
| + else if (asteroid._asteroidSize == AsteroidSize.medium) { |
| + for (int a = 0; a < 5; a++) addAsteroid(AsteroidSize.small, asteroid.position); |
| + } |
| + |
| + // Remove asteroid |
| + asteroid.removeFromParent(); |
| + _asteroids.removeAt(j); |
| + break; |
| + } |
| + } |
| + } |
| + |
| + // Move objects to center camera and warp objects around the edges |
| + centerCamera(); |
| + warpObjects(); |
| + } |
| + |
| + void centerCamera() { |
| + const cameraDampening = 0.1; |
| + Point delta = new Point(_gameSizeWidth/2 - _ship.position.x, _gameSizeHeight/2 - _ship.position.y); |
| + delta = pointMult(delta, cameraDampening); |
| + |
| + for (Node child in children) { |
| + child.position = pointAdd(child.position, delta); |
| + } |
| + } |
| + |
| + void warpObjects() { |
| + for (Node child in children) { |
| + if (child.position.x < 0) child.position = pointAdd(child.position, new Point(_gameSizeWidth, 0.0)); |
| + if (child.position.x >= _gameSizeWidth) child.position = pointAdd(child.position, new Point(-_gameSizeWidth, 0.0)); |
| + if (child.position.y < 0) child.position = pointAdd(child.position, new Point(0.0, _gameSizeHeight)); |
| + if (child.position.y >= _gameSizeHeight) child.position = pointAdd(child.position, new Point(0.0, -_gameSizeHeight)); |
| + } |
| + } |
| + |
| + // Handling controls |
| + |
| + void controlSteering(double x, double y) { |
| + _joystickX = x; |
| + _joystickY = y; |
| + } |
| + |
| + void controlFire() { |
| + addLaser(); |
| + } |
| +} |
| + |
| +// Game objects |
| + |
| +enum AsteroidSize { |
| + small, |
| + medium, |
| + large, |
| +} |
| + |
| +class Asteroid extends Sprite { |
| + Point _movementVector; |
| + AsteroidSize _asteroidSize; |
| + double _radius; |
| + |
| + double get radius { |
| + if (_radius != null) return _radius; |
| + if (_asteroidSize == AsteroidSize.small) _radius = _smlAsteroidRadius; |
| + else if (_asteroidSize == AsteroidSize.medium) _radius = _medAsteroidRadius; |
| + else if (_asteroidSize == AsteroidSize.large) _radius = _lrgAsteroidRadius; |
| + return _radius; |
| + } |
| + |
| + Asteroid.withImage(Image img, AsteroidSize this._asteroidSize) : super.withImage(img) { |
| + size = new Size(radius * 2.0, radius * 2.0); |
| + position = new Point(_gameSizeWidth * _rand.nextDouble(), _gameSizeHeight * _rand.nextDouble()); |
| + rotation = 360.0 * _rand.nextDouble(); |
| + |
| + _movementVector = new Point(_rand.nextDouble() * _maxAsteroidSpeed * 2 - _maxAsteroidSpeed, |
| + _rand.nextDouble() * _maxAsteroidSpeed * 2 - _maxAsteroidSpeed); |
| + } |
| +} |
| + |
| +class Ship extends Sprite { |
| + Vector2 _movementVector; |
| + double _rotationTarget; |
| + |
| + Ship.withImage(Image img) : super.withImage(img) { |
| + _movementVector = new Vector2.zero(); |
| + rotation = _rotationTarget = 270.0; |
| + |
| + // Create sprite |
| + size = new Size(_shipRadius * 2.0, _shipRadius * 2.0); |
| + position = new Point(_gameSizeWidth/2.0, _gameSizeHeight/2.0); |
| + } |
| + |
| + void thrust(double x, double y) { |
| + _rotationTarget = convertRadians2Degrees(Math.atan2(y, x)); |
| + Vector2 directionVector = new Vector2(x, y).normalize(); |
| + _movementVector.addScaled(directionVector, 1.0); |
| + } |
| + |
| + void move() { |
| + position = new Point(position.x + _movementVector[0], position.y + _movementVector[1]); |
| + _movementVector.scale(0.9); |
| + |
| + rotation = dampenRotation(rotation, _rotationTarget, 0.1); |
| + } |
| +} |
| + |
| +class Laser extends Sprite { |
| + int _frameCount = 0; |
| + Point _movementVector; |
| + double radius = 10.0; |
| + |
| + Laser.withImage(Image img, Ship ship) : super.withImage(img) { |
| + size = new Size(20.0, 20.0); |
| + position = ship.position; |
| + rotation = ship.rotation + 90.0; |
| + transferMode = TransferMode.plusMode; |
| + double rotRadians = convertDegrees2Radians(rotation); |
| + _movementVector = pointMult(new Point(Math.sin(rotRadians), -Math.cos(rotRadians)), 10.0); |
| + _movementVector = new Point(_movementVector.x + ship._movementVector[0], _movementVector.y + ship._movementVector[1]); |
| + } |
| + |
| + bool move() { |
| + position = pointAdd(position, _movementVector); |
| + _frameCount++; |
| + } |
| +} |
| + |
| +// Convenience methods |
| + |
| +Point pointAdd(Point a, Point b) { |
| + return new Point(a.x+ b.x, a.y + b.y); |
| +} |
|
abarth-chromium
2015/06/13 00:03:20
We have an operator+ for Point and Size. I wonder
|
| + |
| +Point pointMult(Point a, double multiplier) { |
| + return new Point(a.x * multiplier, a.y * multiplier); |
| +} |
|
abarth-chromium
2015/06/13 00:03:20
We should just add this to Point.dart
|
| + |
| +double dampenRotation(double src, double dst, double dampening) { |
| + double delta = dst - src; |
| + while (delta > 180.0) delta -= 360; |
| + while (delta < -180) delta += 360; |
| + delta *= dampening; |
| + |
| + return src + delta; |
| +} |
| + |
| +double pointQuickDist(Point a, Point b) { |
| + double dx = a.x - b.x; |
| + double dy = a.y - b.y; |
| + if (dx < 0.0) dx = -dx; |
| + if (dy < 0.0) dy = -dy; |
| + if (dx > dy) { |
| + return dx + dy/2.0; |
| + } |
| + else { |
| + return dy + dx/2.0; |
| + } |
| +} |