Added the Main Menu #12, Mobile Icons #18. Runner animations finished in previous commit #6. Also implemented text scaling for different devices.

This commit is contained in:
Marco Salazar 2021-10-01 16:40:28 -06:00
parent 23e925a1b9
commit e8455500da
34 changed files with 437 additions and 146 deletions

View File

@ -3,7 +3,7 @@
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application
android:label="firo_runner" android:label="firo_runner"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/launcher_icon">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
assets/icon/head-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
assets/images/mm3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,4 +1,5 @@
import 'package:firo_runner/holder.dart'; import 'package:firo_runner/holder.dart';
import 'package:flame/components.dart';
import 'package:flame/flame.dart'; import 'package:flame/flame.dart';
import 'package:firo_runner/coin.dart'; import 'package:firo_runner/coin.dart';
@ -8,10 +9,49 @@ import 'package:firo_runner/platform.dart';
class CoinHolder extends Holder { class CoinHolder extends Holder {
late Image coin; late Image coin;
late SpriteAnimationGroupComponent sprite;
late MyGame personalGameRef;
@override @override
Future load() async { Future load() async {
coin = await Flame.images.load("coin-frames.png"); coin = await Flame.images.load("coin-frames.png");
SpriteAnimation normal = SpriteAnimation.fromFrameData(
coin,
SpriteAnimationData.sequenced(
amount: 12,
stepTime: 0.1,
textureSize: Vector2(512, 512),
),
);
sprite = SpriteAnimationGroupComponent(
animations: {
CoinState.normal: normal,
},
current: CoinState.normal,
);
sprite.changePriorityWithoutResorting(COIN_PRIORITY);
sprite.size = Vector2(20, 20);
}
void setPersonalGameRef(MyGame gameRef) {
personalGameRef = gameRef;
}
@override
void resize(Vector2 newSize, double xRatio, double yRatio) {
super.resize(newSize, xRatio, yRatio);
sprite.x *= xRatio;
sprite.y *= yRatio;
sprite.width *= xRatio;
sprite.height *= yRatio;
}
void renderCoinScore(Canvas c) {
sprite.position = Vector2(personalGameRef.size.x - 33, 10);
sprite.render(c);
} }
Image getCoin() { Image getCoin() {

View File

@ -12,22 +12,29 @@ class LoseMenuOverlay extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return Center( return Center(
child: Container( child: Container(
height: game.viewport.canvasSize.y, height: game.viewport.canvasSize.y,
width: game.viewport.canvasSize.x, width: game.viewport.canvasSize.x,
decoration: const BoxDecoration( decoration: const BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage('assets/images/overlay100.png'), image: lossImage,
fit: BoxFit.fill, fit: BoxFit.fill,
), ),
), ),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Material(
'Score: ' + game.gameState.getPlayerScore().toString(), type: MaterialType.transparency,
style: overlayText, child: Text(
'Score: ${game.gameState.getPlayerScore()}',
style: TextStyle(
color: Colors.white,
fontSize: width * 0.05,
),
),
), ),
const SizedBox(height: 32.0), const SizedBox(height: 32.0),
Row( Row(
@ -40,21 +47,24 @@ class LoseMenuOverlay extends StatelessWidget {
elevation: 8.0, elevation: 8.0,
child: Container( child: Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
image: DecorationImage( image:
image: AssetImage('assets/images/button.png'), DecorationImage(image: buttonImage, fit: BoxFit.fill),
fit: BoxFit.fill),
), ),
child: const Padding( child: Padding(
padding: EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
" Main Menu ", " Main Menu ",
style: overlayText, style: TextStyle(
color: Colors.white,
fontSize: width * 0.03,
),
), ),
), ),
), ),
// ), // ),
onPressed: () { onPressed: () {
// Go to the Main Menu // Go to the Main Menu
game.mainMenu();
}, },
), ),
const SizedBox( const SizedBox(
@ -67,15 +77,17 @@ class LoseMenuOverlay extends StatelessWidget {
elevation: 8.0, elevation: 8.0,
child: Container( child: Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
image: DecorationImage( image:
image: AssetImage('assets/images/button.png'), DecorationImage(image: buttonImage, fit: BoxFit.fill),
fit: BoxFit.fill),
), ),
child: const Padding( child: Padding(
padding: EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
" Replay ", " Replay ",
style: overlayText, style: TextStyle(
color: Colors.white,
fontSize: width * 0.03,
),
), ),
), ),
), ),

