Flutter Flame:如何使用 camera.followComponent 的视差?

Flutter Flame: how to use parallax with camera.followComponent?

我正在尝试使用 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 的 我最终得到了以下视差组件,现在它可以按预期工作。 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 编写)。