如何在设定的时间间隔后在两个状态(aminations)之间切换并添加过渡动画

问题描述 投票:0回答:1

我刚刚开始学习扑动和火焰,我正在开发一个简单的平台游戏,我想添加一只外壳上带有尖刺的敌方乌龟。我想让尖刺在3秒后进出,而主角只有在尖刺进入后才能取消它的生命。怎么能做到呢。

我尝试使用 Future.delayed 函数,但我无法使其工作

enum TurtleState { hit, idleSpikesIn, idleSpikesOut, spikesIn, spikesOut }

class Turtle extends SpriteAnimationGroupComponent
    with HasGameRef<PixelAdventure>, CollisionCallbacks {
  final double offNeg;
  final double offPos;
  Turtle({
    super.position,
    super.size,
    this.offPos = 0,
    this.offNeg = 0,
  });

  late final SpriteAnimation _hitAnimation;
  late final SpriteAnimation _idleSpikeInAnimation;
  late final SpriteAnimation _idleSpikeOutAnimation;
  late final SpriteAnimation _spikeOutAnimation;
  late final SpriteAnimation _spikeInAnimation;
  late final Player player;

  static const _bounceHeight = 260.0;
  static const stepTime = 0.05;
  static const tileSize = 16;

  final textureSize = Vector2(44, 26);

  double moveSpeed = 80;
  double moveDirection = -1;
  double rangeNeg = 0;
  double rangePos = 0;

  bool gotStomped = false;
  bool spikesIn = false;

  @override
  FutureOr<void> onLoad() {
    player = game.player;
    add(RectangleHitbox(
      position: Vector2.zero(),
      size: Vector2(44, 26),
    ));

    debugMode = true;

    _loadAllAnimations();
    _calculateRange();
    return super.onLoad();
  }

  @override
  void update(double dt) {
    if (!gotStomped) {
      _updateState();
      _movement(dt);
    }
    super.update(dt);
  }

  void _loadAllAnimations() {
    _idleSpikeOutAnimation = _spriteAnimation('Idle 1', 14);
    _hitAnimation = _spriteAnimation('Hit', 5)..loop = false;
    _idleSpikeInAnimation = _spriteAnimation('Idle 2', 8);
    _spikeOutAnimation = _spriteAnimation('Spikes out', 8)..loop = false;
    _spikeInAnimation = _spriteAnimation('Spikes in', 8)..loop = false;

    animations = {
      TurtleState.idleSpikesIn: _idleSpikeInAnimation,
      TurtleState.idleSpikesOut: _idleSpikeOutAnimation,
      TurtleState.hit: _hitAnimation,
      TurtleState.spikesOut: _spikeOutAnimation,
      TurtleState.spikesIn: _spikeInAnimation,
    };
    current = TurtleState.idleSpikesOut;
  }

  SpriteAnimation _spriteAnimation(String state, int amount) {
    return SpriteAnimation.fromFrameData(
      game.images.fromCache('Enemies/Turtle/$state (44x26).png'),
      SpriteAnimationData.sequenced(
        amount: amount,
        stepTime: stepTime,
        textureSize: textureSize,
      ),
    );
  }

  void _calculateRange() {
    rangeNeg = position.x - offNeg * tileSize;
    rangePos = position.x + width + offPos * tileSize;
  }

  void _updateState() {
    if ((moveDirection > 0 && scale.x > 0) ||
        (moveDirection < 0 && scale.x < 0)) {
      flipHorizontallyAroundCenter();
    }
    const spikeDuration = Duration(seconds: 3);
    Future.delayed(spikeDuration, () {
      current = TurtleState.idleSpikesOut;
      spikesIn = false;
    });
    Future.delayed(spikeDuration, () {
      spikesIn = true;
      current = TurtleState.spikesIn;
    });
  }

  void _movement(double dt) {
    if (position.x >= rangePos) {
      moveDirection = -1;
    } else if (position.x <= rangeNeg) {
      moveDirection = 1;
    }
    position.x += moveSpeed * moveDirection * dt;
  }

  void collidedWithPlayer() async {
    if (player.velocity.y > 0 && player.y + player.height > position.y) {
      gotStomped = true;
      current = TurtleState.hit;
      player.velocity.y = -_bounceHeight;
      await animationTicker?.completed;
      removeFromParent();
    } else {
      player.collidedWithEnemy();
    }
  }
flutter flutter-animation flame
1个回答
0
投票

我看不到其他人为

Future.delayed
之外的延迟创建变量的任何示例。
您可能只需要像这样重构持续时间:

  void _updateState() {
    if ((moveDirection > 0 && scale.x > 0) ||
        (moveDirection < 0 && scale.x < 0)) {
      flipHorizontallyAroundCenter();
    }
    Future.delayed(const Duration(seconds: SPIKE_DURATION), () {
      current = TurtleState.idleSpikesOut;
      spikesIn = false;
    });
    Future.delayed(const Duration(seconds: SPIKE_DURATION), () {
      spikesIn = true;
      current = TurtleState.spikesIn;
    });
  }

文件顶部定义了持续时间

// Duration in seconds
const SPIKE_DURATION = 3

堆栈上的一些其他答案

Flutter 文档示例:

Future.delayed(const Duration(seconds: 1), () {
  print('One second has passed.'); // Prints after 1 second.
});
© www.soinside.com 2019 - 2024. All rights reserved.