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

Unified Diff: samples/pop_pop_win/lib/src/stage/game_element.dart

Issue 242443008: samples/pop_pop_win: now based on StageXL (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: tiny nit Created 6 years, 8 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: samples/pop_pop_win/lib/src/stage/game_element.dart
diff --git a/samples/pop_pop_win/lib/src/stage/game_element.dart b/samples/pop_pop_win/lib/src/stage/game_element.dart
new file mode 100644
index 0000000000000000000000000000000000000000..3bceeb4f5677533ac42af3e8e49c902bcb96e782
--- /dev/null
+++ b/samples/pop_pop_win/lib/src/stage/game_element.dart
@@ -0,0 +1,311 @@
+library pop_pop_win.stage.game_element;
+
+import 'dart:async';
+import 'dart:math';
+
+import 'package:bot/bot.dart' show Size, Vector, Tuple;
+import 'package:stagexl/stagexl.dart' hide Vector, Point;
+
+import 'package:pop_pop_win/src/audio.dart';
+import 'package:pop_pop_win/src/game.dart';
+
+import 'board_element.dart';
+import 'game_background_element.dart';
+import 'game_root.dart';
+import 'score_element.dart';
+import 'square_element.dart';
+
+class GameElement extends Sprite {
+ static const _edgeOffset = 32;
+ static const _backgroundSize = const Size(2048, 1536);
+ static const _backgroundHoleSize = 16 * SquareElement.SIZE + 2 * _edgeOffset;
+ static const BOARD_OFFSET = const Vector(352, 96);
+ static const _popAnimationHitFrame = 12;
+ static const _popExplodeAnimationOffset = const Vector(-88, -88);
+ static const _dartAnimationOffset =
+ const Vector(-512 + 0.5 * SquareElement.SIZE,
+ -388 + 0.5 * SquareElement.SIZE);
+
+ final GameRoot manager;
+
+ final Random _rnd = new Random();
+
+ GameBackgroundElement _gameBackground;
+ BoardElement _boardElement;
+ ScoreElement _scoreElement;
+ SimpleButton _newGameButton, _logoButton;
+ Sprite _popLayer = new Sprite(), _dartLayer = new Sprite();
+
+ num _boardSize, _boardScale;
+
+
+ int _targetX, _targetY;
+ TextureAtlas _animations;
+
+ Game get game => manager.game;
+ ResourceManager get resourceManager => manager.resourceManager;
+
+ num get boardSize => _boardSize;
+ num get boardScale => _boardScale;
+
+ ScoreElement get scoreElement => _scoreElement;
+ BoardElement get boardElement => _boardElement;
+
+ GameElement(this.manager) {
+ TextureAtlas opa = resourceManager.getTextureAtlas('opaque');
+ TextureAtlas sta = resourceManager.getTextureAtlas('static');
+ _animations = resourceManager.getTextureAtlas('animated');
+
+ _boardSize = game.field.width * SquareElement.SIZE + 2 * _edgeOffset;
+ _boardScale = _backgroundHoleSize / _boardSize;
+
+ _gameBackground = new GameBackgroundElement(this, opa);
+
+ var newButtonNormal = new Bitmap(sta.getBitmapData("button_new_game"));
+ var newButtonPressed =
+ new Bitmap(sta.getBitmapData("button_new_game_clicked"));
+
+ _newGameButton = new SimpleButton(newButtonNormal, newButtonPressed,
+ newButtonPressed, newButtonPressed)
+ ..x = 450
+ ..y = 20
+ ..onMouseClick.listen((e) {
+ GameAudio.click();
+ manager.newGame();
+ })
+ ..addTo(this);
+
+ _boardElement = new BoardElement(this)
+ ..x = BOARD_OFFSET.x + _edgeOffset * _boardScale
+ ..y = BOARD_OFFSET.y + _edgeOffset * _boardScale;
+
+
+ manager.bestTimeMilliseconds.then((v) {
+ if (v == null) v = 0;
+ _scoreElement = new ScoreElement(v)..addTo(this);
+
+ stage.juggler.add(_scoreElement);
+
+ });
+
+ num logoScale = min(max(_boardScale, 1.1), 1.5);
+ Bitmap logo = new Bitmap(sta.getBitmapData('logo_win'));
+ _logoButton = new SimpleButton(logo, logo, logo, logo);
+ _logoButton
+ ..y = 20
+ ..scaleX = logoScale
+ ..scaleY = logoScale
+ ..x = _backgroundSize.width / 2 - _logoButton.width / 2
+ ..onMouseClick.listen((e) => _titleClickedEventHandle.add(null))
+ ..addTo(this);
+
+ _popLayer
+ ..mouseEnabled = false
+ ..x = BOARD_OFFSET.x + _edgeOffset * _boardScale
+ ..y = BOARD_OFFSET.y + _edgeOffset * _boardScale
+ ..scaleX = _boardScale
+ ..scaleY = _boardScale
+ ..addTo(this);
+
+ _dartLayer
+ ..mouseEnabled = false
+ ..x = BOARD_OFFSET.x + _edgeOffset * _boardScale
+ ..y = BOARD_OFFSET.y + _edgeOffset * _boardScale
+ ..scaleX = _boardScale
+ ..scaleY = _boardScale
+ ..addTo(this);
+
+ }
+
+ bool get canRevealTarget =>
+ _targetX != null && game.canReveal(_targetX, _targetY);
+
+ bool get canFlagTarget =>
+ _targetX != null && game.canToggleFlag(_targetX, _targetY);
+
+ void revealTarget() {
+ if (_targetX != null) {
+ game.reveal(_targetX, _targetY);
+ }
+ }
+
+ void click(int x, int y, bool alt) {
+ assert(!game.gameEnded);
+ final ss = game.getSquareState(x, y);
+
+ List<Point> reveals = null;
+
+ if (alt) {
+ if (ss == SquareState.hidden || ss == SquareState.flagged) {
+ _toggleFlag(x, y);
+ } else if (ss == SquareState.revealed) {
+ if (game.canReveal(x, y)) {
+ // get adjacent ballons
+ final adjHidden = game.field.getAdjacentIndices(x, y)
+ .map((i) {
+ final t = game.field.getCoordinate(i);
+ return new Point(t.item1, t.item2);
+ })
+ .where((t) => game.getSquareState(t.x, t.y) == SquareState.hidden)
+ .toList();
+
+ assert(adjHidden.length > 0);
+
+ _startDartAnimation(adjHidden);
+ reveals = game.reveal(x, y);
+ }
+ }
+ } else {
+ if (ss == SquareState.hidden) {
+ _startDartAnimation([new Point(x, y)]);
+ reveals = game.reveal(x, y);
+ }
+ }
+
+ if (reveals != null && reveals.length > 0) {
+ assert(game.state != GameState.lost);
+ if (!alt) {
+ // if it was a normal click, the first item should be the clicked item
+ var first = reveals[0];
+ assert(first.x == x);
+ assert(first.y == y);
+ }
+ _startPopAnimation(new Point(x, y), reveals);
+ } else if (game.state == GameState.lost) {
+ _startPopAnimation(new Point(x, y));
+ }
+ }
+
+ bool _toggleFlag(int x, int y) {
+ assert(!game.gameEnded);
+ final se = _boardElement.squares.get(x, y);
+ final ss = se.squareState;
+ if (ss == SquareState.hidden) {
+ game.setFlag(x, y, true);
+ se.updateState();
+ GameAudio.flag();
+ return true;
+ } else if (ss == SquareState.flagged) {
+ game.setFlag(x, y, false);
+ se.updateState();
+ GameAudio.unflag();
+ return true;
+ }
+ return false;
+ }
+
+ void _startPopAnimation(Point start, [Iterable<Point> reveals = null]) {
+ if (reveals == null) {
+ assert(game.state == GameState.lost);
+ reveals = new Iterable.generate(game.field.length)
+ .map((i) {
+ var t = game.field.getCoordinate(i);
+ var c = new Point(t.item1, t.item2);
+ return new Tuple(c, game.getSquareState(c.x, c.y));
+ })
+ .where((t2) => t2.item2 == SquareState.bomb ||
+ t2.item2 == SquareState.hidden)
+ .map((t2) => t2.item1)
+ .toList();
+ }
+
+ final values = reveals.map((c) {
+ var initialOffset =
+ new Vector(SquareElement.SIZE * c.x, SquareElement.SIZE * c.y);
+ var squareOffset = _popExplodeAnimationOffset + initialOffset;
+
+ var delay = _popAnimationHitFrame + ((c - start).magnitude * 4).toInt();
+ delay += _rnd.nextInt(10);
+
+ return [c, initialOffset, squareOffset, delay];
+ }).toList();
+
+ values.sort((a, b) {
+ int da = a[3];
+ int db = b[3];
+ return da.compareTo(db);
+ });
+
+ for (var v in values) {
+ Point c = v[0];
+ Vector initialOffset = v[1];
+ Vector squareOffset = v[2];
+ int delay = v[3];
+
+ var se = _boardElement.squares.get(c.x, c.y);
+ var ss = se.squareState;
+
+ var texturePrefix = ss == SquareState.bomb ?
+ 'balloon_explode' : 'balloon_pop';
+
+ var anim = new FlipBook(_animations.getBitmapDatas(texturePrefix),
+ stage.frameRate, false)
+ ..x = squareOffset.x
+ ..y = squareOffset.y
+ ..alpha = 0
+ ..mouseEnabled = false
+ ..addTo(_popLayer);
+
+ anim.onComplete.listen((e) => anim.removeFromParent());
+
+ stage.juggler
+ ..add(anim)
+ ..delayCall(() => _animationDelay(anim, se, ss),
+ delay / stage.frameRate);
+ }
+ }
+
+ void _startDartAnimation(List<Point> points) {
+ assert(points.length >= 1);
+ GameAudio.throwDart();
+ for (var point in points) {
+ var squareOffset = _dartAnimationOffset +
+ new Vector(SquareElement.SIZE * point.x,
+ SquareElement.SIZE * point.y);
+
+ var dart = new FlipBook(_animations.getBitmapDatas('dart'),
+ stage.frameRate, false)
+ ..x = squareOffset.x
+ ..y = squareOffset.y
+ ..mouseEnabled = false
+ ..play()
+ ..addTo(_dartLayer);
+
+ dart.onComplete.listen((e) => dart.removeFromParent());
+
+ var shadow = new FlipBook(_animations.getBitmapDatas('shadow'),
+ stage.frameRate, false)
+ ..x = squareOffset.x
+ ..y = squareOffset.y
+ ..mouseEnabled = false
+ ..play()
+ ..addTo(_dartLayer);
+
+ shadow.onComplete.listen((e) => shadow.removeFromParent());
+
+ stage.juggler
+ ..add(dart)
+ ..add(shadow);
+ }
+ }
+}
+
+void _animationDelay(FlipBook anim, SquareElement se, SquareState ss) {
+ anim
+ ..alpha = 1
+ ..play();
+ se.updateState();
+ switch (ss) {
+ case SquareState.revealed:
+ case SquareState.hidden:
+ GameAudio.pop();
+ break;
+ case SquareState.bomb:
+ GameAudio.bomb();
+ break;
+ }
+}
+
+final StreamController _titleClickedEventHandle = new StreamController();
+
+Stream get titleClickedEvent => _titleClickedEventHandle.stream;
« no previous file with comments | « samples/pop_pop_win/lib/src/stage/game_background_element.dart ('k') | samples/pop_pop_win/lib/src/stage/game_root.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698