2021-10-09 03:59:38 +00:00
|
|
|
import 'package:firo_runner/holders/holder.dart';
|
2021-09-03 23:29:18 +00:00
|
|
|
import 'package:firo_runner/main.dart';
|
2021-10-09 03:59:38 +00:00
|
|
|
import 'package:firo_runner/moving_objects/moving_object.dart';
|
2021-10-05 23:19:58 +00:00
|
|
|
import 'package:flame/components.dart';
|
2021-10-09 03:59:38 +00:00
|
|
|
import 'package:firo_runner/moving_objects/platform.dart';
|
2021-09-03 23:29:18 +00:00
|
|
|
|
2021-09-16 21:15:32 +00:00
|
|
|
class PlatformHolder extends Holder {
|
2021-10-05 23:19:58 +00:00
|
|
|
late List<Sprite> l1;
|
|
|
|
late List<Sprite> l2;
|
|
|
|
late List<Sprite> m1;
|
|
|
|
late List<Sprite> m2;
|
|
|
|
late List<Sprite> r1;
|
|
|
|
late List<Sprite> r2;
|
|
|
|
late List<Sprite> o1;
|
|
|
|
late List<Sprite> o2;
|
2021-09-22 19:26:06 +00:00
|
|
|
bool noTopObstaclesForNext = false;
|
|
|
|
bool noMiddleObstaclesForNext = false;
|
2021-09-11 02:39:32 +00:00
|
|
|
int timeSinceLastTopHole = 0;
|
|
|
|
int timeSinceLastBottomHole = 0;
|
2021-09-03 23:29:18 +00:00
|
|
|
|
2021-09-16 21:15:32 +00:00
|
|
|
@override
|
|
|
|
Future load() async {
|
2021-10-05 23:19:58 +00:00
|
|
|
l1 = await loadListSprites("platform", "platform-left-nowire-frames", 5);
|
|
|
|
l2 = await loadListSprites("platform", "platform-left-wire-frames", 5);
|
|
|
|
m1 = await loadListSprites("platform", "platform-mid-nowire-frames", 5);
|
|
|
|
m2 = await loadListSprites("platform", "platform-mid-wire-frames", 5);
|
|
|
|
r1 = await loadListSprites("platform", "platform-right-nowire-frames", 5);
|
|
|
|
r2 = await loadListSprites("platform", "platform-right-wire-frames", 5);
|
|
|
|
o1 = await loadListSprites("platform", "platform-single-nowire-frames", 5);
|
|
|
|
o2 = await loadListSprites("platform", "platform-single-wire-frames", 5);
|
2021-09-05 22:36:36 +00:00
|
|
|
}
|
|
|
|
|
2021-09-16 21:15:32 +00:00
|
|
|
@override
|
2021-09-05 22:36:36 +00:00
|
|
|
void setUp() {
|
2021-09-11 02:39:32 +00:00
|
|
|
timeSinceLastTopHole = 0;
|
|
|
|
timeSinceLastBottomHole = 0;
|
2021-09-16 21:15:32 +00:00
|
|
|
super.setUp();
|
2021-09-03 23:29:18 +00:00
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Removes obstacles from around openings in the floor so that the game is
|
|
|
|
// not unfair to the player.
|
2021-09-13 19:21:52 +00:00
|
|
|
void removeUnfairObstacles(
|
|
|
|
MyGame gameRef, Platform currentPlatform, int from, int to) {
|
|
|
|
for (int i = from; i <= to; i++) {
|
|
|
|
if (i == 0) {
|
2021-10-09 18:32:15 +00:00
|
|
|
// First level has a harder difficulty curve, and no platforms are on
|
|
|
|
// level -1, so objects have to be removed differently.
|
2021-09-16 21:15:32 +00:00
|
|
|
List<MovingObject> bugLevel = gameRef.bugHolder.objects[0];
|
|
|
|
for (MovingObject bug in gameRef.bugHolder.objects[0]) {
|
2021-09-13 19:21:52 +00:00
|
|
|
if (bug.sprite.x >= currentPlatform.sprite.x &&
|
|
|
|
bug.sprite.x <
|
|
|
|
currentPlatform.sprite.x + 4 * currentPlatform.sprite.width) {
|
2021-09-16 21:15:32 +00:00
|
|
|
gameRef.bugHolder.remove(bugLevel, bugLevel.indexOf(bug));
|
2021-09-13 19:21:52 +00:00
|
|
|
}
|
|
|
|
}
|
2021-09-16 21:15:32 +00:00
|
|
|
List<MovingObject> wireLevel = gameRef.wireHolder.objects[0];
|
|
|
|
for (MovingObject wire in gameRef.wireHolder.objects[0]) {
|
2021-09-13 19:21:52 +00:00
|
|
|
if (wire.sprite.x >= currentPlatform.sprite.x &&
|
|
|
|
wire.sprite.x <
|
|
|
|
currentPlatform.sprite.x + 4 * currentPlatform.sprite.width) {
|
2021-09-16 21:15:32 +00:00
|
|
|
gameRef.wireHolder.remove(wireLevel, wireLevel.indexOf(wire));
|
2021-09-13 19:21:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2021-10-09 18:32:15 +00:00
|
|
|
// All other objects on the other levels can be removed simply.
|
2021-09-13 19:21:52 +00:00
|
|
|
int nearestPlatform = getNearestPlatform(i);
|
2021-09-16 21:15:32 +00:00
|
|
|
for (MovingObject platform in objects[nearestPlatform]) {
|
2021-09-13 19:21:52 +00:00
|
|
|
if (platform.sprite.x >= currentPlatform.sprite.x &&
|
|
|
|
platform.sprite.x <
|
|
|
|
currentPlatform.sprite.x + 4 * currentPlatform.sprite.width) {
|
2021-09-16 21:15:32 +00:00
|
|
|
(platform as Platform).removeChildrenObjects();
|
2021-09-13 19:21:52 +00:00
|
|
|
platform.prohibitObstacles = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Generate all the platforms in the game.
|
|
|
|
// Including top openings, and bottom structures.
|
2021-09-11 02:39:32 +00:00
|
|
|
void generatePlatforms(MyGame gameRef) {
|
|
|
|
while (!generatePlatform(gameRef, 2)) {
|
|
|
|
timeSinceLastTopHole++;
|
|
|
|
}
|
|
|
|
while (!generatePlatform(gameRef, 5)) {
|
|
|
|
timeSinceLastBottomHole++;
|
|
|
|
}
|
|
|
|
|
|
|
|
int topChance =
|
|
|
|
random.nextInt(timeSinceLastTopHole > 0 ? timeSinceLastTopHole : 1);
|
|
|
|
int bottomChance = random
|
|
|
|
.nextInt(timeSinceLastBottomHole > 0 ? timeSinceLastBottomHole : 1);
|
|
|
|
|
|
|
|
if (topChance > 50) {
|
2021-09-13 19:21:52 +00:00
|
|
|
removeUnfairObstacles(
|
2021-09-16 21:15:32 +00:00
|
|
|
gameRef, objects[2][objects[2].length - 4] as Platform, 0, 4);
|
2021-09-13 19:21:52 +00:00
|
|
|
// Create an opening in the top.
|
2021-09-16 21:15:32 +00:00
|
|
|
remove(objects[2], objects[2].length - 2);
|
|
|
|
remove(objects[2], objects[2].length - 2);
|
2021-09-13 19:21:52 +00:00
|
|
|
|
2021-09-11 02:39:32 +00:00
|
|
|
timeSinceLastTopHole = 0;
|
2021-09-22 19:26:06 +00:00
|
|
|
noTopObstaclesForNext = true;
|
2021-09-11 02:39:32 +00:00
|
|
|
}
|
|
|
|
if (bottomChance > 30) {
|
2021-09-16 21:15:32 +00:00
|
|
|
Platform start = objects[5].elementAt(objects[5].length - 10) as Platform;
|
2021-09-11 02:39:32 +00:00
|
|
|
generatePlatform(gameRef, 8, xPosition: start.sprite.position.x);
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
generatePlatform(gameRef, 8);
|
|
|
|
}
|
2021-09-16 21:15:32 +00:00
|
|
|
int lastToRemove = objects[5].length - 3;
|
|
|
|
int firstToRemove = objects[5].length - 10;
|
2021-09-13 19:21:52 +00:00
|
|
|
|
2021-09-16 21:15:32 +00:00
|
|
|
removeUnfairObstacles(
|
|
|
|
gameRef, objects[5][lastToRemove - 1] as Platform, 3, 7);
|
|
|
|
remove(objects[5], lastToRemove);
|
|
|
|
remove(objects[5], lastToRemove);
|
2021-09-13 19:21:52 +00:00
|
|
|
|
2021-09-16 21:15:32 +00:00
|
|
|
removeUnfairObstacles(
|
|
|
|
gameRef, objects[5][firstToRemove - 1] as Platform, 3, 7);
|
|
|
|
remove(objects[5], firstToRemove);
|
|
|
|
remove(objects[5], firstToRemove);
|
2021-09-13 19:21:52 +00:00
|
|
|
|
2021-09-11 02:39:32 +00:00
|
|
|
timeSinceLastBottomHole = 0;
|
2021-09-22 19:26:06 +00:00
|
|
|
noMiddleObstaclesForNext = true;
|
2021-09-11 02:39:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Create a platform object.
|
2021-09-11 02:39:32 +00:00
|
|
|
bool generatePlatform(MyGame gameRef, int level, {double xPosition = 0}) {
|
|
|
|
double xCoordinate = xPosition;
|
2021-09-16 21:15:32 +00:00
|
|
|
if (objects[level].isNotEmpty && xPosition == 0) {
|
|
|
|
xCoordinate = objects[level].last.getRightEnd();
|
2021-09-03 23:29:18 +00:00
|
|
|
}
|
|
|
|
|
2021-09-11 02:39:32 +00:00
|
|
|
if (xCoordinate > gameRef.size.x + 2000) {
|
2021-09-03 23:29:18 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
Platform platform = Platform(gameRef);
|
2021-09-04 22:56:08 +00:00
|
|
|
platform.setPosition(xCoordinate, gameRef.blockSize * level);
|
2021-09-08 19:27:06 +00:00
|
|
|
platform.row = level;
|
2021-09-04 22:56:08 +00:00
|
|
|
gameRef.add(platform.sprite);
|
2021-09-16 21:15:32 +00:00
|
|
|
objects[level].add(platform);
|
2021-09-22 19:26:06 +00:00
|
|
|
if (level == 2 && noTopObstaclesForNext) {
|
|
|
|
platform.prohibitObstacles = true;
|
|
|
|
noTopObstaclesForNext = false;
|
|
|
|
} else if (level == 5 && noMiddleObstaclesForNext) {
|
|
|
|
platform.prohibitObstacles = true;
|
|
|
|
noMiddleObstaclesForNext = false;
|
|
|
|
}
|
2021-09-03 23:29:18 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-09 18:32:15 +00:00
|
|
|
// Choose a random platform that is off screen from the player.
|
2021-09-04 22:56:08 +00:00
|
|
|
Platform? getPlatformOffScreen(int level) {
|
2021-09-16 21:15:32 +00:00
|
|
|
for (int i = 0; i < objects[level].length; i++) {
|
|
|
|
Platform p = objects[level][i] as Platform;
|
2021-09-04 22:56:08 +00:00
|
|
|
if (p.sprite.x > p.gameRef.size.x) {
|
2021-09-16 21:15:32 +00:00
|
|
|
int chosenIndex = random.nextInt(objects[level].length - i) + i;
|
|
|
|
return objects[level][chosenIndex] as Platform;
|
2021-09-04 22:56:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2021-09-03 23:29:18 +00:00
|
|
|
}
|