View File

@ -29,8 +29,10 @@ import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:firo_runner/lose_menu_overlay.dart'; import 'package:firo_runner/lose_menu_overlay.dart';
import 'package:firo_runner/main_menu_overlay.dart';
const COLOR = Color(0xFFDDC0A3); const COLOR = Color(0xFFDDC0A3);
const int LOADING_TIME = 2000000;
const LEVEL2 = 10000000; const LEVEL2 = 10000000;
const LEVEL3 = 20000000; const LEVEL3 = 20000000;
@ -50,24 +52,47 @@ const WIRE_PRIORITY = 25;
const FIREWORK_PRIORITY = 15; const FIREWORK_PRIORITY = 15;
const WINDOW_PRIORITY = 10; const WINDOW_PRIORITY = 10;
const overlayText = TextStyle( // const overlayText = TextStyle(
fontSize: 30, // fontSize: 30,
color: Colors.white, // color: Colors.white,
); // );
const AssetImage mainMenuImage = AssetImage('assets/images/mm3.gif');
const AssetImage lossImage = AssetImage('assets/images/overlay100.png');
const AssetImage buttonImage = AssetImage('assets/images/button-new.png');
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await Flame.device.fullScreen(); await Flame.device.fullScreen();
await Flame.device.setLandscape(); await Flame.device.setLandscape();
final myGame = MyGame(); final myGame = MyGame();
runApp(GameWidget<MyGame>( runApp(MaterialApp(
game: myGame, debugShowCheckedModeBanner: false,
overlayBuilderMap: { home: GameWidget<MyGame>(
'gameOver': (_, myGame) { game: myGame,
return LoseMenuOverlay(game: myGame); overlayBuilderMap: {
}, // Should be used once before all overlays are called. Flame has a slight
}, // delay when constructing the overlay widgets, so to make the text and
)); // images load together, all the other overlays should be called in the
// load section, and removed, and the loading black screen should be kept
// up until everything is finished loading.
'loading': (_, myGame) {
return Center(
child: Container(
height: myGame.viewport.canvasSize.y,
width: myGame.viewport.canvasSize.x,
color: Colors.black,
),
);
},
'mainMenu': (_, myGame) {
return MainMenuOverlay(game: myGame);
},
'gameOver': (_, myGame) {
return LoseMenuOverlay(game: myGame);
},
},
)));
} }
int getNearestPlatform(int level) { int getNearestPlatform(int level) {
@ -110,6 +135,7 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
late Wire wire; late Wire wire;
late TextComponent _distance; late TextComponent _distance;
late TextComponent _coins; late TextComponent _coins;
int startLoading = 0;
MyGame() : super() { MyGame() : super() {
viewport.resize(Vector2(1920, 1080)); viewport.resize(Vector2(1920, 1080));
@ -125,6 +151,7 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
platformHolder = PlatformHolder(); platformHolder = PlatformHolder();
await platformHolder.load(); await platformHolder.load();
coinHolder = CoinHolder(); coinHolder = CoinHolder();
coinHolder.setPersonalGameRef(this);
await coinHolder.load(); await coinHolder.load();
wireHolder = WireHolder(); wireHolder = WireHolder();
await wireHolder.load(); await wireHolder.load();
@ -142,19 +169,22 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
runner = Runner(); runner = Runner();
await runner.load(loadSpriteAnimation); await runner.load(loadSpriteAnimation);
if (!kIsWeb) {
playMusic();
}
loaded = true; loaded = true;
_distance = TextComponent("Distance: 0", _distance = TextComponent("Distance: 0",
position: Vector2(size.x - 100, 10), textRenderer: scoresPaint) position: Vector2(size.x - 100, 10), textRenderer: scoresPaint)
..anchor = Anchor.topRight; ..anchor = Anchor.topRight;
_distance.changePriorityWithoutResorting(OVERLAY_PRIORITY); _distance.changePriorityWithoutResorting(OVERLAY_PRIORITY);
_coins = TextComponent("Coins: 0", _coins = TextComponent(": 0",
position: Vector2(size.x - 10, 10), textRenderer: scoresPaint) position: Vector2(size.x - 35, 10), textRenderer: scoresPaint)
..anchor = Anchor.topRight; ..anchor = Anchor.topRight;
_coins.changePriorityWithoutResorting(OVERLAY_PRIORITY); _coins.changePriorityWithoutResorting(OVERLAY_PRIORITY);
overlays.add("gameOver");
overlays.remove('gameOver');
overlays.add("mainMenu");
overlays.add('loading');
setUp(); setUp();
gameState.setPaused();
startLoading = DateTime.now().microsecondsSinceEpoch;
} }
void playMusic() { void playMusic() {
@ -248,56 +278,56 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
bool shouldReset = false; bool shouldReset = false;
late Socket socket; // late Socket socket;
void dataHandler(data) { // void dataHandler(data) {
print(new String.fromCharCodes(data).trim()); // print(new String.fromCharCodes(data).trim());
} // }
//
// void errorHandler(error, StackTrace trace) {
// print(error);
// }
//
// void doneHandler() {
// socket.destroy();
// }
void errorHandler(error, StackTrace trace) { // Future<void> connectServer() async {
print(error); // try {
} // Socket.connect('10.0.0.224', 50018).then((Socket sock) {
// socket = sock;
void doneHandler() { // socket.listen(dataHandler,
socket.destroy(); // onError: errorHandler, onDone: doneHandler, cancelOnError: false);
} // });
// } catch (e) {
Future<void> connectServer() async { // print(e);
try { // }
Socket.connect('10.0.0.224', 50018).then((Socket sock) { // // try {
socket = sock; // // final response = await http.post(
socket.listen(dataHandler, // // Uri.parse('http://10.0.0.224:50017'),
onError: errorHandler, onDone: doneHandler, cancelOnError: false); // // headers: <String, String>{
}); // // 'Content-Type': 'application/json; charset=UTF-8',
} catch (e) { // // },
print(e); // // body: jsonEncode(<String, String>{
} // // 'title': "hi",
// try { // // }),
// final response = await http.post( // // );
// Uri.parse('http://10.0.0.224:50017'), // // if (response.statusCode == 201) {
// headers: <String, String>{ // // // If the server did return a 201 CREATED response,
// 'Content-Type': 'application/json; charset=UTF-8', // // // then parse the JSON.
// }, // // print("hello");
// body: jsonEncode(<String, String>{ // // print(response);
// 'title': "hi", // // print(response.body);
// }), // // } else {
// ); // // // If the server did not return a 201 CREATED response,
// if (response.statusCode == 201) { // // // then throw an exception.
// // If the server did return a 201 CREATED response, // // throw Exception('Failed to create album.');
// // then parse the JSON. // // }
// print("hello"); // // // var value = await channel.stream.first;
// print(response); // // // print(value);
// print(response.body); // // } catch (e) {
// } else { // // print(e);
// // If the server did not return a 201 CREATED response, // // }
// // then throw an exception. // }
// throw Exception('Failed to create album.');
// }
// // var value = await channel.stream.first;
// // print(value);
// } catch (e) {
// print(e);
// }
}
Future<void> displayLoss() async { Future<void> displayLoss() async {
if (!(runner.sprite.animation?.done() ?? false) && if (!(runner.sprite.animation?.done() ?? false) &&
@ -305,14 +335,20 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
firstDeath) { firstDeath) {
return; return;
} }
await connectServer(); // await connectServer();
firstDeath = false; firstDeath = false;
overlays.add('gameOver'); overlays.add('gameOver');
} }
void mainMenu() {
overlays.remove('gameOver');
overlays.add('mainMenu');
}
void reset() { void reset() {
runner.sprite.animation!.reset(); runner.sprite.animation!.reset();
overlays.remove('gameOver'); overlays.remove('gameOver');
overlays.remove('mainMenu');
shouldReset = false; shouldReset = false;
components.clear(); components.clear();
setUp(); setUp();
@ -349,19 +385,29 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
@override @override
void render(Canvas canvas) { void render(Canvas canvas) {
circuitBackground.render(canvas); if (!overlays.isActive('mainMenu')) {
fireworks.renderText(canvas); circuitBackground.render(canvas);
super.render(canvas); fireworks.renderText(canvas);
final fpsCount = fps(10000); super.render(canvas);
fireworksPaint.render( final fpsCount = fps(10000);
canvas, fireworksPaint.render(
fpsCount.toString(), canvas,
Vector2(0, 0), fpsCount.toString(),
); Vector2(0, 0),
);
coinHolder.renderCoinScore(canvas);
}
} }
@override @override
void update(double dt) { void update(double dt) {
if (overlays.isActive('loading') &&
(DateTime.now().microsecondsSinceEpoch - startLoading) > LOADING_TIME) {
overlays.remove('loading');
if (!kIsWeb) {
playMusic();
}
}
fireworks.update(dt); fireworks.update(dt);
platformHolder.removePast(this); platformHolder.removePast(this);
coinHolder.removePast(this); coinHolder.removePast(this);
@ -381,8 +427,10 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
wallHolder.update(dt); wallHolder.update(dt);
_distance.text = "Distance: ${gameState.getPlayerDistance()}"; _distance.text = "Distance: ${gameState.getPlayerDistance()}";
_coins.text = "Coins: ${gameState.numCoins}"; _coins.text = " ${gameState.numCoins}";
if (shouldReset && !overlays.isActive('gameOver')) { if (shouldReset &&
!overlays.isActive('gameOver') &&
!overlays.isActive('mainMenu')) {
displayLoss(); displayLoss();
} }
} }

142
lib/main_menu_overlay.dart Normal file
View File

@ -0,0 +1,142 @@
import 'package:flutter/material.dart';
import 'main.dart';
class MainMenuOverlay extends StatelessWidget {
const MainMenuOverlay({
Key? key,
required this.game,
}) : super(key: key);
final MyGame game;
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return Center(
child: Container(
height: game.viewport.canvasSize.y,
width: game.viewport.canvasSize.x,
decoration: const BoxDecoration(
image: DecorationImage(
image: mainMenuImage,
fit: BoxFit.fitWidth,
),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// const SizedBox(
// height: 32.0,
// ),
// const SizedBox(
// height: 32.0,
// ),
// const SizedBox(
// height: 32.0,
// ),
MaterialButton(
padding: const EdgeInsets.fromLTRB(8, 8, 8, 8),
textColor: Colors.white,
splashColor: Colors.greenAccent,
elevation: 8.0,
child: Container(
decoration: const BoxDecoration(
image:
DecorationImage(image: buttonImage, fit: BoxFit.fill),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
" Start ",
style: TextStyle(
color: Colors.white,
fontSize: width * 0.03,
),
),
),
),
// ),
onPressed: () {
// Go to the Main Menu
game.reset();
},
),
// MaterialButton(
// padding: const EdgeInsets.fromLTRB(8, 8, 8, 8),
// textColor: Colors.white,
// splashColor: Colors.greenAccent,
// elevation: 8.0,
// child: Container(
// decoration: const BoxDecoration(
// image:
// DecorationImage(image: buttonImage, fit: BoxFit.fill),
// ),
// child: Padding(
// padding: EdgeInsets.all(8.0),
// child: Text(
// " Deposit ",
// style: TextStyle(
// color: Colors.white,
// fontSize: width * 0.03,
// ),
// ),
// ),
// ),
// // ),
// onPressed: () {
// // Show QR code
// },
// ),
// MaterialButton(
// padding: const EdgeInsets.fromLTRB(8, 8, 8, 8),
// textColor: Colors.white,
// splashColor: Colors.greenAccent,
// elevation: 8.0,
// child: Container(
// decoration: const BoxDecoration(
// image:
// DecorationImage(image: buttonImage, fit: BoxFit.fill),
// ),
// child: Padding(
// padding: EdgeInsets.all(8.0),
// child: Text(
// " Leader Boards ",
// style: TextStyle(
// color: Colors.white,
// fontSize: width * 0.03,
// ),
// ),
// ),
// ),
// // ),
// onPressed: () {
// // Show QR code
// },
// ),
],
),
const SizedBox(
width: 32.0,
),
const SizedBox(
width: 32.0,
),
const SizedBox(
width: 32.0,
),
const SizedBox(
width: 32.0,
),
],
),
),
);
}
}

View File

@ -177,16 +177,11 @@ class Runner extends Component with HasGameRef<MyGame> {
} }
previousState = runnerState; previousState = runnerState;
sprite.clearEffects(); sprite.clearEffects();
level = 11;
sprite.addEffect(MoveEffect(
path: [Vector2(sprite.position.x, gameRef.blockSize * 11)],
duration: 2,
curve: Curves.bounceOut,
onComplete: () {},
));
runnerState = event; runnerState = event;
sprite.current = RunnerState.die; sprite.current = RunnerState.die;
dead = true;
gameRef.die(); gameRef.die();
sprite.addEffect(getFallingEffect());
break; break;
case "electrocute": case "electrocute":
if (dead) { if (dead) {
@ -194,16 +189,11 @@ class Runner extends Component with HasGameRef<MyGame> {
} }
previousState = runnerState; previousState = runnerState;
sprite.clearEffects(); sprite.clearEffects();
level = 11;
sprite.addEffect(MoveEffect(
path: [Vector2(sprite.position.x, gameRef.blockSize * 11)],
duration: 1,
curve: Curves.bounceOut,
onComplete: () {},
));
runnerState = event; runnerState = event;
sprite.current = RunnerState.electrocute; sprite.current = RunnerState.electrocute;
dead = true;
gameRef.die(); gameRef.die();
sprite.addEffect(getFallingEffect());
break; break;
case "glitch": case "glitch":
if (dead) { if (dead) {
@ -211,15 +201,9 @@ class Runner extends Component with HasGameRef<MyGame> {
} }
previousState = runnerState; previousState = runnerState;
sprite.clearEffects(); sprite.clearEffects();
level = 11;
sprite.addEffect(MoveEffect(
path: [Vector2(sprite.position.x, gameRef.blockSize * 11)],
duration: 1,
curve: Curves.bounceOut,
onComplete: () {},
));
runnerState = event; runnerState = event;
sprite.current = RunnerState.glitch; sprite.current = RunnerState.glitch;
dead = true;
gameRef.die(); gameRef.die();
break; break;
default: default:
@ -283,7 +267,7 @@ class Runner extends Component with HasGameRef<MyGame> {
} }
switch (input) { switch (input) {
case "up": case "up":
if (runnerState == "run") { if (runnerState == "run" || runnerState == "kick") {
event("jump"); event("jump");
} else if (runnerState == "float" && previousState == "jump") { } else if (runnerState == "float" && previousState == "jump") {
event("double_jump"); event("double_jump");
@ -293,7 +277,7 @@ class Runner extends Component with HasGameRef<MyGame> {
} }
break; break;
case "down": case "down":
if (runnerState == "run") { if (runnerState == "run" || runnerState == "kick") {
event("duck"); event("duck");
} else if (runnerState == "float" && onTopOfPlatform()) { } else if (runnerState == "float" && onTopOfPlatform()) {
sprite.clearEffects(); sprite.clearEffects();
@ -304,7 +288,7 @@ class Runner extends Component with HasGameRef<MyGame> {
} }
break; break;
case "right": case "right":
if (runnerState == "run") { if (runnerState == "run" || runnerState == "kick") {
event("kick"); event("kick");
} }
break; break;
@ -332,11 +316,13 @@ class Runner extends Component with HasGameRef<MyGame> {
} }
// If the animation is finished // If the animation is finished
if (sprite.animation?.done() ?? false) { if (sprite.animation?.done() ?? false) {
sprite.animation!.reset(); if (!dead) {
if (runnerState == "kick") { sprite.animation!.reset();
event("run"); if (runnerState == "kick") {
event("run");
}
sprite.current = RunnerState.run;
} }
sprite.current = RunnerState.run;
} }
if (runnerState == "float" || runnerState == "double_jump") { if (runnerState == "float" || runnerState == "double_jump") {
@ -425,8 +411,11 @@ class Runner extends Component with HasGameRef<MyGame> {
continue; continue;
} }
if (intersectState == "none") { if (intersectState == "none") {
Rect above = Rect.fromLTRB(runnerRect.left, runnerRect.top - 1, Rect above = Rect.fromLTRB(
runnerRect.right, runnerRect.bottom); runnerRect.left + sprite.width / 3,
runnerRect.top - 1,
runnerRect.right - sprite.width / 3,
runnerRect.bottom);
String aboveIntersect = bugLevel[i].intersect(above); String aboveIntersect = bugLevel[i].intersect(above);
if (aboveIntersect != "none" && if (aboveIntersect != "none" &&
(runnerState == "duck" || runnerState == "float")) { (runnerState == "duck" || runnerState == "float")) {
@ -570,24 +559,29 @@ class Runner extends Component with HasGameRef<MyGame> {
SpriteAnimation floating = SpriteAnimation floating =
SpriteAnimation.spriteList(floats, stepTime: 0.02, loop: true); SpriteAnimation.spriteList(floats, stepTime: 0.02, loop: true);
// TODO Falling animations List<Sprite> falls = [];
// List<Sprite> falls = []; for (int i = 1; i <= 38; i++) {
// for (int i = 1; i <= 38; i++) { final composition = ImageComposition()
// falls.add(Sprite(await Flame.images.load( ..add(satellites.elementAt(i - 1), Vector2(0, 0))
// 'runner/run/run00${i < 10 ? "0" + i.toString() : i.toString()}.png'))); ..add(
// } await Flame.images.load(
// 'runner/run/run00${i < 10 ? "0" + i.toString() : i.toString()}.png'),
// SpriteAnimation falling = Vector2(0, 0));
// SpriteAnimation.spriteList(falls, stepTime: 0.02, loop: true);
SpriteAnimation falling = await loadSpriteAnimation( falls.add(Sprite(await composition.compose()));
'fall-frames.png', }
SpriteAnimationData.sequenced(
amount: 7, SpriteAnimation falling =
stepTime: 0.1, SpriteAnimation.spriteList(falls, stepTime: 0.02, loop: false);
textureSize: Vector2(512, 512),
), // SpriteAnimation falling = await loadSpriteAnimation(
); // 'fall-frames.png',
// SpriteAnimationData.sequenced(
// amount: 7,
// stepTime: 0.1,
// textureSize: Vector2(512, 512),
// ),
// );
List<Sprite> dies = []; List<Sprite> dies = [];
for (int i = 1; i <= 57; i++) { for (int i = 1; i <= 57; i++) {

View File

@ -1,6 +1,20 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.5"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -104,6 +118,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.2"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -135,6 +156,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
image:
dependency: transitive
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.7"
js: js:
dependency: transitive dependency: transitive
description: description:
@ -219,6 +247,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.11.1" version: "1.11.1"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.0"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -329,6 +364,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0" version: "0.2.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "5.3.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
sdks: sdks:
dart: ">=2.13.0 <3.0.0" dart: ">=2.14.0 <3.0.0"
flutter: ">=2.0.0" flutter: ">=2.0.0"

View File

@ -32,10 +32,16 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
flutter_icons:
android: "launcher_icon"
ios: true
image_path: "assets/icon/head-logo.png"
dev_dependencies: dev_dependencies:
flutter_lints: ^1.0.4 flutter_lints: ^1.0.4
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_launcher_icons: "^0.9.2"
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 72 KiB