flame

How to achieve an animation track from one point to another?


How to achieve an animation track from one point to another? MovingParticle seems to be able to achieve but can only receive one point. I want multiple points, such as a-b-c-d, and the animation time between each two points is different. There is also a related problem, how to realize the process of moving from a-b to show the animation from opaque to transparent at the same time. At present, I have realized these two points, but occasionally there is a jam between animations. I want to know if there is a better way

 List<List<Vector2>> fromList = [
    [Vector2.zero()..y += 12, Vector2.zero()..y -= 3],
    [Vector2.zero()..y -= 3, Vector2.zero()],
    [Vector2.zero(), Vector2.zero()..y -= 1.5],
    [Vector2.zero()..y -= 1.5, Vector2.zero()]
  ];
  test() async {
    for (var i = 0; i < fromList.length; i++) {
      ParticleSystemComponent component = await play(fromList[i], i);
      world.add(component);[enter image description here](https://i.sstatic.net/7oHGix4e.gif)
      await Future.delayed(const Duration(milliseconds: 300));
    }
  }
  Future<ParticleSystemComponent> play(List<Vector2> list, int i) async {
    Sprite sprite = await loadSprite("atlantic/assemble_5.png",
        srcSize: Vector2(82, 82), srcPosition: Vector2(0, 320));
    MovingParticle? movingParticle;
    movingParticle = MovingParticle(
      from: list[0],
      lifespan: 0.3,
      to: list[1],
      child: MySpriteParticle(
          index: i,
          sprite: sprite,
          size: Vector2(5, 5),
          position: Vector2.zero(),
          anchor: Anchor.center),
    );

    return ParticleSystemComponent(
      particle: movingParticle,
    );
  }
class MySpriteParticle extends SpriteParticle {
  final Duration duration = const Duration(milliseconds: 300);
  late DateTime startTime;
  MySpriteParticle({
    required super.sprite,
    required Vector2 super.size,
    required Vector2 super.position,
    required super.anchor,
    required this.index,
  }) {
    startTime = DateTime.now();
  }
  final int index;
  @override
  void render(Canvas canvas) {
    DateTime now = DateTime.now();
    Duration elapsedTime = now.difference(startTime);
    double progress =
        (elapsedTime.inMilliseconds / duration.inMilliseconds).clamp(0.0, 1.0);
    double opacity = progress;
    Paint paint = Paint()..color = Colors.white.withOpacity(opacity);
    sprite.render(canvas,
        overridePaint: index == 0 ? paint : null,
        anchor: anchor,
        position: position,
        size: size);
  }
}

enter image description here

I want to know if there is a better way


Solution

  • You can use the MoveByPathEffect and add all the points that you want to the Path.

    final path = Path()..moveTo(100, 100)..lineTo(150, 150)..lineTo(200, -100),
    final effect = MoveAlongPathEffect(
      path,
      EffectController(duration: 1.5),
    );
    yourComponent.add(effect);
    

    PS. Don't call sprite.render manually inside of your SpriteComponent, that is already done automatically.

    Source: https://docs.flame-engine.org/latest/flame/effects.html#movealongpatheffect