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

Flame游戏中Joystick与HudButtonComponent被场景遮挡,优先级无效

Flame游戏HUD控件被场景遮挡问题解决

我在Flame游戏中给Joystick及其他HudButtonComponent设置了最高优先级,但加载游戏场景后,这些控件始终被场景遮挡。已确保在场景加载完成后添加控件,问题仍未解决。

核心代码片段

game.dart(继承FlameGame)

late JoystickComponent joystick;
late HudButtonComponent jumpButton;
late HudButtonComponent attackButton;

@override
FutureOr<void> onLoad() async {
  health = maxHealth;
  if (!_isAlreadyLoaded) {
    await images.loadAllImages();

    _loadFloor();

    if (showControls) {
      addJoystick();
      addJumpButton();
      addAttackButton();
    }
    _isAlreadyLoaded = true;
  }

  return super.onLoad();
}

添加Joystick的代码(其他HUD按钮逻辑一致)

void addJoystick() {
  joystick = JoystickComponent(
    priority: 10,
    knob: SpriteComponent(
      sprite: Sprite(
        images.fromCache('HUD/Knob.png'),
      ),
    ),
    knobRadius: 64,
    background: SpriteComponent(
      sprite: Sprite(
        images.fromCache('HUD/Joystick.png'),
      ),
    ),
    margin: const EdgeInsets.only(left: 128, bottom: 32),
  );

  add(joystick);
}

加载Floor的代码

void _loadFloor() {
  Future.delayed(
    const Duration(milliseconds: 1000),
    () {
      Floor world = Floor(
        player: player,
        floorName: floorNames[currentFloorIndex],
      );

      cam = CameraComponent.withFixedResolution(
        world: world,
        width: 640,
        height: 340,
      );
      cam.viewfinder.anchor = Anchor.topLeft;

      addAll([cam, world]);
    },
  );
}

问题原因与解决方法

问题根源

  • 延迟加载导致层级覆盖:_loadFloor用Future.delayed延迟1秒添加cam和world,这两个组件会在HUD控件之后被添加到游戏中。即使HUD设了priority:10,后添加的组件渲染层级更高,直接把HUD挡住了。
  • CameraComponent渲染逻辑限制:CameraComponent负责渲染整个游戏世界,直接添加到根节点的HUD会和它的渲染层级竞争,优先级设置不一定能覆盖这种层级关系。

靠谱的解决方式

把HUD控件放到CameraComponent的overlay里,这个层级是专门用来显示HUD的,会始终在游戏世界上方渲染,完全不用依赖优先级:

  • 修改HUD的添加逻辑,把控件加到cam.overlay:
void addJoystick() {
  joystick = JoystickComponent(
    knob: SpriteComponent(
      sprite: Sprite(
        images.fromCache('HUD/Knob.png'),
      ),
    ),
    knobRadius: 64,
    background: SpriteComponent(
      sprite: Sprite(
        images.fromCache('HUD/Joystick.png'),
      ),
    ),
    margin: const EdgeInsets.only(left: 128, bottom: 32),
  );

  // 把HUD加到相机的overlay层
  cam.overlay.add(joystick);
}
  • 调整HUD的添加时机,确保cam已经初始化完成:
    因为_loadFloor是延迟执行的,原来在onLoad里直接加HUD的时候cam还没创建,所以要把HUD的添加逻辑移到_loadFloor的回调里:
void _loadFloor() {
  Future.delayed(
    const Duration(milliseconds: 1000),
    () {
      Floor world = Floor(
        player: player,
        floorName: floorNames[currentFloorIndex],
      );

      cam = CameraComponent.withFixedResolution(
        world: world,
        width: 640,
        height: 340,
      );
      cam.viewfinder.anchor = Anchor.topLeft;

      addAll([cam, world]);

      // 相机初始化完成后再添加HUD
      if (showControls) {
        addJoystick();
        addJumpButton();
        addAttackButton();
      }
    },
  );
}

备选方案(不推荐)

  • 给HUD设置更高的优先级(比如priority:100),并且确保HUD在cam和world之后添加。但这种方式不如overlay稳定,因为CameraComponent内部的渲染层级可能会影响最终显示效果。

内容的提问来源于stack exchange,提问作者Gaeun Yoo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:29:59