flame-engine / flame

A Flutter based game engine.
https://flame-engine.org
MIT License
8.98k stars 879 forks source link

Use the flame_texturepacker , Paired with SpriteAnimationGroupComponent, but can't work. #3180

Closed ycfay closed 1 month ago

ycfay commented 1 month ago

Problem to solve

the code

class YangMonster extends Monster {
  late TexturePackerAtlas atlas;

  @override
  Future<void> onLoad() async {
    atlas = await game.atlasFromAssets('tester/shiki/sni.atlas');
    await prepareAnimations();
    await super.onLoad();
  }

  @override
  Future<void> prepareAnimations() async {
    animations = {};
    for (var action in PlayerState.values) {
      final sprites = atlas.findSpritesByName(action.name);
      if (sprites.isNotEmpty) {
        SpriteAnimation animation = SpriteAnimation.spriteList(
          sprites,
          stepTime: 0.2,
          loop: true,
        );
        animations!.addAll({action: animation});
      }
    }
    current = PlayerState.idle_down;
    size = Vector2.all(60);
    //         add(
    //   SpriteAnimationComponent(scale: Vector2.all(0.5), animation: animation),
    // );
  }
}

i must add(SpriteAnimationComponent...) to be able to work, which is not what I was hoping for!

Proposal

I hope to be able to support SpriteAnimationGroupComponent.

More information

No response

Other

spydon commented 1 month ago

Can you do print(animations); after you have prepared them?

ycfay commented 1 month ago

print(animations) the result: flutter: {PlayerState.attack_down: Instance of 'SpriteAnimation', PlayerState.attack_down_left: Instance of 'SpriteAnimation', PlayerState.attack_down_right: Instance of 'SpriteAnimation', PlayerState.attack_left: Instance of 'SpriteAnimation', PlayerState.attack_right: Instance of 'SpriteAnimation', PlayerState.attack_up: Instance of 'SpriteAnimation', PlayerState.attack_up_left: Instance of 'SpriteAnimation', PlayerState.attack_up_right: Instance of 'SpriteAnimation', PlayerState.idle_up: Instance of 'SpriteAnimation', PlayerState.idle_down: Instance of 'SpriteAnimation', PlayerState.idle_left: Instance of 'SpriteAnimation', PlayerState.idle_right: Instance of 'SpriteAnimation', PlayerState.idle_down_left: Instance of 'SpriteAnimation', PlayerState.idle_down_right: Instance of 'SpriteAnimation', PlayerState.idle_up_left: Instance of 'SpriteAnimation', PlayerState.idle_up_right: Instance of 'SpriteAnimation', PlayerState.run_down: Instance of 'SpriteAnimation', PlayerState.run_down_left: Instance of 'SpriteAnimation', PlayerState.run_down_right: Instance of 'SpriteAnimation', PlayerState.run_left: Instance of 'SpriteAnimation', PlayerState.run_right: Instance of 'SpriteAnimation', PlayerState.run_up_left: Instance of 'SpriteAnimation', PlayerState.run_up_right: Instance of 'SpriteAnimation', PlayerState.run_up: Instance of 'SpriteAnimation', PlayerState.death_down: Instance of 'SpriteAnimation', PlayerState.death_down_left: Instance of 'SpriteAnimation', PlayerState.death_down_right: Instance of 'SpriteAnimation', PlayerState.death_left: Instance of 'SpriteAnimation', PlayerState.death_right: Instance of 'SpriteAnimation', PlayerState.death_up: Instance of 'SpriteAnimation', PlayerState.death_up_left: Instance of 'SpriteAnimation', PlayerState.death_up_right: Instance of 'SpriteAnimation'}

ycfay commented 1 month ago

the base class

class Monster extends SpriteAnimationGroupComponent<PlayerState>
    with HasGameRef<Test8Game>, CollisionCallbacks {
  @override
  Future<void> onLoad() async {

  }

  Future<void> prepareAnimations() async {}
}
spydon commented 1 month ago

Which version of Flame are you on?

ycfay commented 1 month ago

flame: ^1.18.0 flame_texturepacker: ^4.0.1

I think it's the components haven't been adapted yet!

spydon commented 1 month ago

I think it's the components haven't been adapted yet!

They should be fine, the output are just normal SpriteAnimation instances which is what SpriteGroupComponent handles. Can you provide a repository (it can be private, but you'd have to invite me) with a minimal reproducible example, containing the atlas etc?

ycfay commented 1 month ago

The code has been uploaded to GitHub: https://github.com/ycfay/tsdm.git

Tkx

spydon commented 1 month ago

Now I see what your problem is, you have to use the animations setter, not mutate the existing map since the animations then won't get any animation tickers etc. So do this instead:

  @override
  Future<void> prepareAnimations() async {
    // The size I would put in the constructor
    size = Vector2.all(60);

    final newAnimations = {};
    for (var action in PlayerState.values) {
      final sprites = atlas.findSpritesByName(action.name);
      if (sprites.isNotEmpty) {
        SpriteAnimation animation = SpriteAnimation.spriteList(
          sprites,
          stepTime: 0.2,
          loop: true,
        );
        newAnimations.addAll({action: animation});
      }
    }
    animations = newAnimations;
    current = PlayerState.idle_down;
  }
spydon commented 1 month ago

Disallowed these mutations in #3183 to avoid confusion in the future.

ycfay commented 1 month ago

It worked, thanks!