flutter 火焰 : how to use parallax with camera. followComponent?

标签 flutter flame

使用 Flutter Flame 我正在尝试为横向卷轴游戏创建视差背景,其中相机聚焦于英雄。我只找到了恒速滚动视差的示例,但没有找到尊重游戏世界中摄像机移动的示例。

如果我给视差一个非零的baseVelocity,即使相机不移动它也会继续滚动。如果我将 baseVelocity 设置为零,视差背景将随着相机移动而移动,但实际的视差效果不可见(即所有图层只是随着相机移动而均匀滚动)。

是否有一种设置可以使用 camera.followComponent 和内置 ParallaxComponent ,以便当相机跟随时背景图层会以视差效果移动主题?或者我是否必须实现自己的尊重相机运动的视差背景?

这是我尝试过的:

视差背景组件:

class BackgroundComponent extends ParallaxComponent {
  double? lastCameraX;

  @override
  Future<void> onLoad() async {
    super.onLoad();
    parallax = await gameRef.loadParallax(
      _imageNames,
      // baseVelocity: Vector2(0.0, 0.0),
      velocityMultiplierDelta: Vector2(1.8, 1.0),
      alignment: Alignment.center,
    );
  }

  static final _imageNames = [
    ParallaxImageData('background/parallax-mountain-bg.png'),
    ParallaxImageData('background/parallax-mountain-mountain-far.png'),
    ParallaxImageData('background/parallax-mountain-mountains.png'),
    ParallaxImageData('background/parallax-mountain-trees.png'),
    ParallaxImageData('background/parallax-mountain-foreground-trees.png'),
  ];

}

FlameGame 加载:

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    Flame.device.setLandscape();
    add(BackgroundComponent()); // This is the parallax background

    final hero= Hero();
    add(hero);

    camera.speed = 1;
    camera.followComponent(hero, relativeOffset: const Anchor(0.2, 1));
  }

更新 基于spydon的answer我最终得到了以下视差组件,它现在按预期工作。 IE。视差效果与相机的移动有关。

class BackgroundComponent extends ParallaxComponent {
  Vector2 lastCameraPosition = Vector2.zero();

// here comes onLoad(), loading the actual images - not relevant
// ...

  @override
  Future<void> update(double dt) async {
    super.update(dt);
    final cameraPosition = gameRef.camera.position;
    final delta = dt > threshold ? 1.0 / (dt * framesPerSec) : 1.0;
    final baseVelocity = cameraPosition
      ..sub(lastCameraPosition)
      ..multiply(backgroundVelocity)
      ..multiply(Vector2(delta, delta));
    parallax!.baseVelocity.setFrom(baseVelocity);
    lastCameraPosition.setFrom(gameRef.camera.position);
  }

  static final backgroundVelocity = Vector2(3.0, 0);
  static const framesPerSec = 60.0;
  static const threshold = 0.005;
}

最佳答案

首先,您必须将 ParallaxComponent 设置为不随相机移动组件本身(这是我们这边的一个错误,在下一个版本中将默认设置)。

您可以通过在组件中设置 positionType = PositionType.viewport; (或覆盖该字段)来实现此目的。

现在您可以将 camera.position 连接到视差的 baseVelocity,例如:

class BackgroundComponent extends ParallaxComponent {
  Vector2 lastCameraPosition = Vector2.zero();

// here comes onLoad(), loading the actual images - not relevant
// ...

  @override
  Future<void> update(double dt) async {
    super.update(dt);
    final cameraPosition = gameRef.camera.position;
    final delta = dt > threshold ? 1.0 / (dt * framesPerSec) : 1.0;
    final baseVelocity = cameraPosition
      ..sub(lastCameraPosition)
      ..multiply(backgroundVelocity)
      ..multiply(Vector2(delta, delta));
    parallax!.baseVelocity.setFrom(baseVelocity);
    lastCameraPosition.setFrom(gameRef.camera.position);
  }

  static final backgroundVelocity = Vector2(3.0, 0);
  static const framesPerSec = 60.0;
  static const threshold = 0.005;
}

(生成的代码由 András Szepesházi 编写)。

关于 flutter 火焰 : how to use parallax with camera. followComponent?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71131480/

相关文章:

dart - 一次从流中请求一个项目的数据?

dart - 如何在 Flutter 中为抽屉菜单项添加徽章?

Flutter TextFormField 初始值不起作用

flutter - 如何用 Canvas 替换 Flutter 小部件,反之亦然?

flutter - Flutter 中的持久代码

flutter - 如何同时实现拖动和点击

flutter - Dismissible 和 FutureBuilder 不能一起工作

flutter - 更改选项卡时如何获取Flutter ScrollController以保存ListView.builder()的位置?

flutter - 如何处理平台游戏的对象碰撞?

flutter - Flutter更新给我这个错误:在空调用方法 '*'