You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RouterComponent使用与状态共享问题咨询(含SDK兼容疑问)

}

### MainGame类(初始写法)
```dart
class MainGame extends Forge2DGame {
...
  Character character; // 原本想在此创建实例,供后续其他类获取其值
  @override
  Future<void> onLoad() async {
    add(
      router = RouterComponent(
        initialRoute: 'character',
        routes: {
          'character': Route(character), // 疑问点
        },
      ),
    );
 }
}

尝试获取角色状态的Scene类写法

class Scene extends Component with HasGameRef<MainGame> {
  ...
  bool characterMovement = gameRef.character.isMoving; 
}

核心问题

  1. 若按照教程写法使用Route(Character.new),是否每次都会创建新实例,导致Scene类无法获取已实例化character的状态?该如何实现我的需求?
  2. 遇到错误提示:This requires the 'constructor-tearoffs' language feature to be enabled. Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15.0 or higher, and running 'pub get'. 由于使用的SDK版本为">=2.11.0 <3.0.0"(暂不想启用空安全),是否仍可使用RouterComponent?

更新内容

询问是否可以按以下方式使用RouterComponent来共享同一个character实例的状态:

class MainGame extends Forge2DGame {
...
  Character character;
  @override
  Future<void> onLoad() async {
    add(
      router = RouterComponent(
        initialRoute: 'character',
        routes: {
          'character': Route( () => character), 
        },
      ),
    );
 }
}

解答

问题1解答

是的,使用Route(Character.new)每次导航到该路由时都会创建新的Character实例,Scene类无法获取到之前实例的状态。

要实现共享同一实例的需求,你需要提前在MainGame中完成Character的初始化,再让路由返回这个已存在的实例,就像你更新的写法那样,但必须先初始化实例:

class MainGame extends Forge2DGame {
...
  Character character;
  @override
  Future<void> onLoad() async {
    // 先初始化character实例
    character = Character();
    add(
      router = RouterComponent(
        initialRoute: 'character',
        routes: {
          'character': Route(() => character), 
        },
      ),
    );
 }
}

这样每次切换到'character'路由时,都会返回同一个实例,Scene类就能通过gameRef.character.isMoving拿到正确的状态。

另外,你之前在Scene类中直接初始化characterMovement的写法存在风险:类成员变量初始化阶段,gameRef.character可能还未完成初始化,会触发空指针异常。建议在组件的生命周期方法中同步状态:

class Scene extends Component with HasGameRef<MainGame> {
  bool characterMovement = false;

  @override
  void update(double dt) {
    super.update(dt);
    // 每次更新时同步角色最新的移动状态
    characterMovement = gameRef.character.isMoving;
  }
}

问题2解答

可以正常使用RouterComponent。Character.new是构造函数分离语法,该特性在SDK 2.15.0才被引入,你的SDK版本不支持这个语法,所以会报错。

替代方案是使用匿名函数来返回实例:

  • 若需要每次创建新实例,改用Route(() => Character()),替代Route(Character.new)
  • 若需要复用已有的实例,就用你更新内容里的Route(() => character)(务必先初始化character)

这种写法不需要升级SDK或启用空安全,就能正常使用RouterComponent。

更新内容的写法验证

你更新的写法是可行的,但必须先完成character的初始化,否则会返回null导致报错。只要在创建RouterComponent之前执行character = Character();,就能保证路由返回同一个实例,所有类都能共享它的状态。


内容的提问来源于stack exchange,提问作者matti peterbull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:41:44