2021-10-05 23:22:01 +00:00
|
|
|
import 'package:flame/extensions.dart';
|
2021-10-09 03:59:38 +00:00
|
|
|
import 'package:firo_runner/moving_objects/bug.dart';
|
|
|
|
import 'package:firo_runner/moving_objects/moving_object.dart';
|
2021-10-05 23:22:01 +00:00
|
|
|
import 'package:firo_runner/main.dart';
|
|
|
|
import 'package:flame/effects.dart';
|
|
|
|
import 'package:flame/flame.dart';
|
|
|
|
import 'dart:math';
|
|
|
|
|
|
|
|
import 'package:flame/components.dart';
|
|
|
|
import 'package:flame/image_composition.dart';
|
|
|
|
import 'package:flame_audio/flame_audio.dart';
|
|
|
|
import 'package:flutter/animation.dart';
|
2021-10-06 18:22:57 +00:00
|
|
|
import 'package:audioplayers/src/api/player_mode.dart';
|
2021-10-05 23:22:01 +00:00
|
|
|
|
|
|
|
enum RunnerState {
|
|
|
|
run,
|
|
|
|
jump,
|
|
|
|
duck,
|
|
|
|
duck2,
|
|
|
|
duck3,
|
|
|
|
kick,
|
|
|
|
kick2,
|
|
|
|
kick3,
|
|
|
|
float,
|
|
|
|
float2,
|
|
|
|
float3,
|
|
|
|
fall,
|
|
|
|
die,
|
|
|
|
electrocute,
|
|
|
|
glitch,
|
|
|
|
}
|
|
|
|
|
|
|
|
class Runner extends Component with HasGameRef<MyGame> {
|
|
|
|
late SpriteAnimationGroupComponent sprite;
|
|
|
|
String runnerState = "run";
|
|
|
|
int level = 4;
|
|
|
|
String previousState = "run";
|
|
|
|
var runnerPosition = Vector2(0, 0);
|
|
|
|
late Vector2 runnerSize;
|
|
|
|
bool dead = false;
|
2021-10-06 18:22:57 +00:00
|
|
|
late Future boost;
|
2021-10-05 23:22:01 +00:00
|
|
|
late var friend = null;
|
|
|
|
|
|
|
|
void setUp() {
|
|
|
|
dead = false;
|
|
|
|
runnerState = "run";
|
|
|
|
previousState = "run";
|
|
|
|
level = 4;
|
|
|
|
|
|
|
|
runnerSize = Vector2(
|
|
|
|
gameRef.size.y / 9,
|
|
|
|
gameRef.size.y / 9,
|
|
|
|
);
|
|
|
|
|
|
|
|
setSize(runnerSize, gameRef.blockSize);
|
|
|
|
runnerPosition = Vector2(gameRef.blockSize * 2, gameRef.blockSize * 4);
|
|
|
|
setPosition(runnerPosition);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setPosition(Vector2 position) {
|
|
|
|
sprite.position = position;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setSize(Vector2 size, double ySize) {
|
|
|
|
sprite.size = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite getSprite() {
|
|
|
|
return sprite.animation!.getSprite();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void render(Canvas c) {
|
|
|
|
super.render(c);
|
|
|
|
getSprite().render(c,
|
|
|
|
position: Vector2(sprite.position.x - sprite.size.x / 3,
|
|
|
|
sprite.position.y - sprite.size.y / 3),
|
|
|
|
size: sprite.size * 1.6);
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// update which level the runner should be at.
|
2021-10-05 23:22:01 +00:00
|
|
|
void updateLevel() {
|
|
|
|
level = (sprite.position.y / gameRef.blockSize).round();
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// process the event that the runner is in.
|
2021-10-06 18:22:57 +00:00
|
|
|
void event(String event) {
|
2021-10-05 23:22:01 +00:00
|
|
|
if (gameRef.gameState.isPaused) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sprite.animation!.reset();
|
|
|
|
switch (event) {
|
|
|
|
case "jump":
|
|
|
|
previousState = runnerState;
|
|
|
|
runnerState = event;
|
|
|
|
sprite.current = RunnerState.jump;
|
|
|
|
sprite.addEffect(MoveEffect(
|
|
|
|
path: [
|
|
|
|
// sprite.position,
|
|
|
|
Vector2(sprite.x, (level - 1) * gameRef.blockSize),
|
|
|
|
],
|
|
|
|
duration: 0.15,
|
|
|
|
curve: Curves.bounceIn,
|
|
|
|
onComplete: () {
|
|
|
|
updateLevel();
|
|
|
|
this.event("float");
|
|
|
|
},
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
case "double_jump":
|
|
|
|
if (belowPlatform()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
previousState = runnerState;
|
2021-10-06 18:22:57 +00:00
|
|
|
clearEffects(keepSounds: true);
|
2021-10-05 23:22:01 +00:00
|
|
|
if (level - 1 < 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
runnerState = event;
|
|
|
|
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.20,
|
|
|
|
curve: Curves.ease,
|
|
|
|
onComplete: () {
|
|
|
|
updateLevel();
|
|
|
|
clearEffects();
|
|
|
|
if (onTopOfPlatform()) {
|
|
|
|
this.event("run");
|
|
|
|
} else {
|
|
|
|
this.event("float");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
case "fall":
|
|
|
|
previousState = runnerState;
|
|
|
|
clearEffects();
|
|
|
|
runnerState = event;
|
|
|
|
sprite.current = RunnerState.fall;
|
|
|
|
sprite.addEffect(getFallingEffect());
|
|
|
|
break;
|
|
|
|
case "kick":
|
|
|
|
previousState = runnerState;
|
|
|
|
runnerState = event;
|
2021-10-06 18:22:57 +00:00
|
|
|
boost = FlameAudio.audioCache
|
|
|
|
.play('sfx/laser.mp3', volume: 1.0, mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
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;
|
|
|
|
runnerState = event;
|
|
|
|
sprite.current = RunnerState.run;
|
|
|
|
break;
|
|
|
|
case "float":
|
|
|
|
previousState = runnerState;
|
|
|
|
runnerState = event;
|
2021-10-06 18:22:57 +00:00
|
|
|
boost = FlameAudio.audioCache.play('sfx/jet_boost.mp3',
|
|
|
|
volume: 0.25, mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
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,
|
|
|
|
curve: Curves.ease,
|
|
|
|
onComplete: () {
|
|
|
|
updateLevel();
|
|
|
|
if (onTopOfPlatform()) {
|
|
|
|
this.event("run");
|
|
|
|
} else {
|
|
|
|
this.event("fall");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
case "duck":
|
|
|
|
previousState = runnerState;
|
|
|
|
runnerState = event;
|
2021-10-06 18:22:57 +00:00
|
|
|
boost = FlameAudio.audioCache
|
|
|
|
.play('sfx/shield.mp3', volume: 0.25, mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
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,
|
|
|
|
curve: Curves.linear,
|
|
|
|
onComplete: () {
|
2021-10-06 18:22:57 +00:00
|
|
|
if (boost != null) {
|
|
|
|
boost.then((value) => value.stop());
|
|
|
|
}
|
2021-10-05 23:22:01 +00:00
|
|
|
this.event("run");
|
|
|
|
},
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
case "die":
|
|
|
|
if (dead) {
|
|
|
|
return;
|
|
|
|
}
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache.play('sfx/fall_death_speed.mp3',
|
|
|
|
volume: 0.5, mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
previousState = runnerState;
|
|
|
|
clearEffects();
|
|
|
|
runnerState = event;
|
|
|
|
sprite.current = RunnerState.die;
|
|
|
|
dead = true;
|
|
|
|
friend.stop();
|
|
|
|
gameRef.die();
|
|
|
|
sprite.addEffect(getFallingEffect());
|
|
|
|
break;
|
|
|
|
case "electrocute":
|
|
|
|
if (dead) {
|
|
|
|
return;
|
|
|
|
}
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache.play('sfx/fall_death_speed.mp3',
|
|
|
|
volume: 0.5, mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
previousState = runnerState;
|
|
|
|
clearEffects();
|
|
|
|
runnerState = event;
|
|
|
|
sprite.current = RunnerState.electrocute;
|
|
|
|
dead = true;
|
|
|
|
friend.stop();
|
|
|
|
gameRef.die();
|
|
|
|
sprite.addEffect(getFallingEffect());
|
|
|
|
break;
|
|
|
|
case "glitch":
|
|
|
|
if (dead) {
|
|
|
|
return;
|
|
|
|
}
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache.play('sfx/glitch_death.mp3',
|
|
|
|
volume: 0.5, mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
previousState = runnerState;
|
|
|
|
clearEffects();
|
|
|
|
runnerState = event;
|
|
|
|
sprite.current = RunnerState.glitch;
|
|
|
|
dead = true;
|
|
|
|
friend.stop();
|
|
|
|
gameRef.die();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Get the falling effect for falling and deaths.
|
2021-10-05 23:22:01 +00:00
|
|
|
MoveEffect getFallingEffect() {
|
|
|
|
for (int i = level; i < 9; i++) {
|
|
|
|
if (i % 3 != 2) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
int distance = (i - 1 - level);
|
|
|
|
double time = 0.2;
|
|
|
|
for (int x = 2; x < distance; x++) {
|
|
|
|
time += time * pow(0.5, x - 1);
|
|
|
|
}
|
|
|
|
double estimatedXCoordinate =
|
|
|
|
time * gameRef.gameState.getVelocity() + sprite.x;
|
|
|
|
for (MovingObject p in gameRef.platformHolder.objects[i]) {
|
|
|
|
if (estimatedXCoordinate >= p.sprite.x - p.sprite.width / 2 &&
|
|
|
|
estimatedXCoordinate <= p.sprite.x + p.sprite.width) {
|
|
|
|
return MoveEffect(
|
|
|
|
path: [
|
|
|
|
Vector2(sprite.x, (i - 1) * gameRef.blockSize),
|
|
|
|
],
|
|
|
|
duration: time,
|
|
|
|
curve: Curves.ease,
|
|
|
|
onComplete: () {
|
|
|
|
updateLevel();
|
|
|
|
if (onTopOfPlatform()) {
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache
|
|
|
|
.play('sfx/land.mp3', mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
event("run");
|
|
|
|
} else {
|
|
|
|
event("fall");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return MoveEffect(
|
|
|
|
path: [
|
|
|
|
Vector2(sprite.x, 8 * gameRef.blockSize),
|
|
|
|
],
|
|
|
|
duration: 0.2 * (8 - level),
|
|
|
|
curve: Curves.ease,
|
|
|
|
onComplete: () {
|
|
|
|
updateLevel();
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache
|
|
|
|
.play('sfx/land.mp3', mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
if (onTopOfPlatform()) {
|
|
|
|
event("run");
|
|
|
|
} else {
|
|
|
|
event("fall");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Platform agnostic control input to determine the runners actions.
|
2021-10-05 23:22:01 +00:00
|
|
|
void control(String input) {
|
|
|
|
if (gameRef.gameState.isPaused) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (input) {
|
|
|
|
case "up":
|
|
|
|
if (runnerState == "run" || runnerState == "kick") {
|
|
|
|
event("jump");
|
|
|
|
} else if (runnerState == "float" && previousState == "jump") {
|
|
|
|
event("double_jump");
|
|
|
|
} else if (runnerState == "duck") {
|
|
|
|
clearEffects();
|
|
|
|
event("run");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "down":
|
|
|
|
if (runnerState == "run" || runnerState == "kick") {
|
|
|
|
event("duck");
|
|
|
|
} else if (runnerState == "float" && onTopOfPlatform()) {
|
|
|
|
clearEffects();
|
|
|
|
event("run");
|
|
|
|
} else if (runnerState == "float") {
|
|
|
|
clearEffects();
|
|
|
|
event("fall");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "right":
|
|
|
|
if (runnerState == "run" || runnerState == "kick") {
|
|
|
|
event("kick");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "left":
|
|
|
|
if (runnerState == "kick") {
|
|
|
|
sprite.animation!.reset();
|
|
|
|
clearEffects();
|
|
|
|
event("run");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void update(double dt) {
|
|
|
|
super.update(dt);
|
|
|
|
if (sprite.position.y + sprite.size.y >= gameRef.size.y) {
|
|
|
|
event("die");
|
|
|
|
}
|
|
|
|
// If the animation is finished
|
|
|
|
if (sprite.animation?.done() ?? false) {
|
|
|
|
if (!dead) {
|
|
|
|
sprite.animation!.reset();
|
|
|
|
if (runnerState == "kick") {
|
|
|
|
event("run");
|
|
|
|
}
|
|
|
|
sprite.current = RunnerState.run;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (runnerState == "float" || runnerState == "double_jump") {
|
|
|
|
if (onTopOfPlatform()) {
|
|
|
|
updateLevel();
|
|
|
|
clearEffects();
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache
|
|
|
|
.play('sfx/land.mp3', mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
event("run");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
intersecting();
|
|
|
|
sprite.update(dt);
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Check whether or not the runner is on top of a platform.
|
2021-10-05 23:22:01 +00:00
|
|
|
bool onTopOfPlatform() {
|
|
|
|
Rect runnerRect = sprite.toRect();
|
|
|
|
bool onTopOfPlatform = false;
|
|
|
|
for (List<MovingObject> platformLevel in gameRef.platformHolder.objects) {
|
|
|
|
for (MovingObject p in platformLevel) {
|
|
|
|
String side = p.intersect(runnerRect);
|
|
|
|
if (side == "none") {
|
|
|
|
Rect belowRunner = Rect.fromLTRB(runnerRect.left, runnerRect.top,
|
|
|
|
runnerRect.right, runnerRect.bottom + 1);
|
|
|
|
if (p.intersect(belowRunner) != "none") {
|
|
|
|
onTopOfPlatform = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return onTopOfPlatform;
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Check if the runner is directly below a platform.
|
2021-10-05 23:22:01 +00:00
|
|
|
bool belowPlatform() {
|
|
|
|
Rect runnerRect = Rect.fromLTRB(
|
|
|
|
sprite.toRect().left,
|
|
|
|
sprite.toRect().top,
|
|
|
|
sprite.toRect().right - sprite.toRect().width / 2,
|
|
|
|
sprite.toRect().bottom);
|
|
|
|
bool belowPlatform = false;
|
|
|
|
for (List<MovingObject> platformLevel in gameRef.platformHolder.objects) {
|
|
|
|
for (MovingObject p in platformLevel) {
|
|
|
|
String side = p.intersect(runnerRect);
|
|
|
|
if (side == "none") {
|
|
|
|
Rect belowRunner = Rect.fromLTRB(runnerRect.left, runnerRect.top - 1,
|
|
|
|
runnerRect.right, runnerRect.bottom);
|
|
|
|
if (p.intersect(belowRunner) == "bottom") {
|
|
|
|
belowPlatform = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return belowPlatform;
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Check to see if the runner is intersecting any of the game objects, and
|
|
|
|
// trigger the appropriate events.
|
2021-10-06 18:22:57 +00:00
|
|
|
void intersecting() {
|
2021-10-05 23:22:01 +00:00
|
|
|
if (gameRef.gameState.isPaused) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Rect runnerRect = sprite.toRect();
|
|
|
|
bool onTopOfPlatform = this.onTopOfPlatform();
|
|
|
|
|
|
|
|
for (List<MovingObject> coinLevel in gameRef.coinHolder.objects) {
|
|
|
|
for (int i = 0; i < coinLevel.length;) {
|
|
|
|
if (coinLevel[i].intersect(runnerRect) != "none") {
|
|
|
|
gameRef.gameState.numCoins++;
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache.play('sfx/coin_catch.mp3',
|
|
|
|
volume: 0.25, mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
gameRef.coinHolder.remove(coinLevel, i);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (List<MovingObject> wireLevel in gameRef.wireHolder.objects) {
|
|
|
|
for (int i = 0; i < wireLevel.length; i++) {
|
|
|
|
if (wireLevel[i].intersect(runnerRect) != "none") {
|
|
|
|
event("electrocute");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (List<MovingObject> bugLevel in gameRef.bugHolder.objects) {
|
|
|
|
for (int i = 0; i < bugLevel.length; i++) {
|
|
|
|
String intersectState = bugLevel[i].intersect(runnerRect);
|
|
|
|
if (bugLevel[i].sprite.current == BugState.breaking) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (intersectState == "none") {
|
|
|
|
Rect above = Rect.fromLTRB(
|
|
|
|
runnerRect.left + sprite.width / 3,
|
|
|
|
runnerRect.top - 1,
|
|
|
|
runnerRect.right - sprite.width / 3,
|
|
|
|
runnerRect.bottom);
|
|
|
|
String aboveIntersect = bugLevel[i].intersect(above);
|
|
|
|
if (aboveIntersect != "none" &&
|
|
|
|
(runnerState == "duck" || runnerState == "float")) {
|
|
|
|
continue;
|
|
|
|
} else if (aboveIntersect != "none") {
|
|
|
|
event("glitch");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (intersectState == "left" && runnerState == "kick") {
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache
|
|
|
|
.play('sfx/bug_death1.mp3', mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
bugLevel[i].sprite.current = BugState.breaking;
|
|
|
|
gameRef.coinHolder.generateCoin(gameRef, level,
|
|
|
|
force: true, xPosition: bugLevel[i].sprite.x + gameRef.blockSize);
|
|
|
|
} else {
|
|
|
|
event("glitch");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (List<MovingObject> debrisLevel in gameRef.debrisHolder.objects) {
|
|
|
|
for (int i = 0; i < debrisLevel.length; i++) {
|
|
|
|
Rect slim = Rect.fromLTRB(
|
|
|
|
runnerRect.left + sprite.width / 3,
|
|
|
|
runnerRect.top,
|
|
|
|
runnerRect.right - sprite.width / 3,
|
|
|
|
runnerRect.bottom);
|
|
|
|
String intersectState = debrisLevel[i].intersect(slim);
|
|
|
|
if (intersectState == "none") {
|
|
|
|
continue;
|
|
|
|
} else if (runnerState == "duck" && intersectState != "above") {
|
|
|
|
continue;
|
|
|
|
} else {
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache
|
|
|
|
.play('sfx/obstacle_death.mp3', mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
event("die");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (List<MovingObject> wallLevel in gameRef.wallHolder.objects) {
|
|
|
|
for (int i = 0; i < wallLevel.length; i++) {
|
|
|
|
Rect slim = Rect.fromLTRB(
|
|
|
|
runnerRect.left + sprite.width / 3,
|
|
|
|
runnerRect.top + sprite.height / (runnerState == "duck" ? 3 : 6),
|
|
|
|
runnerRect.right - sprite.width / 3,
|
|
|
|
runnerRect.bottom - sprite.height / 3);
|
|
|
|
String intersectState = wallLevel[i].intersect(slim);
|
|
|
|
if (intersectState == "none") {
|
|
|
|
continue;
|
|
|
|
} else {
|
2021-10-06 18:22:57 +00:00
|
|
|
FlameAudio.audioCache
|
|
|
|
.play('sfx/obstacle_death.mp3', mode: PlayerMode.LOW_LATENCY);
|
2021-10-05 23:22:01 +00:00
|
|
|
event("die");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!onTopOfPlatform &&
|
|
|
|
(runnerState == "run" ||
|
|
|
|
runnerState == "kick" ||
|
|
|
|
runnerState == "duck")) {
|
|
|
|
clearEffects();
|
|
|
|
event("fall");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Load all of the runners animations.
|
2021-10-05 23:22:01 +00:00
|
|
|
Future load() async {
|
|
|
|
List<Image> satellites = [];
|
|
|
|
for (int i = 1; i <= 38; i++) {
|
|
|
|
satellites.add(await Flame.images.load(
|
|
|
|
'runner/satellite/satellite00${i < 10 ? "0" + i.toString() : i.toString()}.png'));
|
|
|
|
}
|
|
|
|
|
|
|
|
SpriteAnimation running =
|
|
|
|
await loadSpriteAnimation("run", 38, satellites: satellites);
|
|
|
|
|
|
|
|
SpriteAnimation jumping = await loadSpriteAnimation("jump", 6,
|
|
|
|
satellites: satellites, loop: false);
|
|
|
|
|
|
|
|
SpriteAnimation ducking =
|
|
|
|
await loadSpriteAnimation("duck1", 38, satellites: satellites);
|
|
|
|
|
|
|
|
SpriteAnimation ducking2 =
|
|
|
|
await loadSpriteAnimation("duck2", 38, satellites: satellites);
|
|
|
|
|
|
|
|
SpriteAnimation ducking3 =
|
|
|
|
await loadSpriteAnimation("duck3", 38, satellites: satellites);
|
|
|
|
|
|
|
|
SpriteAnimation kicking = await loadSpriteAnimation("attack1", 38,
|
|
|
|
satellites: satellites, loop: false);
|
|
|
|
|
|
|
|
SpriteAnimation kicking2 = await loadSpriteAnimation("attack2", 38,
|
|
|
|
satellites: satellites, loop: false);
|
|
|
|
|
|
|
|
SpriteAnimation kicking3 = await loadSpriteAnimation("attack3", 38,
|
|
|
|
satellites: satellites, loop: false);
|
|
|
|
|
|
|
|
SpriteAnimation floating =
|
|
|
|
await loadSpriteAnimation("hover1", 44, satellites: satellites);
|
|
|
|
|
|
|
|
SpriteAnimation floating2 =
|
|
|
|
await loadSpriteAnimation("hover2", 44, satellites: satellites);
|
|
|
|
|
|
|
|
SpriteAnimation floating3 =
|
|
|
|
await loadSpriteAnimation("hover3", 44, satellites: satellites);
|
|
|
|
|
|
|
|
SpriteAnimation falling = await loadSpriteAnimation("fall", 20,
|
|
|
|
satellites: satellites, loop: false);
|
|
|
|
|
|
|
|
SpriteAnimation dying =
|
|
|
|
await loadSpriteAnimation("death2", 57, loop: false);
|
|
|
|
|
|
|
|
SpriteAnimation dyingGlitch =
|
2021-10-06 18:22:57 +00:00
|
|
|
await loadSpriteAnimation("death1", 82, loop: false);
|
2021-10-05 23:22:01 +00:00
|
|
|
|
|
|
|
sprite = SpriteAnimationGroupComponent(
|
|
|
|
animations: {
|
|
|
|
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,
|
|
|
|
RunnerState.glitch: dyingGlitch,
|
|
|
|
},
|
|
|
|
current: RunnerState.run,
|
|
|
|
);
|
|
|
|
|
|
|
|
changePriorityWithoutResorting(RUNNER_PRIORITY);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<SpriteAnimation> loadSpriteAnimation(String name, int howManyFrames,
|
|
|
|
{List<Image>? satellites, bool loop = true}) async {
|
|
|
|
List<Sprite> sprites = [];
|
|
|
|
for (int i = 1; i <= howManyFrames; i++) {
|
|
|
|
final composition = ImageComposition();
|
|
|
|
if (satellites != null) {
|
|
|
|
composition.add(
|
|
|
|
satellites.elementAt(((i - 1) % satellites.length)), Vector2(0, 0));
|
|
|
|
}
|
|
|
|
composition.add(
|
|
|
|
await Flame.images.load(
|
|
|
|
'runner/$name/${name}00${i < 10 ? "0" + i.toString() : i.toString()}.png'),
|
|
|
|
Vector2(0, 0));
|
|
|
|
|
|
|
|
sprites.add(Sprite(await composition.compose()));
|
|
|
|
}
|
|
|
|
|
|
|
|
return SpriteAnimation.spriteList(sprites, stepTime: 0.02, loop: loop);
|
|
|
|
}
|
|
|
|
|
|
|
|
void resize(Vector2 newSize, double xRatio, double yRatio) {
|
|
|
|
sprite.x = gameRef.blockSize * 2;
|
|
|
|
sprite.y = gameRef.blockSize * level;
|
|
|
|
sprite.size.x = gameRef.blockSize;
|
|
|
|
sprite.size.y = gameRef.blockSize;
|
|
|
|
if (sprite.effects.isNotEmpty) {
|
|
|
|
sprite.effects.first.onComplete!();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void clearEffects({bool keepSounds = false}) {
|
|
|
|
sprite.clearEffects();
|
2021-10-06 18:22:57 +00:00
|
|
|
if (!keepSounds && boost != null) {
|
|
|
|
boost.then((value) => value.stop());
|
2021-10-05 23:22:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|