diff --git a/assets/images/button.png b/assets/images/button.png index a4ad799..22ee8d5 100644 Binary files a/assets/images/button.png and b/assets/images/button.png differ diff --git a/lib/circuit_background.dart b/lib/circuit_background.dart index b9d178e..da2f3b5 100644 --- a/lib/circuit_background.dart +++ b/lib/circuit_background.dart @@ -1,396 +1,397 @@ -import 'package:firo_runner/moving_object.dart'; -import 'package:firo_runner/main.dart'; -import 'package:flame/components.dart'; -import 'package:flame/flame.dart'; -import 'package:flame/extensions.dart'; - -enum WindowState { - first, - second, - third, - fourth, - fifth, - sixth, - seventh, -} - -enum OverlayState { - first, - second, - third, - fourth, - fifth, - sixth, - seventh, -} - -class CircuitBackground extends MovingObject { - late Image background; - - late Image overlay0; - late Image overlay1; - late Image overlay2; - late Image overlay3; - late Image overlay4; - late Image overlay5; - late Image overlay6; - - late Image windows0; - late Image windows1; - late Image windows2; - late Image windows3; - late Image windows4; - late Image windows5; - late Image windows6; - - late Sprite background1; - late Sprite background2; - late SpriteAnimationGroupComponent windowA; - late SpriteAnimationGroupComponent windowB; - late SpriteAnimationGroupComponent overlayA; - late SpriteAnimationGroupComponent overlayB; - Vector2 background1Size = Vector2(0, 0); - Vector2 background2Size = Vector2(0, 0); - Vector2 background1Position = Vector2(0, 0); - Vector2 background2Position = Vector2(0, 0); - - CircuitBackground(MyGame gameRef) : super(gameRef); - - Future load() async { - background = await Flame.images.load("bg.png"); - background1 = Sprite(background); - background2 = Sprite(background); - - overlay0 = await Flame.images.load("overlay100.png"); - overlay1 = await Flame.images.load("overlay90.png"); - overlay2 = await Flame.images.load("overlay80.png"); - overlay3 = await Flame.images.load("overlay70.png"); - overlay4 = await Flame.images.load("overlay60.png"); - overlay5 = await Flame.images.load("overlay50.png"); - overlay6 = await Flame.images.load("overlay40.png"); - - SpriteAnimation firstOverlay = SpriteAnimation.fromFrameData( - overlay0, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation secondOverlay = SpriteAnimation.fromFrameData( - overlay1, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation thirdOverlay = SpriteAnimation.fromFrameData( - overlay2, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation fourthOverlay = SpriteAnimation.fromFrameData( - overlay3, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation fifthOverlay = SpriteAnimation.fromFrameData( - overlay4, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation sixthOverlay = SpriteAnimation.fromFrameData( - overlay5, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation seventhOverlay = SpriteAnimation.fromFrameData( - overlay6, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - overlayA = SpriteAnimationGroupComponent( - animations: { - OverlayState.first: firstOverlay, - OverlayState.second: secondOverlay, - OverlayState.third: thirdOverlay, - OverlayState.fourth: fourthOverlay, - OverlayState.fifth: fifthOverlay, - OverlayState.sixth: sixthOverlay, - OverlayState.seventh: seventhOverlay, - }, - current: OverlayState.first, - ); - - overlayB = SpriteAnimationGroupComponent( - animations: { - OverlayState.first: firstOverlay, - OverlayState.second: secondOverlay, - OverlayState.third: thirdOverlay, - OverlayState.fourth: fourthOverlay, - OverlayState.fifth: fifthOverlay, - OverlayState.sixth: sixthOverlay, - OverlayState.seventh: seventhOverlay, - }, - current: OverlayState.first, - ); - - overlayA.changePriorityWithoutResorting(WINDOW_PRIORITY - 1); - - overlayA.changePriorityWithoutResorting(WINDOW_PRIORITY - 1); - - windows0 = await Flame.images.load("windows-0.png"); - windows1 = await Flame.images.load("windows-1.png"); - windows2 = await Flame.images.load("windows-2.png"); - windows3 = await Flame.images.load("windows-3.png"); - windows4 = await Flame.images.load("windows-4.png"); - windows5 = await Flame.images.load("windows-5.png"); - windows6 = await Flame.images.load("windows-6.png"); - - SpriteAnimation firstWindow = SpriteAnimation.fromFrameData( - windows0, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation secondWindow = SpriteAnimation.fromFrameData( - windows1, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation thirdWindow = SpriteAnimation.fromFrameData( - windows2, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation fourthWindow = SpriteAnimation.fromFrameData( - windows3, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation fifthWindow = SpriteAnimation.fromFrameData( - windows4, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation sixthWindow = SpriteAnimation.fromFrameData( - windows5, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - SpriteAnimation seventhWindow = SpriteAnimation.fromFrameData( - windows6, - SpriteAnimationData.sequenced( - amount: 1, - stepTime: 1, - textureSize: Vector2(2048, 683), - loop: false)); - - windowA = SpriteAnimationGroupComponent( - animations: { - WindowState.first: firstWindow, - WindowState.second: secondWindow, - WindowState.third: thirdWindow, - WindowState.fourth: fourthWindow, - WindowState.fifth: fifthWindow, - WindowState.sixth: sixthWindow, - WindowState.seventh: seventhWindow, - }, - current: WindowState.first, - ); - - windowB = SpriteAnimationGroupComponent( - animations: { - WindowState.first: firstWindow, - WindowState.second: secondWindow, - WindowState.third: thirdWindow, - WindowState.fourth: fourthWindow, - WindowState.fifth: fifthWindow, - WindowState.sixth: sixthWindow, - WindowState.seventh: seventhWindow, - }, - current: WindowState.first, - ); - - windowA.changePriorityWithoutResorting(WINDOW_PRIORITY); - - windowA.changePriorityWithoutResorting(WINDOW_PRIORITY); - - setUp(); - } - - void setUp() { - windowA.current = WindowState.first; - windowB.current = WindowState.first; - overlayA.current = OverlayState.first; - overlayB.current = OverlayState.first; - background1Position = Vector2(0, 0); - background1Size = Vector2( - gameRef.viewport.canvasSize.y * (background.width / background.height), - gameRef.viewport.canvasSize.y); - windowA.position = background1Position; - windowA.size = background1Size; - overlayA.position = background1Position; - overlayA.size = background1Size; - - background2Position = - Vector2(background1Position.x + background1Size.x - 1, 0); - background2Size = Vector2( - gameRef.viewport.canvasSize.y * (background.width / background.height), - gameRef.viewport.canvasSize.y); - windowB.position = background2Position; - windowB.size = background2Size; - overlayB.position = background2Position; - overlayB.size = background2Size; - } - - @override - void update(double dt) { - switch (gameRef.gameState.getScoreLevel()) { - case 12: - windowA.current = WindowState.seventh; - windowB.current = WindowState.seventh; - break; - case 11: - overlayA.current = OverlayState.seventh; - overlayB.current = OverlayState.seventh; - break; - case 10: - windowA.current = WindowState.sixth; - windowB.current = WindowState.sixth; - break; - case 9: - overlayA.current = OverlayState.sixth; - overlayB.current = OverlayState.sixth; - break; - case 8: - windowA.current = WindowState.fifth; - windowB.current = WindowState.fifth; - break; - case 7: - overlayA.current = OverlayState.fifth; - overlayB.current = OverlayState.fifth; - break; - case 6: - windowA.current = WindowState.fourth; - windowB.current = WindowState.fourth; - break; - case 5: - overlayA.current = OverlayState.fourth; - overlayB.current = OverlayState.fourth; - break; - case 4: - windowA.current = WindowState.third; - windowB.current = WindowState.third; - break; - case 3: - overlayA.current = OverlayState.third; - overlayB.current = OverlayState.third; - break; - case 2: - windowA.current = WindowState.second; - windowB.current = WindowState.second; - break; - case 1: - overlayA.current = OverlayState.second; - overlayB.current = OverlayState.second; - break; - default: - windowA.current = WindowState.first; - windowB.current = WindowState.first; - overlayA.current = OverlayState.first; - overlayB.current = OverlayState.first; - break; - } - windowA.update(dt); - windowB.update(dt); - overlayA.update(dt); - overlayB.update(dt); - if (background1Position.x + background1Size.x < 0) { - double newPosition = background2Position.x + background2Size.x; - background1Position = Vector2(newPosition - 1, 0); - } else if (background2Position.x + background2Size.x < 0) { - double newPosition = background1Position.x + background1Size.x; - background2Position = Vector2(newPosition - 1, 0); - } - - double velocity = gameRef.gameState.getVelocity() / 10.0; - background1Position = background1Position - Vector2(velocity * dt, 0); - windowA.position = background1Position; - overlayA.position = background1Position; - background2Position = background2Position - Vector2(velocity * dt, 0); - windowB.position = background2Position; - overlayB.position = background2Position; - } - - void render(Canvas canvas) { - background1.render(canvas, - size: background1Size, position: background1Position); - canvas.save(); - overlayA.render(canvas); - canvas.restore(); - canvas.save(); - windowA.render(canvas); - canvas.restore(); - background2.render(canvas, - size: background2Size, position: background2Position); - canvas.save(); - overlayB.render(canvas); - canvas.restore(); - canvas.save(); - windowB.render(canvas); - canvas.restore(); - } - - @override - void resize(Vector2 newSize, double xRatio, double yRatio) { - background1Size = - Vector2(newSize.y * (background.width / background.height), newSize.y); - windowA.position = background1Position; - windowA.size = background1Size; - overlayA.position = background1Position; - overlayA.size = background1Size; - - background2Position = - Vector2(background1Position.x + background1Size.x - 1, 0); - background2Size = - Vector2(newSize.y * (background.width / background.height), newSize.y); - windowB.position = background2Position; - windowB.size = background2Size; - overlayB.position = background2Position; - overlayB.size = background2Size; - } -} +import 'package:firo_runner/moving_object.dart'; +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; +import 'package:flame/flame.dart'; +import 'package:flame/extensions.dart'; + +enum WindowState { + first, + second, + third, + fourth, + fifth, + sixth, + seventh, +} + +enum OverlayState { + first, + second, + third, + fourth, + fifth, + sixth, + seventh, +} + +class CircuitBackground extends MovingObject { + late Image background; + + late Image overlay0; + late Image overlay1; + late Image overlay2; + late Image overlay3; + late Image overlay4; + late Image overlay5; + late Image overlay6; + + late Image windows0; + late Image windows1; + late Image windows2; + late Image windows3; + late Image windows4; + late Image windows5; + late Image windows6; + + late Sprite background1; + late Sprite background2; + late SpriteAnimationGroupComponent windowA; + late SpriteAnimationGroupComponent windowB; + late SpriteAnimationGroupComponent overlayA; + late SpriteAnimationGroupComponent overlayB; + Vector2 background1Size = Vector2(0, 0); + Vector2 background2Size = Vector2(0, 0); + Vector2 background1Position = Vector2(0, 0); + Vector2 background2Position = Vector2(0, 0); + + CircuitBackground(MyGame gameRef) : super(gameRef); + + Future load() async { + background = await Flame.images.load("bg.png"); + background1 = Sprite(background); + background2 = Sprite(background); + + overlay0 = await Flame.images.load("overlay100.png"); + overlay1 = await Flame.images.load("overlay90.png"); + overlay2 = await Flame.images.load("overlay80.png"); + overlay3 = await Flame.images.load("overlay70.png"); + overlay4 = await Flame.images.load("overlay60.png"); + overlay5 = await Flame.images.load("overlay50.png"); + overlay6 = await Flame.images.load("overlay40.png"); + + SpriteAnimation firstOverlay = SpriteAnimation.fromFrameData( + overlay0, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation secondOverlay = SpriteAnimation.fromFrameData( + overlay1, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation thirdOverlay = SpriteAnimation.fromFrameData( + overlay2, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation fourthOverlay = SpriteAnimation.fromFrameData( + overlay3, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation fifthOverlay = SpriteAnimation.fromFrameData( + overlay4, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation sixthOverlay = SpriteAnimation.fromFrameData( + overlay5, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation seventhOverlay = SpriteAnimation.fromFrameData( + overlay6, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + overlayA = SpriteAnimationGroupComponent( + animations: { + OverlayState.first: firstOverlay, + OverlayState.second: secondOverlay, + OverlayState.third: thirdOverlay, + OverlayState.fourth: fourthOverlay, + OverlayState.fifth: fifthOverlay, + OverlayState.sixth: sixthOverlay, + OverlayState.seventh: seventhOverlay, + }, + current: OverlayState.first, + ); + + overlayB = SpriteAnimationGroupComponent( + animations: { + OverlayState.first: firstOverlay, + OverlayState.second: secondOverlay, + OverlayState.third: thirdOverlay, + OverlayState.fourth: fourthOverlay, + OverlayState.fifth: fifthOverlay, + OverlayState.sixth: sixthOverlay, + OverlayState.seventh: seventhOverlay, + }, + current: OverlayState.first, + ); + + overlayA.changePriorityWithoutResorting(WINDOW_PRIORITY - 1); + + overlayA.changePriorityWithoutResorting(WINDOW_PRIORITY - 1); + + windows0 = await Flame.images.load("windows-0.png"); + windows1 = await Flame.images.load("windows-1.png"); + windows2 = await Flame.images.load("windows-2.png"); + windows3 = await Flame.images.load("windows-3.png"); + windows4 = await Flame.images.load("windows-4.png"); + windows5 = await Flame.images.load("windows-5.png"); + windows6 = await Flame.images.load("windows-6.png"); + + SpriteAnimation firstWindow = SpriteAnimation.fromFrameData( + windows0, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation secondWindow = SpriteAnimation.fromFrameData( + windows1, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation thirdWindow = SpriteAnimation.fromFrameData( + windows2, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation fourthWindow = SpriteAnimation.fromFrameData( + windows3, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation fifthWindow = SpriteAnimation.fromFrameData( + windows4, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation sixthWindow = SpriteAnimation.fromFrameData( + windows5, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + SpriteAnimation seventhWindow = SpriteAnimation.fromFrameData( + windows6, + SpriteAnimationData.sequenced( + amount: 1, + stepTime: 1, + textureSize: Vector2(2048, 683), + loop: false)); + + windowA = SpriteAnimationGroupComponent( + animations: { + WindowState.first: firstWindow, + WindowState.second: secondWindow, + WindowState.third: thirdWindow, + WindowState.fourth: fourthWindow, + WindowState.fifth: fifthWindow, + WindowState.sixth: sixthWindow, + WindowState.seventh: seventhWindow, + }, + current: WindowState.first, + ); + + windowB = SpriteAnimationGroupComponent( + animations: { + WindowState.first: firstWindow, + WindowState.second: secondWindow, + WindowState.third: thirdWindow, + WindowState.fourth: fourthWindow, + WindowState.fifth: fifthWindow, + WindowState.sixth: sixthWindow, + WindowState.seventh: seventhWindow, + }, + current: WindowState.first, + ); + + windowA.changePriorityWithoutResorting(WINDOW_PRIORITY); + + windowA.changePriorityWithoutResorting(WINDOW_PRIORITY); + + setUp(); + } + + void setUp() { + windowA.current = WindowState.first; + windowB.current = WindowState.first; + overlayA.current = OverlayState.first; + overlayB.current = OverlayState.first; + background1Position = Vector2(0, 0); + background1Size = Vector2( + gameRef.viewport.canvasSize.y * (background.width / background.height), + gameRef.viewport.canvasSize.y); + windowA.position = background1Position; + windowA.size = background1Size; + overlayA.position = background1Position; + overlayA.size = background1Size; + + background2Position = + Vector2(background1Position.x + background1Size.x - 1, 0); + background2Size = Vector2( + gameRef.viewport.canvasSize.y * (background.width / background.height), + gameRef.viewport.canvasSize.y); + windowB.position = background2Position; + windowB.size = background2Size; + overlayB.position = background2Position; + overlayB.size = background2Size; + } + + @override + void update(double dt) { + switch (gameRef.gameState.getScoreLevel()) { + case 12: + windowA.current = WindowState.seventh; + windowB.current = WindowState.seventh; + break; + case 11: + overlayA.current = OverlayState.seventh; + overlayB.current = OverlayState.seventh; + break; + case 10: + windowA.current = WindowState.sixth; + windowB.current = WindowState.sixth; + break; + case 9: + overlayA.current = OverlayState.sixth; + overlayB.current = OverlayState.sixth; + break; + case 8: + windowA.current = WindowState.fifth; + windowB.current = WindowState.fifth; + break; + case 7: + overlayA.current = OverlayState.fifth; + overlayB.current = OverlayState.fifth; + break; + case 6: + windowA.current = WindowState.fourth; + windowB.current = WindowState.fourth; + break; + case 5: + overlayA.current = OverlayState.fourth; + overlayB.current = OverlayState.fourth; + break; + case 4: + windowA.current = WindowState.third; + windowB.current = WindowState.third; + break; + case 3: + overlayA.current = OverlayState.third; + overlayB.current = OverlayState.third; + break; + case 2: + windowA.current = WindowState.second; + windowB.current = WindowState.second; + break; + case 1: + overlayA.current = OverlayState.second; + overlayB.current = OverlayState.second; + break; + default: + windowA.current = WindowState.first; + windowB.current = WindowState.first; + overlayA.current = OverlayState.first; + overlayB.current = OverlayState.first; + break; + } + windowA.update(dt); + windowB.update(dt); + overlayA.update(dt); + overlayB.update(dt); + if (background1Position.x + background1Size.x < 0) { + double newPosition = background2Position.x + background2Size.x; + background1Position = Vector2(newPosition - 1, 0); + } else if (background2Position.x + background2Size.x < 0) { + double newPosition = background1Position.x + background1Size.x; + background2Position = Vector2(newPosition - 1, 0); + } + + double velocity = gameRef.gameState.getVelocity() / 10.0; + background1Position = background1Position - Vector2(velocity * dt, 0); + windowA.position = background1Position; + overlayA.position = background1Position; + background2Position = background2Position - Vector2(velocity * dt, 0); + windowB.position = background2Position; + overlayB.position = background2Position; + } + + void render(Canvas canvas) { + background1.render(canvas, + size: background1Size, position: background1Position); + canvas.save(); + overlayA.render(canvas); + canvas.restore(); + canvas.save(); + windowA.render(canvas); + canvas.restore(); + background2.render(canvas, + size: background2Size, position: background2Position); + canvas.save(); + overlayB.render(canvas); + canvas.restore(); + canvas.save(); + windowB.render(canvas); + canvas.restore(); + } + + @override + void resize(Vector2 newSize, double xRatio, double yRatio) { + background1Position.x *= xRatio; + background1Position.y *= yRatio; + background1Size.x *= xRatio; + background1Size.y *= yRatio; + background2Position.x *= xRatio; + background2Position.y *= yRatio; + background2Size.x *= xRatio; + background2Size.y *= yRatio; + windowA.position = background1Position; + windowA.size = background1Size; + overlayA.position = background1Position; + overlayA.size = background1Size; + windowB.position = background2Position; + windowB.size = background2Size; + overlayB.position = background2Position; + overlayB.size = background2Size; + } +} diff --git a/lib/firework.dart b/lib/firework.dart index c9df46b..d71a7f2 100644 --- a/lib/firework.dart +++ b/lib/firework.dart @@ -1,131 +1,131 @@ -import 'dart:math'; - -import 'package:firo_runner/main.dart'; -import 'package:flame/components.dart'; -import 'package:flame/extensions.dart'; -import 'package:flame/flame.dart'; - -enum FireworkState { normal } - -class Firework extends Component { - MyGame gameRef; - late SpriteAnimationGroupComponent sprite1; - late SpriteAnimationGroupComponent sprite2; - Firework(this.gameRef); - double timeSinceFirework = 0; - late Random random; - String message = ""; - List messages = [ - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - "Speed Up!", - ]; - - Future load() async { - random = Random(); - Image firework = await Flame.images.load("fireworks-frames.png"); - - SpriteAnimation normal = SpriteAnimation.fromFrameData( - firework, - SpriteAnimationData.sequenced( - amount: 10, - stepTime: 0.25, - textureSize: Vector2(512, 512), - loop: false, - ), - ); - - sprite1 = SpriteAnimationGroupComponent( - animations: { - FireworkState.normal: normal, - }, - current: FireworkState.normal, - ); - - sprite1.changePriorityWithoutResorting(FIREWORK_PRIORITY); - sprite1.update(100); - - sprite1.size = - Vector2(gameRef.viewport.canvasSize.y, gameRef.viewport.canvasSize.y); - sprite1.position = Vector2(0, 0); - - sprite2 = SpriteAnimationGroupComponent( - animations: { - FireworkState.normal: normal, - }, - current: FireworkState.normal, - ); - - sprite2.changePriorityWithoutResorting(FIREWORK_PRIORITY); - - sprite2.size = - Vector2(gameRef.viewport.canvasSize.y, gameRef.viewport.canvasSize.y); - sprite2.position = - Vector2(gameRef.viewport.canvasSize.x - sprite2.size.x, 0); - sprite2.update(100); - } - - void setUp() { - message = ""; - timeSinceFirework = 0; - gameRef.add(sprite1); - gameRef.add(sprite2); - } - - @override - void update(double dt) { - if (!(sprite1.animation?.done() ?? false)) { - timeSinceFirework = 0; - } else { - timeSinceFirework += dt; - } - sprite1.update(dt); - sprite2.update(dt); - } - - void renderText(Canvas canvas) { - sprite1.render(canvas); - sprite1.render(canvas); - if ((sprite1.animation?.done() ?? false) && - timeSinceFirework < 1 && - message != "") { - gameRef.fireworksPaint.render( - canvas, - message, - Vector2( - gameRef.size.x / 2 - - gameRef.fireworksPaint.measureTextWidth(message) / 2, - gameRef.size.y / 9 - - gameRef.fireworksPaint.measureTextHeight(message) / 2), - ); - } - } - - void reset() { - message = messages.elementAt(random.nextInt(messages.length)); - sprite1.animation!.reset(); - sprite2.animation!.reset(); - } - - void resize(Vector2 newSize, double xRatio, double yRatio) { - sprite1.x *= xRatio; - sprite1.y *= yRatio; - sprite1.width *= xRatio; - sprite1.height *= yRatio; - - sprite2.x *= xRatio; - sprite2.y *= yRatio; - sprite2.width *= xRatio; - sprite2.height *= yRatio; - } -} +import 'dart:math'; + +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; +import 'package:flame/extensions.dart'; +import 'package:flame/flame.dart'; + +enum FireworkState { normal } + +class Firework extends Component { + MyGame gameRef; + late SpriteAnimationGroupComponent sprite1; + late SpriteAnimationGroupComponent sprite2; + Firework(this.gameRef); + double timeSinceFirework = 0; + late Random random; + String message = ""; + List messages = [ + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + "Speed Up!", + ]; + + Future load() async { + random = Random(); + Image firework = await Flame.images.load("fireworks-frames.png"); + + SpriteAnimation normal = SpriteAnimation.fromFrameData( + firework, + SpriteAnimationData.sequenced( + amount: 10, + stepTime: 0.25, + textureSize: Vector2(512, 512), + loop: false, + ), + ); + + sprite1 = SpriteAnimationGroupComponent( + animations: { + FireworkState.normal: normal, + }, + current: FireworkState.normal, + ); + + sprite1.changePriorityWithoutResorting(FIREWORK_PRIORITY); + sprite1.update(100); + + sprite1.size = + Vector2(gameRef.viewport.canvasSize.y, gameRef.viewport.canvasSize.y); + sprite1.position = Vector2(0, 0); + + sprite2 = SpriteAnimationGroupComponent( + animations: { + FireworkState.normal: normal, + }, + current: FireworkState.normal, + ); + + sprite2.changePriorityWithoutResorting(FIREWORK_PRIORITY); + + sprite2.size = + Vector2(gameRef.viewport.canvasSize.y, gameRef.viewport.canvasSize.y); + sprite2.position = + Vector2(gameRef.viewport.canvasSize.x - sprite2.size.x, 0); + sprite2.update(100); + } + + void setUp() { + message = ""; + timeSinceFirework = 0; + gameRef.add(sprite1); + gameRef.add(sprite2); + } + + @override + void update(double dt) { + if (!(sprite1.animation?.done() ?? false)) { + timeSinceFirework = 0; + } else { + timeSinceFirework += dt; + } + sprite1.update(dt); + sprite2.update(dt); + } + + void renderText(Canvas canvas) { + sprite1.render(canvas); + sprite1.render(canvas); + if ((sprite1.animation?.done() ?? false) && + timeSinceFirework < 1 && + message != "") { + gameRef.fireworksPaint.render( + canvas, + message, + Vector2( + gameRef.size.x / 2 - + gameRef.fireworksPaint.measureTextWidth(message) / 2, + gameRef.size.y / 9 - + gameRef.fireworksPaint.measureTextHeight(message) / 2), + ); + } + } + + void reset() { + message = messages.elementAt(random.nextInt(messages.length)); + sprite1.animation!.reset(); + sprite2.animation!.reset(); + } + + void resize(Vector2 newSize, double xRatio, double yRatio) { + sprite1.x *= xRatio; + sprite1.y *= yRatio; + sprite1.width *= xRatio; + sprite1.height *= yRatio; + + sprite2.x *= xRatio; + sprite2.y *= yRatio; + sprite2.width *= xRatio; + sprite2.height *= yRatio; + } +} diff --git a/lib/game_state.dart b/lib/game_state.dart index 46f77cd..26ff86f 100644 --- a/lib/game_state.dart +++ b/lib/game_state.dart @@ -1,124 +1,124 @@ -import 'package:firo_runner/main.dart'; -import 'package:flame/components.dart'; - -class GameState extends Component { - int start = 0; - bool isPaused = false; - int numCoins = 0; - int distance = 0; - late MyGame gameRef; - int previousLevel = 1; - - @override - void update(double dt) { - super.update(dt); - if (!isPaused) { - distance = DateTime.now().microsecondsSinceEpoch - start; - if (previousLevel != getLevel()) { - previousLevel = getLevel(); - gameRef.fireworks.reset(); - } - } - } - - void addCoin() { - numCoins++; - } - - void setUp(MyGame gameRef) { - this.gameRef = gameRef; - numCoins = 0; - distance = 0; - previousLevel = 1; - start = DateTime.now().microsecondsSinceEpoch; - isPaused = false; - } - - void setPaused() { - isPaused = true; - } - - int getLevel() { - if (distance > LEVEL7) { - return 7; - } else if (distance > LEVEL6) { - return 6; - } else if (distance > LEVEL5) { - return 5; - } else if (distance > LEVEL4) { - return 4; - } else if (distance > LEVEL3) { - return 3; - } else if (distance > LEVEL2) { - return 2; - } else { - return 1; - } - } - - int getScoreLevel() { - int score = getScore(); - if (score > LEVEL7) { - return 12; - } else if (score > LEVEL6 + LEVEL6 / 2) { - return 11; - } else if (score > LEVEL6) { - return 10; - } else if (score > LEVEL5 + LEVEL5 / 2) { - return 9; - } else if (score > LEVEL5) { - return 8; - } else if (score > LEVEL4 + LEVEL4 / 2) { - return 7; - } else if (score > LEVEL4) { - return 6; - } else if (score > LEVEL3 + LEVEL3 / 2) { - return 5; - } else if (score > LEVEL3) { - return 4; - } else if (score > LEVEL2 + LEVEL2 / 2) { - return 3; - } else if (score > LEVEL2) { - return 2; - } else if (score > LEVEL2 - LEVEL2 / 2) { - return 1; - } else { - return 0; - } - } - - int getScore() { - return distance ~/ 10 + numCoins * 1000000; - } - - int getPlayerScore() { - return getScore() ~/ 10000; - } - - int getPlayerDistance() { - return distance ~/ 1000000; - } - - double getVelocity() { - if (!isPaused) { - switch (getLevel()) { - case 7: - return gameRef.viewport.canvasSize.x * 0.25; - case 6: - return gameRef.viewport.canvasSize.x * 0.20; - case 5: - return gameRef.viewport.canvasSize.x * 0.18; - case 4: - return gameRef.viewport.canvasSize.x * 0.16; - case 3: - return gameRef.viewport.canvasSize.x * 0.14; - case 2: - return gameRef.viewport.canvasSize.x * 0.12; - default: - return gameRef.viewport.canvasSize.x * 0.1; - } - } else { - return 0; - } - } -} +import 'package:firo_runner/main.dart'; +import 'package:flame/components.dart'; + +class GameState extends Component { + int start = 0; + bool isPaused = false; + int numCoins = 0; + int distance = 0; + late MyGame gameRef; + int previousLevel = 1; + + @override + void update(double dt) { + super.update(dt); + if (!isPaused) { + distance = DateTime.now().microsecondsSinceEpoch - start; + if (previousLevel != getLevel()) { + previousLevel = getLevel(); + gameRef.fireworks.reset(); + } + } + } + + void addCoin() { + numCoins++; + } + + void setUp(MyGame gameRef) { + this.gameRef = gameRef; + numCoins = 0; + distance = 0; + previousLevel = 1; + start = DateTime.now().microsecondsSinceEpoch; + isPaused = false; + } + + void setPaused() { + isPaused = true; + } + + int getLevel() { + if (distance > LEVEL7) { + return 7; + } else if (distance > LEVEL6) { + return 6; + } else if (distance > LEVEL5) { + return 5; + } else if (distance > LEVEL4) { + return 4; + } else if (distance > LEVEL3) { + return 3; + } else if (distance > LEVEL2) { + return 2; + } else { + return 1; + } + } + + int getScoreLevel() { + int score = getScore(); + if (score > LEVEL7) { + return 12; + } else if (score > LEVEL6 + LEVEL6 / 2) { + return 11; + } else if (score > LEVEL6) { + return 10; + } else if (score > LEVEL5 + LEVEL5 / 2) { + return 9; + } else if (score > LEVEL5) { + return 8; + } else if (score > LEVEL4 + LEVEL4 / 2) { + return 7; + } else if (score > LEVEL4) { + return 6; + } else if (score > LEVEL3 + LEVEL3 / 2) { + return 5; + } else if (score > LEVEL3) { + return 4; + } else if (score > LEVEL2 + LEVEL2 / 2) { + return 3; + } else if (score > LEVEL2) { + return 2; + } else if (score > LEVEL2 - LEVEL2 / 2) { + return 1; + } else { + return 0; + } + } + + int getScore() { + return distance ~/ 10 + numCoins * 1000000; + } + + int getPlayerScore() { + return getScore() ~/ 10000; + } + + int getPlayerDistance() { + return distance ~/ 1000000; + } + + double getVelocity() { + if (!isPaused) { + switch (getLevel()) { + case 7: + return gameRef.viewport.canvasSize.x * 0.25; + case 6: + return gameRef.viewport.canvasSize.x * 0.20; + case 5: + return gameRef.viewport.canvasSize.x * 0.18; + case 4: + return gameRef.viewport.canvasSize.x * 0.16; + case 3: + return gameRef.viewport.canvasSize.x * 0.14; + case 2: + return gameRef.viewport.canvasSize.x * 0.12; + default: + return gameRef.viewport.canvasSize.x * 0.1; + } + } else { + return 0; + } + } +} diff --git a/lib/lose_menu_overlay.dart b/lib/lose_menu_overlay.dart index e8120ea..0f14c8c 100644 --- a/lib/lose_menu_overlay.dart +++ b/lib/lose_menu_overlay.dart @@ -1,88 +1,94 @@ -import 'package:flutter/material.dart'; - -import 'main.dart'; - -class LoseMenuOverlay extends StatelessWidget { - const LoseMenuOverlay({ - Key? key, - required this.game, - }) : super(key: key); - - final MyGame game; - - @override - Widget build(BuildContext context) { - 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'), - fit: BoxFit.fill, - ), - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Score: ' + game.gameState.getPlayerScore().toString(), - style: overlayText, - ), - const SizedBox(height: 32.0), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MaterialButton( - padding: const EdgeInsets.all(8.0), - textColor: Colors.white, - splashColor: Colors.greenAccent, - elevation: 8.0, - child: Container( - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/images/button.png'), - fit: BoxFit.fill), - ), - child: const Padding( - padding: EdgeInsets.all(8.0), - child: Text("Main Menu"), - ), - ), - // ), - onPressed: () { - // Go to the Main Menu - }, - ), - const SizedBox( - width: 32.0, - ), - MaterialButton( - padding: const EdgeInsets.all(8.0), - textColor: Colors.white, - splashColor: Colors.greenAccent, - elevation: 8.0, - child: Container( - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/images/button.png'), - fit: BoxFit.fill), - ), - child: const Padding( - padding: EdgeInsets.all(8.0), - child: Text("Replay"), - ), - ), - // ), - onPressed: () { - game.reset(); - }, - ), - ], - ), - ], - ), - ), - ); - } -} +import 'package:flutter/material.dart'; + +import 'main.dart'; + +class LoseMenuOverlay extends StatelessWidget { + const LoseMenuOverlay({ + Key? key, + required this.game, + }) : super(key: key); + + final MyGame game; + + @override + Widget build(BuildContext context) { + 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'), + fit: BoxFit.fill, + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Score: ' + game.gameState.getPlayerScore().toString(), + style: overlayText, + ), + const SizedBox(height: 32.0), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MaterialButton( + padding: const EdgeInsets.all(8.0), + textColor: Colors.white, + splashColor: Colors.greenAccent, + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/button.png'), + fit: BoxFit.fill), + ), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Text( + " Main Menu ", + style: overlayText, + ), + ), + ), + // ), + onPressed: () { + // Go to the Main Menu + }, + ), + const SizedBox( + width: 32.0, + ), + MaterialButton( + padding: const EdgeInsets.all(8.0), + textColor: Colors.white, + splashColor: Colors.greenAccent, + elevation: 8.0, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/button.png'), + fit: BoxFit.fill), + ), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Text( + " Replay ", + style: overlayText, + ), + ), + ), + // ), + onPressed: () { + game.reset(); + }, + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/platform.dart b/lib/platform.dart index 85d06f7..23d38b1 100644 --- a/lib/platform.dart +++ b/lib/platform.dart @@ -64,7 +64,7 @@ class Platform extends MovingObject { PlatformState.right: right, PlatformState.single: single, }, - current: PlatformState.single, + current: PlatformState.mid, ); sprite.changePriorityWithoutResorting(PLATFORM_PRIORITY); @@ -112,14 +112,19 @@ class Platform extends MovingObject { bool hasLeft = (left.x - sprite.position.x).abs() < 1.9 * sprite.size.x; bool hasRight = (sprite.position.x - right.x).abs() < 1.9 * sprite.size.x; - if (hasLeft && hasRight) { - sprite.current = PlatformState.mid; - } else if (hasLeft && !hasRight) { - sprite.current = PlatformState.right; - } else if (!hasLeft && hasRight) { - sprite.current = PlatformState.left; - } else { - sprite.current = PlatformState.single; + // If the platform cannot be seen by the player. + if (!((sprite.x >= 0 && sprite.x <= gameRef.size.x) || + (sprite.x + sprite.width >= 0 && + sprite.x + sprite.width <= gameRef.size.x))) { + if (hasLeft && hasRight) { + sprite.current = PlatformState.mid; + } else if (hasLeft && !hasRight) { + sprite.current = PlatformState.right; + } else if (!hasLeft && hasRight) { + sprite.current = PlatformState.left; + } else { + sprite.current = PlatformState.single; + } } } } diff --git a/lib/platform_holder.dart b/lib/platform_holder.dart index 65ee336..fab5fd2 100644 --- a/lib/platform_holder.dart +++ b/lib/platform_holder.dart @@ -14,6 +14,8 @@ class PlatformHolder extends Holder { late Image r2; late Image o1; late Image o2; + bool noTopObstaclesForNext = false; + bool noMiddleObstaclesForNext = false; int timeSinceLastTopHole = 0; int timeSinceLastBottomHole = 0; @@ -91,6 +93,7 @@ class PlatformHolder extends Holder { remove(objects[2], objects[2].length - 2); timeSinceLastTopHole = 0; + noTopObstaclesForNext = true; } if (bottomChance > 30) { Platform start = objects[5].elementAt(objects[5].length - 10) as Platform; @@ -112,6 +115,7 @@ class PlatformHolder extends Holder { remove(objects[5], firstToRemove); timeSinceLastBottomHole = 0; + noMiddleObstaclesForNext = true; } } @@ -129,6 +133,13 @@ class PlatformHolder extends Holder { platform.row = level; gameRef.add(platform.sprite); objects[level].add(platform); + if (level == 2 && noTopObstaclesForNext) { + platform.prohibitObstacles = true; + noTopObstaclesForNext = false; + } else if (level == 5 && noMiddleObstaclesForNext) { + platform.prohibitObstacles = true; + noMiddleObstaclesForNext = false; + } return false; } } diff --git a/lib/runner.dart b/lib/runner.dart index 8baf000..ed81056 100644 --- a/lib/runner.dart +++ b/lib/runner.dart @@ -4,8 +4,8 @@ import 'package:firo_runner/moving_object.dart'; import 'package:firo_runner/main.dart'; import 'package:flame/effects.dart'; import 'package:flame/flame.dart'; -// import 'package:flutter/material.dart'; import 'dart:math'; + import 'package:flame/components.dart'; import 'package:flame/image_composition.dart'; import 'package:flutter/animation.dart'; @@ -78,9 +78,9 @@ class Runner extends Component with HasGameRef { if (gameRef.gameState.isPaused) { return; } - previousState = runnerState; switch (event) { case "jump": + previousState = runnerState; runnerState = event; sprite.current = RunnerState.jump; sprite.addEffect(MoveEffect( @@ -100,6 +100,7 @@ class Runner extends Component with HasGameRef { if (belowPlatform()) { break; } + previousState = runnerState; sprite.clearEffects(); if (level - 1 < 0) { break; @@ -123,20 +124,24 @@ class Runner extends Component with HasGameRef { )); break; case "fall": + previousState = runnerState; sprite.clearEffects(); runnerState = event; sprite.current = RunnerState.fall; sprite.addEffect(getFallingEffect()); break; case "kick": + previousState = runnerState; runnerState = event; sprite.current = RunnerState.kick; break; case "run": + previousState = runnerState; runnerState = event; sprite.current = RunnerState.run; break; case "float": + previousState = runnerState; runnerState = event; sprite.current = RunnerState.float; sprite.addEffect(MoveEffect( @@ -154,6 +159,7 @@ class Runner extends Component with HasGameRef { )); break; case "duck": + previousState = runnerState; runnerState = event; sprite.current = RunnerState.duck; sprite.addEffect(MoveEffect( @@ -169,6 +175,7 @@ class Runner extends Component with HasGameRef { if (dead) { return; } + previousState = runnerState; sprite.clearEffects(); level = 11; sprite.addEffect(MoveEffect( @@ -185,6 +192,7 @@ class Runner extends Component with HasGameRef { if (dead) { return; } + previousState = runnerState; sprite.clearEffects(); level = 11; sprite.addEffect(MoveEffect( @@ -201,6 +209,7 @@ class Runner extends Component with HasGameRef { if (dead) { return; } + previousState = runnerState; sprite.clearEffects(); level = 11; sprite.addEffect(MoveEffect( @@ -330,6 +339,14 @@ class Runner extends Component with HasGameRef { sprite.current = RunnerState.run; } + if (runnerState == "float" || runnerState == "double_jump") { + if (onTopOfPlatform()) { + updateLevel(); + sprite.clearEffects(); + event("run"); + } + } + intersecting(); sprite.update(dt); } @@ -353,7 +370,11 @@ class Runner extends Component with HasGameRef { } bool belowPlatform() { - Rect runnerRect = sprite.toRect(); + 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 platformLevel in gameRef.platformHolder.objects) { for (MovingObject p in platformLevel) { @@ -443,14 +464,14 @@ class Runner extends Component with HasGameRef { } } - for (List debrisLevel in gameRef.wallHolder.objects) { - for (int i = 0; i < debrisLevel.length; i++) { + for (List 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 = debrisLevel[i].intersect(slim); + String intersectState = wallLevel[i].intersect(slim); if (intersectState == "none") { continue; } else { diff --git a/lib/wall.dart b/lib/wall.dart index 6b7e9e8..327d3fa 100644 --- a/lib/wall.dart +++ b/lib/wall.dart @@ -31,7 +31,7 @@ class Wall extends MovingObject { gameRef.blockSize * (gameRef.wallHolder.wall.width / gameRef.wallHolder.wall.height / 5) * 2.0, - gameRef.blockSize * 0.5, + gameRef.blockSize * 0.35, ); }