Flutter Flame游戏重启后角色仍处于'up'状态的问题解决
问题:Flame游戏重启后角色状态未重置为middle
我使用Flutter和Flame开发一款游戏,游戏角色拥有middle和up两种状态:用户触发跳跃时角色切换至up状态,延迟后自动恢复为middle状态。
当前遇到的问题是:当角色处于up状态时发生碰撞导致游戏结束,重启游戏后角色仍停留在up状态,而非重置为middle状态。我已尝试在resetPosition()和reset()方法中重置角色位置与状态为middle,但问题仍未解决。
代码片段
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; Timer? _delayTimer; // 新增:保存延迟任务引用 @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为Timer,方便取消 _delayTimer?.cancel(); _delayTimer = Timer(Duration(milliseconds: 1500), () { if (!gameRef.isHit) { debugPrint("if game is hit --> ${game.isHit}"); resetPosition(); current = SkaterGirlMovement.middle; markNeedsPaint(); 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; markNeedsPaint(); 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; markNeedsPaint(); } @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'); } // 清理所有未完成的异步任务和Effect removeAllEffects(); _delayTimer?.cancel(); gameRef.overlays.add('gameOver'); gameRef.pauseEngine(); game.isHit = true; resetPosition(); debugPrint("game is hit --> ${game.isHit}"); } void reset() { gameRef.flowerGroup.resetFlowers(); current = SkaterGirlMovement.middle; markNeedsPaint(); score = 0; // 重置碰撞状态,避免后续逻辑异常 game.isHit = false; resetPosition(); } }
解决方案
1. 清理未完成的异步任务与Effect
碰撞触发游戏结束时,角色的MoveByEffect或延迟任务可能仍在后台运行,会覆盖你重置的状态:
- 新增
Timer? _delayTimer变量保存跳跃后的延迟任务引用,方便取消 - 在
gameOver方法中调用removeAllEffects()移除所有未完成的动画效果,同时调用_delayTimer?.cancel()取消延迟任务
2. 强制刷新UI状态
SpriteGroupComponent的状态更新可能不会自动触发UI刷新,在所有重置current状态的地方添加markNeedsPaint(),强制组件重新绘制。
3. 完善重置逻辑
在reset方法中补充重置game.isHit状态,避免后续逻辑因碰撞状态未清除而异常,同时再次调用resetPosition()确保位置和状态正确。
4. 确保重启时正确调用重置方法
检查游戏重启按钮的回调逻辑,确保明确调用SkaterGirl的reset()方法,同时重置游戏引擎状态:
// 示例重启按钮回调 void onRestartButtonPressed() { gameRef.skatergirl.reset(); gameRef.resumeEngine(); gameRef.overlays.remove('gameOver'); }
内容的提问来源于stack exchange,提问作者senanurr
相关产品推荐
相关产品推荐

