4

I want to reset the game and use bellow methods for resetting, it works, but there is two problem. First is, when I use Future.delayed(Duration(seconds: 1)).then((value) {//} in startGame() method, resetting works correctly! but when I call startGame2() it dosn't work and UI stops working. Why?

2nd question is: After resetting with startGame() method which is working fine a bit, previously generated enemies that I removed them from parent in a loop in this removeAllEnemies() method, all of them appears in the same position that they were before the resetting! I tried to dispose images using:

 for (var element in enemy.animation!.frames) {
         element.sprite.image.dispose();
     }

but it also causing bellow error:

======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
'dart:ui/painting.dart': Failed assertion: line 1683 pos 12: '<optimized out>': is not true.

When the exception was thrown, this was the stack:
#2      Image.dispose (dart:ui/painting.dart:1683:12)
#3      EnemyManager.removeAllEnemies (package:turtleGame/game/enemy_manager.dart:68:30)
#4      TurtleGame.reset (package:turtleGame/game/turtle_game.dart:67:18)
#5      PauseOverlay.build.<anonymous closure> (package:turtleGame/widgets/pause-overlay.dart:54:44)
#6      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)
#7      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:198:24)
#8      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:608:11)
#9      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:296:5)
#10     BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:230:7)
#11     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:563:9)
#12     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:94:12)
#13     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:139:9)
#14     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:539:8)
#15     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:137:18)
#16     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:123:7)
#17     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:439:19)
#18     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:419:22)
#19     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:322:11)
#20     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:374:7)
#21     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:338:5)
#22     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:296:7)
#23     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:279:7)
#27     _invoke1 (dart:ui/hooks.dart:170:10)
#28     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:331:7)
#29     _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
(elided 5 frames from class _AssertionError and dart:async)
Handler: "onTap"
Recognizer: TapGestureRecognizer#8e6e3
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(306.3, 193.7)
finalLocalPosition: Offset(25.3, 17.2)
button: 1
sent tap down
====================================================================================================

PauseOverlay.dart

              ElevatedButton(
                    onPressed: () {
                      gameRefModel.resumeGameEngine();

                      gameRefModel.gameRef.overlays.remove(PauseOverlay.id);
                      gameRefModel.gameRef.reset();
                      gameRefModel.gameRef.startGame();
                    },
                    child: Text('Restart'),
                  ),

TurtleGame.dart

     void reset() {
        overlays.remove(ScoreOverlay.id);
        girlSprites.removeFromParent();
        enemyManager.removeAllEnemies();
        enemyManager.removeFromParent();
      }
void startGame() {
    Future.delayed(Duration(seconds: 1)).then((value) {                //<=======
      GameModel.instance.playerState = PlayerStateEnum.alive;
      GameModel.instance.gameState = GameStateEnum.resume;

      overlays.add(ScoreOverlay.id);
      add(girlSprites..size = Vector2(40, 50));
      add(enemyManager);
      scoreModel.score = 0;
      scoreModel.lives = 5;
    });                                                                 //<=======
  }

void startGame2() async{                                               // Added async
    // Future.delayed(Duration(seconds: 1)).then((value) {                 
      GameModel.instance.playerState = PlayerStateEnum.alive;
      GameModel.instance.gameState = GameStateEnum.resume;

      overlays.add(ScoreOverlay.id);
      await add(girlSprites..size = Vector2(40, 50));                  // added await
      await add(enemyManager);                                         // added await
      scoreModel.score = 0;                      
      scoreModel.lives = 5;
    // });
  }

EnemyManager.dart

 void removeAllEnemies() {
    final enemies = children.whereType<Enemy>();
    for (var enemy in enemies) {
      enemy.removeFromParent();
      // for (var element in enemy.animation!.frames) {
      //   element.sprite.image.dispose();
      // }
    }
  }
Davoud
  • 2,576
  • 1
  • 32
  • 53

1 Answers1

1

"Remove" components only remove them from its parent in the flame component tree. They do not update nor render after being "removed" but they still live in the app. They, being the very same objects, become active, updated and rendered, again as soon as added back to the component tree.

You may consider putting the resetting code, e.g. position etc, in the onMount function, which will be called when it is added back to the tree.

Ken Lee
  • 23
  • 5