flutterdartgame-developmentflame

Flutter Flame Game: Character Stays in 'up' Position After Restarting Game


I am developing a game using Flutter and Flame. In my game, the character has two states: middle and up. The character moves to the up state when the user initiates a jump and returns to the middle state after a delay.

The problem I am facing is that when the game ends due to a collision while the character is in the up state, and I restart the game, the character continues from the up state instead of resetting to the middle state.

Here is my code:

import 'dart:async';
import 'package:flame/collisions.dart';
import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame_audio/flame_audio.dart';
import 'package:flutter/cupertino.dart';
import 'package:rungame/game/assets.dart';
import 'package:rungame/game/configuration.dart';
import 'package:rungame/game/skateboardera_girl.dart';
import 'package:rungame/game/skater_girl_movement.dart';

class SkaterGirl extends SpriteGroupComponent<SkaterGirlMovement>
    with HasGameRef<skateboarderGirl>, CollisionCallbacks {
  SkaterGirl();
  int score = 0;

  @override
  Future<void> onLoad() async {
    final skaterGirlCharacter = await gameRef.loadSprite(Assets.skatergirl);
    final skaterGirlCharacterUp = await gameRef.loadSprite(Assets.skatergirlUp);
    FlameAudio.audioCache
        .loadAll([Assets.flying, Assets.collision, Assets.point]);

    size = Vector2(120, 120);
    double bottomPadding = 190;
    position = Vector2(120, gameRef.size.y - size.y - bottomPadding);

    current = SkaterGirlMovement.middle;
    sprites = {
      SkaterGirlMovement.middle: skaterGirlCharacter,
      SkaterGirlMovement.up: skaterGirlCharacterUp,
    };

    add(RectangleHitbox());
  }

  void fly() {
    if (current != SkaterGirlMovement.up && !gameRef.isHit) {
      try {
        FlameAudio.play(Assets.flying);
        debugPrint('çaldı canım');
      } catch (e) {
        debugPrint('Error playing audio: $e');
      }
      add(
        MoveByEffect(
          Vector2(0, Config.gravity),
          EffectController(duration: 0.5, curve: Curves.decelerate),
          onComplete: () {
            if (current != SkaterGirlMovement.up && !gameRef.isHit) {
              current = SkaterGirlMovement.up;
              debugPrint('if up tan sonra ki ');
              Future.delayed(Duration(milliseconds: 1500), () {
                if (!gameRef.isHit) {
                  debugPrint("if game is hit -->  ${game.isHit}");
                  resetPosition();
                  current = SkaterGirlMovement.middle;
                  gameRef.skatergirl.score++;
                  try {
                    FlameAudio.play(Assets.point);
                    debugPrint('çaldı point');
                  } catch (e) {
                    debugPrint('Error playing audio: $e');
                  }
                  debugPrint("Score fly file: ${gameRef.skatergirl.score}");
                } else {
                  resetPosition();
                  return;
                }
              });
            }
          },
        ),
      );
    } else {
      debugPrint('Collision detected while flying, exiting fly function');
      current = SkaterGirlMovement.middle;
      return;
    }
  }

  void resetPosition() {
    debugPrint('reset position ');
    size = Vector2(120, 120);
    double bottomPadding = 190;
    position = Vector2(
      120,
      gameRef.size.y - size.y - bottomPadding,
    );
    current = SkaterGirlMovement.middle; // Orta pozisyon olarak ayarla
  }

  @override
  void onCollisionStart(
    Set<Vector2> intersectionPoints,
    PositionComponent other,
  ) {
    super.onCollisionStart(intersectionPoints, other);
    debugPrint('Collision detected ');

    gameOver();
  }

  void gameOver() {
    try {
      FlameAudio.play(Assets.collision);
      debugPrint('çaldı game over');
    } catch (e) {
      debugPrint('Error playing audio: $e');
    }

    gameRef.overlays.add('gameOver');
    gameRef.pauseEngine();
    game.isHit = true;
    resetPosition(); // Oyun bittiğinde karakteri orta pozisyona sıfırla

    debugPrint("game is hit -->  ${game.isHit}");
  }

  void reset() {
    gameRef.flowerGroup.resetFlowers();
    current = SkaterGirlMovement.middle;
    score = 0;
  }
}

I've tried to ensure that the character's position and state are reset to middle in both resetPosition() and reset(), but the issue persists. How can I ensure that the character always starts in the middle state when the game restarts?

Any help would be greatly appreciated. Thanks!


Solution

  • When you restart your game, completely recreate the player component instead of re-using the player component that you used for the last run. This will also remedy a bunch of possible future bugs if the player will keep some state.