Added the Main Menu #12, Mobile Icons #18. Runner animations finished in previous commit #6. Also implemented text scaling for different devices.
@ -3,7 +3,7 @@
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<application
|
||||
android:label="firo_runner"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
android:icon="@mipmap/launcher_icon">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
BIN
android/app/src/main/res/mipmap-hdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/icon/head-logo.png
Normal file
After Width: | Height: | Size: 170 KiB |
BIN
assets/images/button-new.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/images/mm3.gif
Normal file
After Width: | Height: | Size: 4.0 MiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 148 KiB |
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 16 KiB |
@ -1,4 +1,5 @@
|
||||
import 'package:firo_runner/holder.dart';
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame/flame.dart';
|
||||
|
||||
import 'package:firo_runner/coin.dart';
|
||||
@ -8,10 +9,49 @@ import 'package:firo_runner/platform.dart';
|
||||
|
||||
class CoinHolder extends Holder {
|
||||
late Image coin;
|
||||
late SpriteAnimationGroupComponent sprite;
|
||||
late MyGame personalGameRef;
|
||||
|
||||
@override
|
||||
Future load() async {
|
||||
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() {
|
||||
|
@ -12,22 +12,29 @@ class LoseMenuOverlay extends StatelessWidget {
|
||||
|
||||
@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: AssetImage('assets/images/overlay100.png'),
|
||||
image: lossImage,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Score: ' + game.gameState.getPlayerScore().toString(),
|
||||
style: overlayText,
|
||||
Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Text(
|
||||
'Score: ${game.gameState.getPlayerScore()}',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: width * 0.05,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32.0),
|
||||
Row(
|
||||
@ -40,21 +47,24 @@ class LoseMenuOverlay extends StatelessWidget {
|
||||
elevation: 8.0,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/images/button.png'),
|
||||
fit: BoxFit.fill),
|
||||
image:
|
||||
DecorationImage(image: buttonImage, fit: BoxFit.fill),
|
||||
),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
" Main Menu ",
|
||||
style: overlayText,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: width * 0.03,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// ),
|
||||
onPressed: () {
|
||||
// Go to the Main Menu
|
||||
game.mainMenu();
|
||||
},
|
||||
),
|
||||
const SizedBox(
|
||||
@ -67,15 +77,17 @@ class LoseMenuOverlay extends StatelessWidget {
|
||||
elevation: 8.0,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/images/button.png'),
|
||||
fit: BoxFit.fill),
|
||||
image:
|
||||
DecorationImage(image: buttonImage, fit: BoxFit.fill),
|
||||
),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
" Replay ",
|
||||
style: overlayText,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: width * 0.03,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
168
lib/main.dart
@ -29,8 +29,10 @@ import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'package:firo_runner/lose_menu_overlay.dart';
|
||||
import 'package:firo_runner/main_menu_overlay.dart';
|
||||
|
||||
const COLOR = Color(0xFFDDC0A3);
|
||||
const int LOADING_TIME = 2000000;
|
||||
|
||||
const LEVEL2 = 10000000;
|
||||
const LEVEL3 = 20000000;
|
||||
@ -50,24 +52,47 @@ const WIRE_PRIORITY = 25;
|
||||
const FIREWORK_PRIORITY = 15;
|
||||
const WINDOW_PRIORITY = 10;
|
||||
|
||||
const overlayText = TextStyle(
|
||||
fontSize: 30,
|
||||
color: Colors.white,
|
||||
);
|
||||
// const overlayText = TextStyle(
|
||||
// fontSize: 30,
|
||||
// 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 {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await Flame.device.fullScreen();
|
||||
await Flame.device.setLandscape();
|
||||
final myGame = MyGame();
|
||||
runApp(GameWidget<MyGame>(
|
||||
runApp(MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
home: GameWidget<MyGame>(
|
||||
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) {
|
||||
@ -110,6 +135,7 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
|
||||
late Wire wire;
|
||||
late TextComponent _distance;
|
||||
late TextComponent _coins;
|
||||
int startLoading = 0;
|
||||
|
||||
MyGame() : super() {
|
||||
viewport.resize(Vector2(1920, 1080));
|
||||
@ -125,6 +151,7 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
|
||||
platformHolder = PlatformHolder();
|
||||
await platformHolder.load();
|
||||
coinHolder = CoinHolder();
|
||||
coinHolder.setPersonalGameRef(this);
|
||||
await coinHolder.load();
|
||||
wireHolder = WireHolder();
|
||||
await wireHolder.load();
|
||||
@ -142,19 +169,22 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
|
||||
runner = Runner();
|
||||
await runner.load(loadSpriteAnimation);
|
||||
|
||||
if (!kIsWeb) {
|
||||
playMusic();
|
||||
}
|
||||
loaded = true;
|
||||
_distance = TextComponent("Distance: 0",
|
||||
position: Vector2(size.x - 100, 10), textRenderer: scoresPaint)
|
||||
..anchor = Anchor.topRight;
|
||||
_distance.changePriorityWithoutResorting(OVERLAY_PRIORITY);
|
||||
_coins = TextComponent("Coins: 0",
|
||||
position: Vector2(size.x - 10, 10), textRenderer: scoresPaint)
|
||||
_coins = TextComponent(": 0",
|
||||
position: Vector2(size.x - 35, 10), textRenderer: scoresPaint)
|
||||
..anchor = Anchor.topRight;
|
||||
_coins.changePriorityWithoutResorting(OVERLAY_PRIORITY);
|
||||
overlays.add("gameOver");
|
||||
overlays.remove('gameOver');
|
||||
overlays.add("mainMenu");
|
||||
overlays.add('loading');
|
||||
setUp();
|
||||
gameState.setPaused();
|
||||
startLoading = DateTime.now().microsecondsSinceEpoch;
|
||||
}
|
||||
|
||||
void playMusic() {
|
||||
@ -248,56 +278,56 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
|
||||
|
||||
bool shouldReset = false;
|
||||
|
||||
late Socket socket;
|
||||
void dataHandler(data) {
|
||||
print(new String.fromCharCodes(data).trim());
|
||||
}
|
||||
|
||||
void errorHandler(error, StackTrace trace) {
|
||||
print(error);
|
||||
}
|
||||
|
||||
void doneHandler() {
|
||||
socket.destroy();
|
||||
}
|
||||
|
||||
Future<void> connectServer() async {
|
||||
try {
|
||||
Socket.connect('10.0.0.224', 50018).then((Socket sock) {
|
||||
socket = sock;
|
||||
socket.listen(dataHandler,
|
||||
onError: errorHandler, onDone: doneHandler, cancelOnError: false);
|
||||
});
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
// try {
|
||||
// final response = await http.post(
|
||||
// Uri.parse('http://10.0.0.224:50017'),
|
||||
// headers: <String, String>{
|
||||
// 'Content-Type': 'application/json; charset=UTF-8',
|
||||
// },
|
||||
// body: jsonEncode(<String, String>{
|
||||
// 'title': "hi",
|
||||
// }),
|
||||
// );
|
||||
// if (response.statusCode == 201) {
|
||||
// // If the server did return a 201 CREATED response,
|
||||
// // then parse the JSON.
|
||||
// print("hello");
|
||||
// print(response);
|
||||
// print(response.body);
|
||||
// } else {
|
||||
// // If the server did not return a 201 CREATED response,
|
||||
// // then throw an exception.
|
||||
// throw Exception('Failed to create album.');
|
||||
// late Socket socket;
|
||||
// void dataHandler(data) {
|
||||
// print(new String.fromCharCodes(data).trim());
|
||||
// }
|
||||
// // var value = await channel.stream.first;
|
||||
// // print(value);
|
||||
//
|
||||
// void errorHandler(error, StackTrace trace) {
|
||||
// print(error);
|
||||
// }
|
||||
//
|
||||
// void doneHandler() {
|
||||
// socket.destroy();
|
||||
// }
|
||||
|
||||
// Future<void> connectServer() async {
|
||||
// try {
|
||||
// Socket.connect('10.0.0.224', 50018).then((Socket sock) {
|
||||
// socket = sock;
|
||||
// socket.listen(dataHandler,
|
||||
// onError: errorHandler, onDone: doneHandler, cancelOnError: false);
|
||||
// });
|
||||
// } catch (e) {
|
||||
// print(e);
|
||||
// }
|
||||
}
|
||||
// // try {
|
||||
// // final response = await http.post(
|
||||
// // Uri.parse('http://10.0.0.224:50017'),
|
||||
// // headers: <String, String>{
|
||||
// // 'Content-Type': 'application/json; charset=UTF-8',
|
||||
// // },
|
||||
// // body: jsonEncode(<String, String>{
|
||||
// // 'title': "hi",
|
||||
// // }),
|
||||
// // );
|
||||
// // if (response.statusCode == 201) {
|
||||
// // // If the server did return a 201 CREATED response,
|
||||
// // // then parse the JSON.
|
||||
// // print("hello");
|
||||
// // print(response);
|
||||
// // print(response.body);
|
||||
// // } else {
|
||||
// // // 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 {
|
||||
if (!(runner.sprite.animation?.done() ?? false) &&
|
||||
@ -305,14 +335,20 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
|
||||
firstDeath) {
|
||||
return;
|
||||
}
|
||||
await connectServer();
|
||||
// await connectServer();
|
||||
firstDeath = false;
|
||||
overlays.add('gameOver');
|
||||
}
|
||||
|
||||
void mainMenu() {
|
||||
overlays.remove('gameOver');
|
||||
overlays.add('mainMenu');
|
||||
}
|
||||
|
||||
void reset() {
|
||||
runner.sprite.animation!.reset();
|
||||
overlays.remove('gameOver');
|
||||
overlays.remove('mainMenu');
|
||||
shouldReset = false;
|
||||
components.clear();
|
||||
setUp();
|
||||
@ -349,6 +385,7 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
|
||||
|
||||
@override
|
||||
void render(Canvas canvas) {
|
||||
if (!overlays.isActive('mainMenu')) {
|
||||
circuitBackground.render(canvas);
|
||||
fireworks.renderText(canvas);
|
||||
super.render(canvas);
|
||||
@ -358,10 +395,19 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
|
||||
fpsCount.toString(),
|
||||
Vector2(0, 0),
|
||||
);
|
||||
coinHolder.renderCoinScore(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void update(double dt) {
|
||||
if (overlays.isActive('loading') &&
|
||||
(DateTime.now().microsecondsSinceEpoch - startLoading) > LOADING_TIME) {
|
||||
overlays.remove('loading');
|
||||
if (!kIsWeb) {
|
||||
playMusic();
|
||||
}
|
||||
}
|
||||
fireworks.update(dt);
|
||||
platformHolder.removePast(this);
|
||||
coinHolder.removePast(this);
|
||||
@ -381,8 +427,10 @@ class MyGame extends BaseGame with PanDetector, TapDetector, KeyboardEvents {
|
||||
wallHolder.update(dt);
|
||||
|
||||
_distance.text = "Distance: ${gameState.getPlayerDistance()}";
|
||||
_coins.text = "Coins: ${gameState.numCoins}";
|
||||
if (shouldReset && !overlays.isActive('gameOver')) {
|
||||
_coins.text = " ${gameState.numCoins}";
|
||||
if (shouldReset &&
|
||||
!overlays.isActive('gameOver') &&
|
||||
!overlays.isActive('mainMenu')) {
|
||||
displayLoss();
|
||||
}
|
||||
}
|
||||
|
142
lib/main_menu_overlay.dart
Normal 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,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -177,16 +177,11 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
}
|
||||
previousState = runnerState;
|
||||
sprite.clearEffects();
|
||||
level = 11;
|
||||
sprite.addEffect(MoveEffect(
|
||||
path: [Vector2(sprite.position.x, gameRef.blockSize * 11)],
|
||||
duration: 2,
|
||||
curve: Curves.bounceOut,
|
||||
onComplete: () {},
|
||||
));
|
||||
runnerState = event;
|
||||
sprite.current = RunnerState.die;
|
||||
dead = true;
|
||||
gameRef.die();
|
||||
sprite.addEffect(getFallingEffect());
|
||||
break;
|
||||
case "electrocute":
|
||||
if (dead) {
|
||||
@ -194,16 +189,11 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
}
|
||||
previousState = runnerState;
|
||||
sprite.clearEffects();
|
||||
level = 11;
|
||||
sprite.addEffect(MoveEffect(
|
||||
path: [Vector2(sprite.position.x, gameRef.blockSize * 11)],
|
||||
duration: 1,
|
||||
curve: Curves.bounceOut,
|
||||
onComplete: () {},
|
||||
));
|
||||
runnerState = event;
|
||||
sprite.current = RunnerState.electrocute;
|
||||
dead = true;
|
||||
gameRef.die();
|
||||
sprite.addEffect(getFallingEffect());
|
||||
break;
|
||||
case "glitch":
|
||||
if (dead) {
|
||||
@ -211,15 +201,9 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
}
|
||||
previousState = runnerState;
|
||||
sprite.clearEffects();
|
||||
level = 11;
|
||||
sprite.addEffect(MoveEffect(
|
||||
path: [Vector2(sprite.position.x, gameRef.blockSize * 11)],
|
||||
duration: 1,
|
||||
curve: Curves.bounceOut,
|
||||
onComplete: () {},
|
||||
));
|
||||
runnerState = event;
|
||||
sprite.current = RunnerState.glitch;
|
||||
dead = true;
|
||||
gameRef.die();
|
||||
break;
|
||||
default:
|
||||
@ -283,7 +267,7 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
}
|
||||
switch (input) {
|
||||
case "up":
|
||||
if (runnerState == "run") {
|
||||
if (runnerState == "run" || runnerState == "kick") {
|
||||
event("jump");
|
||||
} else if (runnerState == "float" && previousState == "jump") {
|
||||
event("double_jump");
|
||||
@ -293,7 +277,7 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
}
|
||||
break;
|
||||
case "down":
|
||||
if (runnerState == "run") {
|
||||
if (runnerState == "run" || runnerState == "kick") {
|
||||
event("duck");
|
||||
} else if (runnerState == "float" && onTopOfPlatform()) {
|
||||
sprite.clearEffects();
|
||||
@ -304,7 +288,7 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
}
|
||||
break;
|
||||
case "right":
|
||||
if (runnerState == "run") {
|
||||
if (runnerState == "run" || runnerState == "kick") {
|
||||
event("kick");
|
||||
}
|
||||
break;
|
||||
@ -332,12 +316,14 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
}
|
||||
// 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()) {
|
||||
@ -425,8 +411,11 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
continue;
|
||||
}
|
||||
if (intersectState == "none") {
|
||||
Rect above = Rect.fromLTRB(runnerRect.left, runnerRect.top - 1,
|
||||
runnerRect.right, runnerRect.bottom);
|
||||
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")) {
|
||||
@ -570,24 +559,29 @@ class Runner extends Component with HasGameRef<MyGame> {
|
||||
SpriteAnimation floating =
|
||||
SpriteAnimation.spriteList(floats, stepTime: 0.02, loop: true);
|
||||
|
||||
// TODO Falling animations
|
||||
// List<Sprite> falls = [];
|
||||
// for (int i = 1; i <= 38; i++) {
|
||||
// falls.add(Sprite(await Flame.images.load(
|
||||
// 'runner/run/run00${i < 10 ? "0" + i.toString() : i.toString()}.png')));
|
||||
// }
|
||||
//
|
||||
// SpriteAnimation falling =
|
||||
// SpriteAnimation.spriteList(falls, stepTime: 0.02, loop: true);
|
||||
List<Sprite> falls = [];
|
||||
for (int i = 1; i <= 38; i++) {
|
||||
final composition = ImageComposition()
|
||||
..add(satellites.elementAt(i - 1), Vector2(0, 0))
|
||||
..add(
|
||||
await Flame.images.load(
|
||||
'runner/run/run00${i < 10 ? "0" + i.toString() : i.toString()}.png'),
|
||||
Vector2(0, 0));
|
||||
|
||||
SpriteAnimation falling = await loadSpriteAnimation(
|
||||
'fall-frames.png',
|
||||
SpriteAnimationData.sequenced(
|
||||
amount: 7,
|
||||
stepTime: 0.1,
|
||||
textureSize: Vector2(512, 512),
|
||||
),
|
||||
);
|
||||
falls.add(Sprite(await composition.compose()));
|
||||
}
|
||||
|
||||
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++) {
|
||||
|
51
pubspec.lock
@ -1,6 +1,20 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -104,6 +118,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
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:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -135,6 +156,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -219,6 +247,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -329,6 +364,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
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:
|
||||
dart: ">=2.13.0 <3.0.0"
|
||||
dart: ">=2.14.0 <3.0.0"
|
||||
flutter: ">=2.0.0"
|
||||
|
@ -32,10 +32,16 @@ dependencies:
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.2
|
||||
|
||||
flutter_icons:
|
||||
android: "launcher_icon"
|
||||
ios: true
|
||||
image_path: "assets/icon/head-logo.png"
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^1.0.4
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_launcher_icons: "^0.9.2"
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 72 KiB |