mirror of
https://github.com/johrpan/christmas_cats.git
synced 2025-10-28 03:07:25 +01:00
Add coins to game
This adds a new asset, a new component and some new game mechanics. Coins will appear every one to two minutes and can be collected by tapping them.
This commit is contained in:
parent
72aa6d7183
commit
03c94fe48c
5 changed files with 258 additions and 0 deletions
146
art/coin.svg
Normal file
146
art/coin.svg
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="12.700001mm"
|
||||||
|
height="12.7mm"
|
||||||
|
viewBox="0 0 12.700001 12.7"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||||
|
sodipodi:docname="coin.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.2"
|
||||||
|
inkscape:cx="46.064289"
|
||||||
|
inkscape:cy="36.680608"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1016"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-94.676527,-139.76874)">
|
||||||
|
<circle
|
||||||
|
style="fill:#ffcc00;fill-opacity:1;stroke:#000000;stroke-width:0.5291667;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4524"
|
||||||
|
cx="101.02653"
|
||||||
|
cy="146.11874"
|
||||||
|
r="6.0854168" />
|
||||||
|
<circle
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.02374466;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="circle6443"
|
||||||
|
cx="101.55569"
|
||||||
|
cy="146.11874"
|
||||||
|
r="4.2333331" />
|
||||||
|
<circle
|
||||||
|
r="4.2333331"
|
||||||
|
cy="146.11874"
|
||||||
|
cx="100.49736"
|
||||||
|
id="circle6441"
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.02374466;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
style="fill:#ffe680;fill-opacity:1;stroke:none;stroke-width:0.02374466;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4522"
|
||||||
|
cx="101.02653"
|
||||||
|
cy="146.11874"
|
||||||
|
r="4.2333331" />
|
||||||
|
<g
|
||||||
|
id="g7849"
|
||||||
|
style="fill:#c9a100;fill-opacity:1"
|
||||||
|
transform="translate(0,0.52916667)">
|
||||||
|
<ellipse
|
||||||
|
ry="0.26458335"
|
||||||
|
rx="0.26458332"
|
||||||
|
cy="145.61581"
|
||||||
|
cx="100.54639"
|
||||||
|
id="path7822"
|
||||||
|
style="fill:#c9a100;fill-opacity:1;stroke:none;stroke-width:0.5291667;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
r="0.26458332"
|
||||||
|
cy="145.75754"
|
||||||
|
cx="101.79843"
|
||||||
|
id="path7824"
|
||||||
|
style="fill:#c9a100;fill-opacity:1;stroke:none;stroke-width:0.52916658;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g7845"
|
||||||
|
style="stroke:#c9a100;stroke-opacity:1"
|
||||||
|
transform="translate(0,0.52916667)">
|
||||||
|
<path
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-filename="/home/johrpan/Projekte/jolakotturinn/assets/images/cat6s.png"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path1178-6"
|
||||||
|
d="m 99.07953,146.84377 c 0,0 -0.24582,-0.85541 0.28092,-1.32675 0,0 0.0176,-4.45166 1.15876,-1.06491 0,0 1.05343,0.40154 1.40459,0.22696 0,0 2.3,-3.19472 1.26411,0.80303 0,0 0.40382,1.13475 -0.31602,1.90286 -2.47717,2.02429 -3.79236,-0.54119 -3.79236,-0.54119 z"
|
||||||
|
style="fill:none;stroke:#c9a100;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path7826"
|
||||||
|
d="m 100.0692,146.54185 -1.842639,-1.12212"
|
||||||
|
style="fill:none;stroke:#c9a100;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path7828"
|
||||||
|
d="m 99.951078,146.84896 -1.724517,-0.47247"
|
||||||
|
style="fill:none;stroke:#c9a100;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path7830"
|
||||||
|
d="m 100.10463,147.10882 -1.559151,0.16536"
|
||||||
|
style="fill:none;stroke:#c9a100;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path7832"
|
||||||
|
d="m 102.05357,146.73084 2.03162,-0.57878"
|
||||||
|
style="fill:none;stroke:#c9a100;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path7834"
|
||||||
|
d="m 101.95908,147.08519 1.88988,0.12993"
|
||||||
|
style="fill:none;stroke:#c9a100;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path7836"
|
||||||
|
d="m 101.6756,147.36867 1.22842,0.72052"
|
||||||
|
style="fill:none;stroke:#c9a100;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.6 KiB |
BIN
assets/images/coin.png
Normal file
BIN
assets/images/coin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
75
lib/components/coin.dart
Normal file
75
lib/components/coin.dart
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
import 'components/cat.dart';
|
import 'components/cat.dart';
|
||||||
|
import 'components/coin.dart';
|
||||||
import 'components/tree.dart';
|
import 'components/tree.dart';
|
||||||
import 'localizations.dart';
|
import 'localizations.dart';
|
||||||
|
|
||||||
|
|
@ -30,6 +31,7 @@ class Cell {
|
||||||
|
|
||||||
Tree tree;
|
Tree tree;
|
||||||
Cat cat;
|
Cat cat;
|
||||||
|
Coin coin;
|
||||||
|
|
||||||
Cell(this.x, this.y);
|
Cell(this.x, this.y);
|
||||||
}
|
}
|
||||||
|
|
@ -65,6 +67,7 @@ class ChristmasCats extends BaseGame with Tapable {
|
||||||
bool gameOver = false;
|
bool gameOver = false;
|
||||||
|
|
||||||
Timer nextCatTimer;
|
Timer nextCatTimer;
|
||||||
|
Timer coinTimer;
|
||||||
Timer scoreTimer;
|
Timer scoreTimer;
|
||||||
List<Cell> cells;
|
List<Cell> cells;
|
||||||
List<int> treeCells;
|
List<int> 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) {
|
void updateCat(int oldCellIndex, Cat cat) {
|
||||||
int newCellIndex;
|
int newCellIndex;
|
||||||
|
|
||||||
|
|
@ -150,6 +159,26 @@ class ChristmasCats extends BaseGame with Tapable {
|
||||||
nCats++;
|
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() {
|
void reset() {
|
||||||
paused = true;
|
paused = true;
|
||||||
nCats = 0;
|
nCats = 0;
|
||||||
|
|
@ -208,6 +237,7 @@ class ChristmasCats extends BaseGame with Tapable {
|
||||||
}
|
}
|
||||||
|
|
||||||
createCat();
|
createCat();
|
||||||
|
createCoin();
|
||||||
|
|
||||||
for (final tree in trees) {
|
for (final tree in trees) {
|
||||||
add(tree);
|
add(tree);
|
||||||
|
|
@ -238,6 +268,7 @@ class ChristmasCats extends BaseGame with Tapable {
|
||||||
void update(double t) {
|
void update(double t) {
|
||||||
if (!paused) {
|
if (!paused) {
|
||||||
nextCatTimer?.update(t);
|
nextCatTimer?.update(t);
|
||||||
|
coinTimer?.update(t);
|
||||||
scoreTimer?.update(t);
|
scoreTimer?.update(t);
|
||||||
|
|
||||||
final List<Timer> oldTimers = [];
|
final List<Timer> oldTimers = [];
|
||||||
|
|
@ -285,6 +316,11 @@ class ChristmasCats extends BaseGame with Tapable {
|
||||||
}
|
}
|
||||||
|
|
||||||
onScoreChanged(score);
|
onScoreChanged(score);
|
||||||
|
} else if (cell?.coin != null) {
|
||||||
|
cell.coin.tap();
|
||||||
|
if (cell.cat == null) {
|
||||||
|
emptyCells.add(cellIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ flutter:
|
||||||
- assets/images/cat6s.png
|
- assets/images/cat6s.png
|
||||||
- assets/images/cat7r.png
|
- assets/images/cat7r.png
|
||||||
- assets/images/cat7s.png
|
- assets/images/cat7s.png
|
||||||
|
- assets/images/coin.png
|
||||||
- assets/images/tree1.png
|
- assets/images/tree1.png
|
||||||
- assets/images/tree2.png
|
- assets/images/tree2.png
|
||||||
- assets/images/tree3.png
|
- assets/images/tree3.png
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue