Added level scaling and animations as Firo coins are gathered #4. Also Tightened the controls on mobile to make user input faster.

This commit is contained in:
Marco Salazar 2021-10-01 20:46:44 -06:00
parent e8455500da
commit 91e5554105
6 changed files with 267 additions and 84 deletions

View File

@ -50,7 +50,7 @@ class CoinHolder extends Holder {
}
void renderCoinScore(Canvas c) {
sprite.position = Vector2(personalGameRef.size.x - 33, 10);
sprite.position = Vector2(personalGameRef.size.x - 70, 10);
sprite.render(c);
}

View File

@ -87,6 +87,23 @@ class GameState extends Component {
}
}
int getDangerLevel() {
int score = getScore();
if (score > LEVEL2 / 2 + LEVEL2 / (2 * 4)) {
return 5;
} else if (score > LEVEL2 / 2) {
return 4;
} else if (score > LEVEL2 / 2 - LEVEL2 / (2 * 4)) {
return 3;
} else if (score > LEVEL2 / 2 - 2 * LEVEL2 / (2 * 4)) {
return 2;
} else if (score > LEVEL2 / 2 - 3 * LEVEL2 / (2 * 4)) {
return 1;
} else {
return 0;
}
}
int getScore() {
return distance ~/ 10 + numCoins * 1000000;
}
@ -103,22 +120,32 @@ class GameState extends Component {
if (!isPaused) {
switch (getLevel()) {
case 7:
return gameRef.viewport.canvasSize.x * 0.25;
return gameRef.viewport.canvasSize.x * 0.28;
case 6:
return gameRef.viewport.canvasSize.x * 0.20;
return gameRef.viewport.canvasSize.x * 0.26;
case 5:
return gameRef.viewport.canvasSize.x * 0.18;
return gameRef.viewport.canvasSize.x * 0.24;
case 4:
return gameRef.viewport.canvasSize.x * 0.16;
return gameRef.viewport.canvasSize.x * 0.22;
case 3:
return gameRef.viewport.canvasSize.x * 0.14;
return gameRef.viewport.canvasSize.x * 0.20;
case 2:
return gameRef.viewport.canvasSize.x * 0.12;
return gameRef.viewport.canvasSize.x * 0.18;
default:
return gameRef.viewport.canvasSize.x * 0.1;
return gameRef.viewport.canvasSize.x * 0.16;
}
} else {
return 0;
}
}
int getRobotLevel() {
if (numCoins > COINS_ROBOT_UPGRADE2) {
return 3;
} else if (numCoins > COINS_ROBOT_UPGRADE1) {
return 2;
} else {
return 1;
}
}
}

View File

@ -53,9 +53,9 @@ class LoseMenuOverlay extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
" Main Menu ",
" MAIN MENU ",
style: TextStyle(
color: Colors.white,
color: Colors.cyan,
fontSize: width * 0.03,
),
),
@ -83,9 +83,9 @@ class LoseMenuOverlay extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
" Replay ",
" REPLAY ",
style: TextStyle(
color: Colors.white,
color: Colors.cyan,
fontSize: width * 0.03,
),
),

View File

@ -34,12 +34,15 @@ import 'package:firo_runner/main_menu_overlay.dart';
const COLOR = Color(0xFFDDC0A3);
const int LOADING_TIME = 2000000;
const LEVEL2 = 10000000;
const LEVEL3 = 20000000;
const LEVEL4 = 30000000;
const LEVEL5 = 40000000;
const LEVEL6 = 50000000;
const LEVEL7 = 60000000;
const LEVEL2 = 25000000;
const LEVEL3 = 50000000;
const LEVEL4 = 75000000;
const LEVEL5 = 100000000;
const LEVEL6 = 125000000;
const LEVEL7 = 150000000;
const COINS_ROBOT_UPGRADE1 = 50;
const COINS_ROBOT_UPGRADE2 = 100;
const OVERLAY_PRIORITY = 110;
const RUNNER_PRIORITY = 100;
@ -170,12 +173,12 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
await runner.load(loadSpriteAnimation);
loaded = true;
_distance = TextComponent("Distance: 0",
_distance = TextComponent("Time: 0",
position: Vector2(size.x - 100, 10), textRenderer: scoresPaint)
..anchor = Anchor.topRight;
_distance.changePriorityWithoutResorting(OVERLAY_PRIORITY);
_coins = TextComponent(": 0",
position: Vector2(size.x - 35, 10), textRenderer: scoresPaint)
position: Vector2(size.x - 20, 10), textRenderer: scoresPaint)
..anchor = Anchor.topRight;
_coins.changePriorityWithoutResorting(OVERLAY_PRIORITY);
overlays.add("gameOver");
@ -196,24 +199,31 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
if (shouldReset) {
return;
}
int dangerLevel = gameState.getDangerLevel();
platformHolder.generatePlatforms(this);
int wireChosenRegion = random.nextInt(9);
if (wireChosenRegion % 3 != 2 &&
wireChosenRegion != 6 &&
wireChosenRegion != 7) {
wireHolder.generateWire(this, wireChosenRegion);
if (dangerLevel > 2) {
int wireChosenRegion = random.nextInt(9);
if (wireChosenRegion % 3 != 2 &&
wireChosenRegion != 6 &&
wireChosenRegion != 7) {
wireHolder.generateWire(this, wireChosenRegion);
}
}
int bugChosenRegion = random.nextInt(9);
if (bugChosenRegion % 3 != 2 && bugChosenRegion % 3 != 0) {
bugHolder.generateBug(this, bugChosenRegion);
if (dangerLevel > 0) {
int bugChosenRegion = random.nextInt(9);
if (bugChosenRegion % 3 != 2 && bugChosenRegion % 3 != 0) {
bugHolder.generateBug(this, bugChosenRegion);
}
}
int debrisChosenRegion = random.nextInt(9);
if (debrisChosenRegion % 3 == 0 && debrisChosenRegion != 6) {
debrisHolder.generateDebris(this, debrisChosenRegion);
if (dangerLevel > 1) {
int debrisChosenRegion = random.nextInt(9);
if (debrisChosenRegion % 3 == 0 && debrisChosenRegion != 6) {
debrisHolder.generateDebris(this, debrisChosenRegion);
}
}
int choseCoinLevel = random.nextInt(9);
@ -221,9 +231,11 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
coinHolder.generateCoin(this, choseCoinLevel);
}
int wallChosenRegion = random.nextInt(9);
if (wallChosenRegion % 3 == 1 && wallChosenRegion != 7) {
wallHolder.generateWall(this, wallChosenRegion);
if (dangerLevel > 4) {
int wallChosenRegion = random.nextInt(9);
if (wallChosenRegion % 3 == 1 && wallChosenRegion != 7) {
wallHolder.generateWall(this, wallChosenRegion);
}
}
}
@ -389,12 +401,12 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
circuitBackground.render(canvas);
fireworks.renderText(canvas);
super.render(canvas);
final fpsCount = fps(10000);
fireworksPaint.render(
canvas,
fpsCount.toString(),
Vector2(0, 0),
);
// final fpsCount = fps(10000);
// fireworksPaint.render(
// canvas,
// fpsCount.toString(),
// Vector2(0, 0),
// );
coinHolder.renderCoinScore(canvas);
}
}
@ -426,7 +438,7 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
debrisHolder.update(dt);
wallHolder.update(dt);
_distance.text = "Distance: ${gameState.getPlayerDistance()}";
_distance.text = "Time: ${gameState.getPlayerDistance()}";
_coins.text = " ${gameState.numCoins}";
if (shouldReset &&
!overlays.isActive('gameOver') &&
@ -464,36 +476,46 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
yDeltas = List.empty(growable: true);
}
bool action = false;
@override
void onPanUpdate(DragUpdateInfo info) {
xDeltas.add(info.delta.game.x);
yDeltas.add(info.delta.game.y);
if (xDeltas.length > 2 && !action) {
action = true;
if (!playingMusic && kIsWeb) {
playMusic();
}
double xDelta = xDeltas.isEmpty
? 0
: xDeltas.reduce((value, element) => value + element);
double yDelta = yDeltas.isEmpty
? 0
: yDeltas.reduce((value, element) => value + element);
if (xDelta.abs() > yDelta.abs()) {
if (xDelta > 0) {
runner.control("right");
} else {
runner.control("left");
}
} else if (xDelta.abs() < yDelta.abs()) {
if (yDelta > 0) {
runner.control("down");
} else {
runner.control("up");
}
}
xDeltas = List.empty(growable: true);
yDeltas = List.empty(growable: true);
}
}
@override
void onPanEnd(DragEndInfo info) {
if (!playingMusic && kIsWeb) {
playMusic();
}
double xDelta = xDeltas.isEmpty
? 0
: xDeltas.reduce((value, element) => value + element);
double yDelta = yDeltas.isEmpty
? 0
: yDeltas.reduce((value, element) => value + element);
if (xDelta.abs() > yDelta.abs()) {
if (xDelta > 0) {
runner.control("right");
} else {
runner.control("left");
}
} else if (xDelta.abs() < yDelta.abs()) {
if (yDelta > 0) {
runner.control("down");
} else {
runner.control("up");
}
}
action = false;
xDeltas = List.empty(growable: true);
yDeltas = List.empty(growable: true);
}
@override

View File

@ -54,9 +54,9 @@ class MainMenuOverlay extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
" Start ",
" START ",
style: TextStyle(
color: Colors.white,
color: Colors.cyan,
fontSize: width * 0.03,
),
),
@ -81,9 +81,9 @@ class MainMenuOverlay extends StatelessWidget {
// child: Padding(
// padding: EdgeInsets.all(8.0),
// child: Text(
// " Deposit ",
// " DEPOSIT ",
// style: TextStyle(
// color: Colors.white,
// color: Colors.cyan,
// fontSize: width * 0.03,
// ),
// ),
@ -107,9 +107,9 @@ class MainMenuOverlay extends StatelessWidget {
// child: Padding(
// padding: EdgeInsets.all(8.0),
// child: Text(
// " Leader Boards ",
// " LEADER BOARD ",
// style: TextStyle(
// color: Colors.white,
// color: Colors.cyan,
// fontSize: width * 0.03,
// ),
// ),

View File

@ -14,8 +14,14 @@ enum RunnerState {
run,
jump,
duck,
duck2,
duck3,
kick,
kick2,
kick3,
float,
float2,
float3,
fall,
die,
electrocute,
@ -78,6 +84,7 @@ class Runner extends Component with HasGameRef<MyGame> {
if (gameRef.gameState.isPaused) {
return;
}
sprite.animation!.reset();
switch (event) {
case "jump":
previousState = runnerState;
@ -88,7 +95,7 @@ class Runner extends Component with HasGameRef<MyGame> {
// sprite.position,
Vector2(sprite.x, (level - 1) * gameRef.blockSize),
],
duration: 0.25,
duration: 0.15,
curve: Curves.bounceIn,
onComplete: () {
updateLevel();
@ -106,12 +113,22 @@ class Runner extends Component with HasGameRef<MyGame> {
break;
}
runnerState = event;
sprite.current = RunnerState.float;
switch (gameRef.gameState.getRobotLevel()) {
case 3:
sprite.current = RunnerState.float3;
break;
case 2:
sprite.current = RunnerState.float2;
break;
default:
sprite.current = RunnerState.float;
break;
}
sprite.addEffect(MoveEffect(
path: [
Vector2(sprite.x, (level - 2) * gameRef.blockSize),
],
duration: 0.5,
duration: 0.20,
curve: Curves.ease,
onComplete: () {
updateLevel();
@ -133,7 +150,17 @@ class Runner extends Component with HasGameRef<MyGame> {
case "kick":
previousState = runnerState;
runnerState = event;
sprite.current = RunnerState.kick;
switch (gameRef.gameState.getRobotLevel()) {
case 3:
sprite.current = RunnerState.kick3;
break;
case 2:
sprite.current = RunnerState.kick2;
break;
default:
sprite.current = RunnerState.kick;
break;
}
break;
case "run":
previousState = runnerState;
@ -143,7 +170,17 @@ class Runner extends Component with HasGameRef<MyGame> {
case "float":
previousState = runnerState;
runnerState = event;
sprite.current = RunnerState.float;
switch (gameRef.gameState.getRobotLevel()) {
case 3:
sprite.current = RunnerState.float3;
break;
case 2:
sprite.current = RunnerState.float2;
break;
default:
sprite.current = RunnerState.float;
break;
}
sprite.addEffect(MoveEffect(
path: [sprite.position],
duration: 1.5,
@ -161,7 +198,17 @@ class Runner extends Component with HasGameRef<MyGame> {
case "duck":
previousState = runnerState;
runnerState = event;
sprite.current = RunnerState.duck;
switch (gameRef.gameState.getRobotLevel()) {
case 3:
sprite.current = RunnerState.duck3;
break;
case 2:
sprite.current = RunnerState.duck2;
break;
default:
sprite.current = RunnerState.duck;
break;
}
sprite.addEffect(MoveEffect(
path: [sprite.position],
duration: 1.5,
@ -529,6 +576,36 @@ class Runner extends Component with HasGameRef<MyGame> {
SpriteAnimation ducking =
SpriteAnimation.spriteList(ducks, stepTime: 0.02, loop: true);
List<Sprite> ducks2 = [];
for (int i = 1; i <= 38; i++) {
final composition = ImageComposition()
..add(satellites.elementAt(i - 1), Vector2(0, 0))
..add(
await Flame.images.load(
'runner/duck2/duck200${i < 10 ? "0" + i.toString() : i.toString()}.png'),
Vector2(0, 0));
ducks2.add(Sprite(await composition.compose()));
}
SpriteAnimation ducking2 =
SpriteAnimation.spriteList(ducks2, stepTime: 0.02, loop: true);
List<Sprite> ducks3 = [];
for (int i = 1; i <= 38; i++) {
final composition = ImageComposition()
..add(satellites.elementAt(i - 1), Vector2(0, 0))
..add(
await Flame.images.load(
'runner/duck3/duck300${i < 10 ? "0" + i.toString() : i.toString()}.png'),
Vector2(0, 0));
ducks3.add(Sprite(await composition.compose()));
}
SpriteAnimation ducking3 =
SpriteAnimation.spriteList(ducks3, stepTime: 0.02, loop: true);
List<Sprite> kicks = [];
for (int i = 1; i <= 38; i++) {
final composition = ImageComposition()
@ -544,6 +621,36 @@ class Runner extends Component with HasGameRef<MyGame> {
SpriteAnimation kicking =
SpriteAnimation.spriteList(kicks, stepTime: 0.02, loop: false);
List<Sprite> kicks2 = [];
for (int i = 1; i <= 38; i++) {
final composition = ImageComposition()
..add(satellites.elementAt(i - 1), Vector2(0, 0))
..add(
await Flame.images.load(
'runner/attack2/attack200${i < 10 ? "0" + i.toString() : i.toString()}.png'),
Vector2(0, 0));
kicks2.add(Sprite(await composition.compose()));
}
SpriteAnimation kicking2 =
SpriteAnimation.spriteList(kicks2, stepTime: 0.02, loop: false);
List<Sprite> kicks3 = [];
for (int i = 1; i <= 38; i++) {
final composition = ImageComposition()
..add(satellites.elementAt(i - 1), Vector2(0, 0))
..add(
await Flame.images.load(
'runner/attack3/attack300${i < 10 ? "0" + i.toString() : i.toString()}.png'),
Vector2(0, 0));
kicks3.add(Sprite(await composition.compose()));
}
SpriteAnimation kicking3 =
SpriteAnimation.spriteList(kicks3, stepTime: 0.02, loop: false);
List<Sprite> floats = [];
for (int i = 1; i <= 44; i++) {
final composition = ImageComposition()
@ -559,6 +666,36 @@ class Runner extends Component with HasGameRef<MyGame> {
SpriteAnimation floating =
SpriteAnimation.spriteList(floats, stepTime: 0.02, loop: true);
List<Sprite> floats2 = [];
for (int i = 1; i <= 44; i++) {
final composition = ImageComposition()
..add(satellites.elementAt(((i - 1) % 38)), Vector2(0, 0))
..add(
await Flame.images.load(
'runner/hover2/hover200${i < 10 ? "0" + i.toString() : i.toString()}.png'),
Vector2(0, 0));
floats2.add(Sprite(await composition.compose()));
}
SpriteAnimation floating2 =
SpriteAnimation.spriteList(floats2, stepTime: 0.02, loop: true);
List<Sprite> floats3 = [];
for (int i = 1; i <= 44; i++) {
final composition = ImageComposition()
..add(satellites.elementAt(((i - 1) % 38)), Vector2(0, 0))
..add(
await Flame.images.load(
'runner/hover3/hover300${i < 10 ? "0" + i.toString() : i.toString()}.png'),
Vector2(0, 0));
floats3.add(Sprite(await composition.compose()));
}
SpriteAnimation floating3 =
SpriteAnimation.spriteList(floats3, stepTime: 0.02, loop: true);
List<Sprite> falls = [];
for (int i = 1; i <= 38; i++) {
final composition = ImageComposition()
@ -574,15 +711,6 @@ class Runner extends Component with HasGameRef<MyGame> {
SpriteAnimation falling =
SpriteAnimation.spriteList(falls, stepTime: 0.02, loop: false);
// SpriteAnimation falling = await loadSpriteAnimation(
// 'fall-frames.png',
// SpriteAnimationData.sequenced(
// amount: 7,
// stepTime: 0.1,
// textureSize: Vector2(512, 512),
// ),
// );
List<Sprite> dies = [];
for (int i = 1; i <= 57; i++) {
dies.add(Sprite(await Flame.images.load(
@ -606,8 +734,14 @@ class Runner extends Component with HasGameRef<MyGame> {
RunnerState.run: running,
RunnerState.jump: jumping,
RunnerState.duck: ducking,
RunnerState.duck2: ducking2,
RunnerState.duck3: ducking3,
RunnerState.kick: kicking,
RunnerState.kick2: kicking2,
RunnerState.kick3: kicking3,
RunnerState.float: floating,
RunnerState.float2: floating2,
RunnerState.float3: floating3,
RunnerState.fall: falling,
RunnerState.die: dying,
RunnerState.electrocute: dying,