diff --git a/art/coin.svg b/art/coin.svg new file mode 100644 index 0000000..cd20859 --- /dev/null +++ b/art/coin.svg @@ -0,0 +1,146 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/coin.png b/assets/images/coin.png new file mode 100644 index 0000000..34c7bf8 Binary files /dev/null and b/assets/images/coin.png differ diff --git a/lib/components/coin.dart b/lib/components/coin.dart new file mode 100644 index 0000000..a07b2f9 --- /dev/null +++ b/lib/components/coin.dart @@ -0,0 +1,75 @@ +import 'dart:ui'; + +import 'package:flame/anchor.dart'; +import 'package:flame/components/component.dart'; +import 'package:flame/sprite.dart'; +import 'package:flame/time.dart'; +import 'package:flutter/widgets.dart'; +import 'package:vector_math/vector_math_64.dart'; + +import '../storage.dart'; + +class Coin extends PositionComponent { + static const flightTime = 0.8; + + final sprite = Sprite('coin.png'); + final Vector2 position; + final Vector2 target; + + Timer killTimer; + bool shouldDestroy = false; + + bool flying = false; + double flight = 0.0; + + Coin(this.position, this.target, void Function() onDestroy) { + x = position.x; + y = position.y; + width = 24.0; + height = 24.0; + anchor = Anchor.center; + + killTimer = Timer(2.5, callback: () { + onDestroy(); + shouldDestroy = true; + }); + + killTimer.start(); + } + + void tap() { + killTimer.stop(); + flying = true; + storage.addCoins(1); + } + + @override + void render(Canvas c) { + prepareCanvas(c); + sprite.render(c, width: width, height: height); + } + + @override + void update(double t) { + killTimer.update(t); + + if (flying) { + flight += t / flightTime; + + if (flight > 1.0) { + flight = 1.0; + flying = false; + shouldDestroy = true; + } + + x = lerpDouble(position.x, target.x, Curves.easeIn.transform(flight)); + y = lerpDouble(position.y, target.y, Curves.easeInBack.transform(flight)); + } + } + + @override + bool destroy() => shouldDestroy; + + @override + int priority() => 25000; +} diff --git a/lib/game.dart b/lib/game.dart index dcb4474..c10e66d 100644 --- a/lib/game.dart +++ b/lib/game.dart @@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart'; import 'package:vector_math/vector_math_64.dart'; import 'components/cat.dart'; +import 'components/coin.dart'; import 'components/tree.dart'; import 'localizations.dart'; @@ -30,6 +31,7 @@ class Cell { Tree tree; Cat cat; + Coin coin; Cell(this.x, this.y); } @@ -65,6 +67,7 @@ class ChristmasCats extends BaseGame with Tapable { bool gameOver = false; Timer nextCatTimer; + Timer coinTimer; Timer scoreTimer; List cells; List treeCells; @@ -98,6 +101,12 @@ class ChristmasCats extends BaseGame with Tapable { } } + Vector2 getCoinPosition(Cell cell) { + final x = marginLRB + (cell.x + 0.5) * cellWidth; + final y = marginTop + (cell.y + 0.5) * cellHeight; + return Vector2(x, y); + } + void updateCat(int oldCellIndex, Cat cat) { int newCellIndex; @@ -150,6 +159,26 @@ class ChristmasCats extends BaseGame with Tapable { nCats++; } + void createCoin() { + coinTimer = Timer(60.0 + random.nextInt(60), callback: () { + final cellIndex = emptyCells.pick(); + final cell = cells[cellIndex]; + final coin = Coin( + getCoinPosition(cell), + Vector2(size.width / 2, -cellHeight), + () { + cell.coin = null; + }, + ); + + add(coin); + cell.coin = coin; + + createCoin(); + }); + coinTimer.start(); + } + void reset() { paused = true; nCats = 0; @@ -208,6 +237,7 @@ class ChristmasCats extends BaseGame with Tapable { } createCat(); + createCoin(); for (final tree in trees) { add(tree); @@ -238,6 +268,7 @@ class ChristmasCats extends BaseGame with Tapable { void update(double t) { if (!paused) { nextCatTimer?.update(t); + coinTimer?.update(t); scoreTimer?.update(t); final List oldTimers = []; @@ -285,6 +316,11 @@ class ChristmasCats extends BaseGame with Tapable { } onScoreChanged(score); + } else if (cell?.coin != null) { + cell.coin.tap(); + if (cell.cat == null) { + emptyCells.add(cellIndex); + } } } } diff --git a/pubspec.yaml b/pubspec.yaml index 61764e1..f536a97 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ flutter: - assets/images/cat6s.png - assets/images/cat7r.png - assets/images/cat7s.png + - assets/images/coin.png - assets/images/tree1.png - assets/images/tree2.png - assets/images/tree3.png