如何在Flutter Flame中正确重置游戏?

问题描述 投票:0回答:1

我想重置游戏,用下面的方法重置,可以,但是有两个问题。首先,当我在

Future.delayed(Duration(seconds: 1)).then((value) {//}
方法中使用
startGame()
时,重置工作正常!但是当我调用
startGame2()
时它不起作用并且 UI 停止工作。为什么?

第二个问题是:使用运行良好的

startGame()
方法重置后,之前生成的敌人,我在这个
removeAllEnemies()
方法中循环地将它们从父级中删除,所有这些敌人都出现在与之前相同的位置重置!我尝试使用以下方法处理图像:

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

但它也会导致以下错误:

======== 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();
      // }
    }
  }
flutter dart flame
1个回答
1
投票

“删除”组件仅将它们从火焰组件树中的父组件中删除。它们在被“删除”后不会更新或渲染,但它们仍然存在于应用程序中。 它们是完全相同的对象,一旦添加回组件树,就会再次变得活跃、更新和渲染。

您可以考虑输入重置代码,例如位置等,在 onMount 函数中,当它被添加回树时将被调用。

© www.soinside.com 2019 - 2024. All rights reserved.