Added wires, and fixed rendering so that flips of images will be registered.

This commit is contained in:
Marco Salazar 2021-09-04 16:56:08 -06:00
parent f5be43202d
commit 09db52bcc9
17 changed files with 254 additions and 114 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

View File

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

View File

@ -1,9 +1,6 @@
import 'dart:math';
import 'package:firo_runner/MovingObject.dart';
import 'package:firo_runner/main.dart';
import 'package:flame/components.dart';
import 'package:flutter/material.dart';
enum CoinState { normal }
@ -26,6 +23,8 @@ class Coin extends MovingObject {
current: CoinState.normal,
);
sprite.changePriorityWithoutResorting(COIN_PRIORITY);
var platform = gameRef.platformHolder.getPlatform(0);
setSize(
@ -38,8 +37,7 @@ class Coin extends MovingObject {
return sprite.position.x + sprite.width;
}
@override
void render(Canvas c) {
getSprite().render(c, position: sprite.position, size: sprite.size);
void remove() {
sprite.remove();
}
}

View File

@ -1,12 +1,11 @@
import 'dart:math';
import 'package:flame/flame.dart';
import 'package:flutter/material.dart';
import 'Coin.dart';
import 'main.dart';
class Coinholder {
class CoinHolder {
var coin;
Random random = Random();
@ -28,19 +27,17 @@ class Coinholder {
return false;
}
double xCordinate = gameRef.platformHolder.getFlushX();
// if (coins[level].isNotEmpty) {
// xCordinate = coins[level].last.getRightEnd();
// }
xCordinate = xCordinate +
gameRef.blockSize * random.nextInt(5) +
gameRef.blockSize * 20;
if (xCordinate < gameRef.size.x && random.nextInt(1000000) > 99999) {
if (xCordinate < gameRef.size.x || random.nextInt(100) > 10) {
return true;
} else {
Coin coin = Coin(gameRef);
coin.setPosition(xCordinate, gameRef.blockSize * level);
coins[level].add(coin);
gameRef.add(coin.sprite);
return false;
}
}
@ -53,14 +50,6 @@ class Coinholder {
return total;
}
void render(Canvas canvas) {
for (List<Coin> coinLevel in coins) {
for (Coin p in coinLevel) {
p.render(canvas);
}
}
}
void update(double dt) {
for (List<Coin> coinLevel in coins) {
for (Coin p in coinLevel) {
@ -73,6 +62,7 @@ class Coinholder {
for (List<Coin> coinLevel in coins) {
for (int i = 0; i < coinLevel.length;) {
if (coinLevel[i].sprite.x + coinLevel[i].sprite.width < 0) {
coinLevel[i].sprite.remove();
coinLevel.removeAt(i);
continue;
}

View File

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:firo_runner/main.dart';
import 'package:flame/components.dart';
class MovingObject extends Component {
class MovingObject {
late SpriteAnimationGroupComponent sprite;
MyGame gameRef;
@ -21,15 +21,7 @@ class MovingObject extends Component {
return sprite.animation!.getSprite();
}
@override
void render(Canvas c) {
super.render(c);
}
@override
void update(double dt) {
super.update(dt);
sprite.update(dt);
double velocity = gameRef.gameState.getVelocity();
sprite.position = sprite.position - Vector2(velocity * dt, 0);
}
@ -37,17 +29,16 @@ class MovingObject extends Component {
String intersect(Rect other) {
final collision = sprite.toRect().intersect(other);
if (!collision.isEmpty) {
// print(collision);
double ydistance = other.top - sprite.toRect().top;
double xdistance = other.left - sprite.toRect().left;
if (ydistance.abs() > xdistance.abs()) {
if (ydistance > 0) {
double yDistance = other.top - sprite.toRect().top;
double xDistance = other.left - sprite.toRect().left;
if (yDistance.abs() > xDistance.abs()) {
if (yDistance > 0) {
return "bottom";
} else {
return "top";
}
} else {
if (xdistance > 0) {
if (xDistance > 0) {
return "right";
} else {
return "left";

View File

@ -3,11 +3,12 @@ import 'dart:math';
import 'package:firo_runner/MovingObject.dart';
import 'package:firo_runner/main.dart';
import 'package:flame/components.dart';
import 'package:flutter/material.dart';
enum PlatformState { normal }
class Platform extends MovingObject {
var removeChildren = null;
Platform(MyGame gameRef) : super(gameRef) {
var random = Random();
int version = random.nextInt(3) + 1;
@ -28,6 +29,8 @@ class Platform extends MovingObject {
current: PlatformState.normal,
);
sprite.changePriorityWithoutResorting(PLATFORM_PRIORITY);
setSize(
gameRef.blockSize * (platform!.width / platform!.height / 7),
gameRef.blockSize,
@ -38,8 +41,9 @@ class Platform extends MovingObject {
return sprite.position.x + sprite.width;
}
@override
void render(Canvas c) {
getSprite().render(c, position: sprite.position, size: sprite.size);
void remove() {
if (removeChildren != null) {
removeChildren();
}
}
}

View File

@ -2,7 +2,6 @@ import 'dart:math';
import 'package:firo_runner/main.dart';
import 'package:flame/flame.dart';
import 'package:flutter/material.dart';
import 'Platform.dart';
class PlatformHolder {
@ -33,29 +32,22 @@ class PlatformHolder {
}
bool generatePlatform(MyGame gameRef, int level, bool force) {
double xCordinate = 0;
double xCoordinate = 0;
if (platforms[level].isNotEmpty) {
xCordinate = platforms[level].last.getRightEnd();
xCoordinate = platforms[level].last.getRightEnd();
}
if (xCordinate > gameRef.size.x + 1000) {
if (xCoordinate > gameRef.size.x + 1000) {
return true;
} else {
Platform platform = Platform(gameRef);
platform.setPosition(xCordinate, gameRef.blockSize * level);
platform.setPosition(xCoordinate, gameRef.blockSize * level);
gameRef.add(platform.sprite);
platforms[level].add(platform);
return false;
}
}
void render(Canvas canvas) {
for (List<Platform> platformLevel in platforms) {
for (Platform p in platformLevel) {
p.render(canvas);
}
}
}
void update(double dt) {
for (List<Platform> platformLevel in platforms) {
for (Platform p in platformLevel) {
@ -70,6 +62,7 @@ class PlatformHolder {
while (platformLevel.isNotEmpty &&
platformLevel[0].sprite.position.x + platformLevel[0].sprite.width <
0) {
platformLevel[0].sprite.remove();
platformLevel.removeAt(0);
removed++;
}
@ -81,7 +74,12 @@ class PlatformHolder {
double secondToLastPosition =
platformLevel.elementAt(secondToLast).sprite.x;
if (secondToLastPosition > gameRef.size.x) {
platformLevel[secondToLast].remove();
platformLevel[secondToLast].sprite.remove();
platformLevel.removeAt(secondToLast);
platformLevel[secondToLast + 1].remove();
platformLevel[secondToLast + 1].sprite.remove();
platformLevel.removeAt(secondToLast + 1);
}
}
@ -98,4 +96,15 @@ class PlatformHolder {
});
return platform.sprite.x;
}
Platform? getPlatformOffScreen(int level) {
for (int i = 0; i < platforms[level].length; i++) {
Platform p = platforms[level][i];
if (p.sprite.x > p.gameRef.size.x) {
int chosenIndex = random.nextInt(platforms[level].length - i) + i;
return platforms[level][chosenIndex];
}
}
return null;
}
}

View File

@ -1,4 +1,5 @@
import 'package:firo_runner/Coin.dart';
import 'package:firo_runner/Wire.dart';
import 'package:firo_runner/main.dart';
import 'package:flame/effects.dart';
import 'package:flutter/material.dart';
@ -72,17 +73,16 @@ class Runner extends Component with HasGameRef<MyGame> {
break;
}
runnerState = event;
sprite.current = RunnerState.jump;
sprite.current = RunnerState.float;
sprite.addEffect(MoveEffect(
path: [
sprite.position,
Vector2(sprite.x, (level - 2) * gameRef.blockSize),
],
speed: 50,
speed: 100,
curve: Curves.ease,
onComplete: () {
updateLevel();
runnerState = "run";
this.event("float");
},
));
break;
@ -96,13 +96,8 @@ class Runner extends Component with HasGameRef<MyGame> {
speed: 100,
curve: Curves.ease,
onComplete: () {
if (runnerState == "fall") {
updateLevel();
sprite.position = Vector2(sprite.x, level * gameRef.blockSize);
this.event("run");
} else {
this.event("float");
}
},
));
break;
@ -119,7 +114,7 @@ class Runner extends Component with HasGameRef<MyGame> {
sprite.current = RunnerState.float;
sprite.addEffect(MoveEffect(
path: [sprite.position],
speed: 50,
speed: 500,
curve: Curves.ease,
onComplete: () {
updateLevel();
@ -227,8 +222,8 @@ class Runner extends Component with HasGameRef<MyGame> {
onTopOfPlatform = true;
}
} else if (side == "bottom") {
// The runner has hit his head on the ceiling and should die.
event("die");
return;
}
}
}
@ -237,6 +232,7 @@ class Runner extends Component with HasGameRef<MyGame> {
for (int i = 0; i < coinLevel.length;) {
if (coinLevel[i].intersect(runnerRect) != "none") {
gameRef.gameState.numCoins++;
coinLevel[i].remove();
coinLevel.removeAt(i);
print(gameRef.gameState.numCoins);
continue;
@ -245,6 +241,14 @@ class Runner extends Component with HasGameRef<MyGame> {
}
}
for (List<Wire> wireLevel in gameRef.wireHolder.wires) {
for (int i = 0; i < wireLevel.length; i++) {
if (wireLevel[i].intersect(runnerRect) != "none") {
event("electro");
}
}
}
if (!onTopOfPlatform &&
(runnerState == "run" ||
runnerState == "kick" ||
@ -293,24 +297,24 @@ class Runner extends Component with HasGameRef<MyGame> {
);
SpriteAnimation floating = await loadSpriteAnimation(
'run-frames.png',
'hover-frames.png',
SpriteAnimationData.sequenced(
amount: 1,
amount: 3,
stepTime: 0.1,
textureSize: Vector2(512, 512),
),
);
SpriteAnimation falling = await loadSpriteAnimation(
'run-frames.png',
'hover-frames.png',
SpriteAnimationData.sequenced(
amount: 1,
amount: 3,
stepTime: 0.1,
textureSize: Vector2(512, 512),
),
);
SpriteAnimation dieing = await loadSpriteAnimation(
SpriteAnimation dying = await loadSpriteAnimation(
'death-normal-frames.png',
SpriteAnimationData.sequenced(
amount: 20,
@ -320,8 +324,8 @@ class Runner extends Component with HasGameRef<MyGame> {
),
);
SpriteAnimation dieingElectorcuted = await loadSpriteAnimation(
'electrecuted-frames.png',
SpriteAnimation dyingElectrocuted = await loadSpriteAnimation(
'electrocuted-frames.png',
SpriteAnimationData.sequenced(
amount: 2,
stepTime: 0.1,
@ -337,10 +341,12 @@ class Runner extends Component with HasGameRef<MyGame> {
RunnerState.kick: kicking,
RunnerState.float: floating,
RunnerState.fall: falling,
RunnerState.die: dieing,
RunnerState.electro: dieingElectorcuted,
RunnerState.die: dying,
RunnerState.electro: dyingElectrocuted,
},
current: RunnerState.run,
);
changePriorityWithoutResorting(RUNNER_PRIORITY);
}
}

41
lib/Wire.dart Normal file
View File

@ -0,0 +1,41 @@
import 'package:firo_runner/MovingObject.dart';
import 'package:firo_runner/main.dart';
import 'package:flame/components.dart';
enum WireState { normal }
class Wire extends MovingObject {
Wire(MyGame gameRef) : super(gameRef) {
var wire = gameRef.wireHolder.getWire();
SpriteAnimation normal = SpriteAnimation.fromFrameData(
wire,
SpriteAnimationData.sequenced(
amount: 6,
stepTime: 0.1,
textureSize: Vector2(512, 512),
),
);
sprite = SpriteAnimationGroupComponent(
animations: {
WireState.normal: normal,
},
current: WireState.normal,
);
sprite.changePriorityWithoutResorting(WIRE_PRIORITY);
setSize(
gameRef.blockSize,
gameRef.blockSize,
);
}
double getRightEnd() {
return sprite.position.x + sprite.width;
}
void remove() {
sprite.remove();
}
}

103
lib/WireHolder.dart Normal file
View File

@ -0,0 +1,103 @@
import 'dart:math';
import 'package:firo_runner/Platform.dart';
import 'package:flame/flame.dart';
import 'Wire.dart';
import 'main.dart';
class WireHolder {
var wire;
Random random = Random();
late List<List<Wire>> wires = [];
Future loadWires() async {
wire = await Flame.images.load("wire-frames.png");
for (int i = 0; i < 9; i++) {
wires.add([]);
}
}
getWire() {
return wire;
}
bool generateWire(MyGame gameRef, int level, bool force) {
if (wires[level].isNotEmpty) {
return false;
}
if (random.nextInt(100) > 100) {
return true;
} else {
int nearestPlatform = level <= 0
? 0
: level <= 3
? 2
: level <= 6
? 5
: 8;
Platform? platform =
gameRef.platformHolder.getPlatformOffScreen(nearestPlatform);
double xCoordinate = -100;
if (level == 0) {
xCoordinate = gameRef.size.x;
} else if (platform != null) {
xCoordinate = platform.sprite.x;
} else {
return false;
}
Wire wire = Wire(gameRef);
if (level % 3 == 0) {
wire.sprite.renderFlipY = true;
wire.setPosition(
xCoordinate, gameRef.blockSize * level - gameRef.blockSize / 6);
} else {
wire.setPosition(
xCoordinate, gameRef.blockSize * level + gameRef.blockSize / 10);
}
wires[level].add(wire);
gameRef.add(wire.sprite);
if (platform != null) {
platform.removeChildren = () {
wires[level].remove(wire);
wire.remove();
};
}
return false;
}
}
int totalWires() {
int total = 0;
for (List<Wire> levelWires in wires) {
total += levelWires.length;
}
return total;
}
void update(double dt) {
for (List<Wire> wireLevel in wires) {
for (Wire p in wireLevel) {
p.update(dt);
}
}
}
void removePast(MyGame gameRef) {
for (List<Wire> wireLevel in wires) {
for (int i = 0; i < wireLevel.length;) {
if (wireLevel[i].sprite.x + wireLevel[i].sprite.width < 0) {
wireLevel[i].sprite.remove();
wireLevel.removeAt(i);
continue;
}
i++;
}
}
}
}

View File

@ -2,26 +2,27 @@ import 'dart:math';
import 'package:firo_runner/CoinHolder.dart';
import 'package:firo_runner/GameState.dart';
import 'package:firo_runner/MovingObject.dart';
import 'package:firo_runner/Platform.dart';
import 'package:firo_runner/PlatformHolder.dart';
import 'package:firo_runner/Wire.dart';
import 'package:firo_runner/WireHolder.dart';
import 'package:flame/components.dart';
import 'package:flame/extensions.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/gestures.dart';
import 'package:flame/keyboard.dart';
import 'package:flame/palette.dart';
import 'package:flame_audio/flame_audio.dart';
import 'package:flutter/material.dart';
import 'package:flame_audio/bgm.dart';
import 'package:flutter/services.dart';
import 'Runner.dart';
const COLOR = const Color(0xFFDDC0A3);
const SIZE = 52.0;
const GRAVITY = 400.0;
const BOOST = -380.0;
const RUNNER_PRIORITY = 100;
const PLATFORM_PRIORITY = 50;
const WIRE_PRIORITY = 25;
const COIN_PRIORITY = 70;
const BUG_PRIORITY = 75;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
@ -37,7 +38,8 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
);
late PlatformHolder platformHolder;
late Coinholder coinHolder;
late CoinHolder coinHolder;
late WireHolder wireHolder;
Random random = Random();
late Sprite background1;
@ -45,12 +47,6 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
late Runner runner;
late GameState gameState;
var background;
late var platform1;
late var platform2;
late var platform3;
late var wire;
late var bug;
late var coin;
var runnerPosition = Vector2(0, 0);
var runnerSize;
@ -60,25 +56,22 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
late double blockSize;
bool loaded = false;
late Wire wire;
@override
Future<void> onLoad() async {
debugMode = true;
// debugMode = true;
FlameAudio.bgm.initialize();
background = await Flame.images.load('bg.png');
background1 = Sprite(background);
background2 = Sprite(background);
platform1 = await Flame.images.load('platform1.png');
platform2 = await Flame.images.load('platform2.png');
platform3 = await Flame.images.load('platform3.png');
wire = await Flame.images.load('wire.png');
bug = await Flame.images.load('bug.png');
coin = await Flame.images.load('coin.png');
platformHolder = PlatformHolder();
await platformHolder.loadPlatforms();
coinHolder = Coinholder();
coinHolder = CoinHolder();
await coinHolder.loadCoins();
wireHolder = WireHolder();
await wireHolder.loadWires();
gameState = GameState();
await gameState.load(size);
@ -102,9 +95,14 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
void fillScreen() {
for (int i = 2; i < 9; i = i + 3) {
while (!platformHolder.generatePlatform(this, i, false));
while (!platformHolder.generatePlatform(this, i, false)) {}
}
int choseCoinLevel = random.nextInt(9);
int wireChosenRegion = random.nextInt(8) + 1;
if (wireChosenRegion % 3 != 2) {
wireHolder.generateWire(this, wireChosenRegion, false);
}
int choseCoinLevel = random.nextInt(8) + 1;
if (choseCoinLevel % 3 != 2) {
coinHolder.generateCoin(this, choseCoinLevel, false);
}
@ -119,8 +117,6 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
size: Vector2(size.y * (background!.width / background!.height), size.y),
);
super.render(canvas);
platformHolder.render(canvas);
coinHolder.render(canvas);
final fpsCount = fps(1);
textPaint.render(
canvas,
@ -133,11 +129,13 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
void update(double dt) {
platformHolder.removePast(this);
coinHolder.removePast(this);
wireHolder.removePast(this);
fillScreen();
super.update(dt);
gameState.update(dt);
platformHolder.update(dt);
coinHolder.update(dt);
wireHolder.update(dt);
}
@override
@ -157,36 +155,36 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
}
// Mobile controls
late List<double> xdeltas;
late List<double> ydeltas;
late List<double> xDeltas;
late List<double> yDeltas;
@override
void onPanStart(DragStartInfo info) {
xdeltas = List.empty(growable: true);
ydeltas = List.empty(growable: true);
xDeltas = List.empty(growable: true);
yDeltas = List.empty(growable: true);
}
@override
void onPanUpdate(DragUpdateInfo info) {
xdeltas.add(info.delta.game.x);
ydeltas.add(info.delta.game.y);
xDeltas.add(info.delta.game.x);
yDeltas.add(info.delta.game.y);
}
@override
void onPanEnd(DragEndInfo info) {
double xdelta = xdeltas.isEmpty
double xDelta = xDeltas.isEmpty
? 0
: xdeltas.reduce((value, element) => value + element);
double ydelta = ydeltas.isEmpty
: 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) {
: 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) {
} else if (xDelta.abs() < yDelta.abs()) {
if (yDelta > 0) {
runner.control("down");
} else {
runner.control("up");