flame icon indicating copy to clipboard operation
flame copied to clipboard

SpriteAnimationComponent doesn't render on web

Open Kantino777 opened this issue 2 years ago • 7 comments

Current bug behaviour

I am using Flame and try to render a SpriteAnimationComponent. It works on an Android emulator but not on web. I tried with both Chrome and Edge.

Expected behaviour

SpriteAnimationComponent should render on web.

Steps to reproduce

I am following this tutorial: https://blog.codemagic.io/flutter-flame-game-development/ Source code available here: https://github.com/Ivy-Walobwa/flutter_flame_game_example You can run flutter pub upgrade to update the dependencies.

SpriteAnimationComponent class is the following:

DinoPlayer class
import 'package:flame/components.dart';
import 'package:flame/sprite.dart';
import 'helpers/directions.dart';

class DinoPlayer extends SpriteAnimationComponent with HasGameRef {
  DinoPlayer() : super(size: Vector2.all(100.0), anchor: Anchor.center);

  late final SpriteAnimation _walkingRightAnimation;
  late final SpriteAnimation _walkingLeftAnimation;
  late final SpriteAnimation _idleAnimation;

  final double _animationSpeed = .15;
  Direction direction = Direction.none;

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    await _loadAnimations();
    animation = _idleAnimation;
  }

  @override
  void update(double dt) {
    super.update(dt);
    updatePosition(dt);
  }

  updatePosition(double dt) {
    switch (direction) {
      case Direction.up:
        position.y--;
        break;
      case Direction.down:
        position.y++;
        break;
      case Direction.left:
        animation = _walkingLeftAnimation;
        position.x--;
        break;
      case Direction.right:
        animation = _walkingRightAnimation;
        position.x++;
        break;
      case Direction.none:
        animation = _idleAnimation;
        break;
    }
  }

  Future<void> _loadAnimations() async {
    final spriteSheet = SpriteSheet.fromColumnsAndRows(
        image: await gameRef.images.load('spritesheet.png'),
        columns: 30,
        rows: 1);

    _idleAnimation = spriteSheet.createAnimation(
        row: 0, stepTime: _animationSpeed, from: 0, to: 9);

    _walkingRightAnimation = spriteSheet.createAnimation(
        row: 0, stepTime: _animationSpeed, from: 10, to: 19);
    _walkingLeftAnimation = spriteSheet.createAnimation(
        row: 0, stepTime: _animationSpeed, from: 20, to: 29);
  }
}

Flutter doctor output

Output of: flutter doctor -v

[√] Flutter (Channel stable, 3.0.5, on Microsoft Windows [Version 10.0.19043.1826], locale en-GB) • Flutter version 3.0.5 at C:\Users\EATOPS\Downloads\flutter_windows_2.5.3-stable\flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision f1875d570e (2 weeks ago), 2022-07-13 11:24:16 -0700 • Engine revision e85ea0e79c • Dart version 2.17.6 • DevTools version 2.12.2

[√] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1) • Android SDK at C:\Users\EATOPS\AppData\Local\Android\sdk • Platform android-32, build-tools 32.1.0-rc1 • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840) • All Android licenses accepted.

[√] Chrome - develop for the web • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.2.6) • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community • Visual Studio Community 2022 version 17.2.32630.192 • Windows 10 SDK version 10.0.19041.0

[√] Android Studio (version 2021.2) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin can be installed from: https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)

[√] VS Code (version 1.69.2) • VS Code at C:\Users\EATOPS\AppData\Local\Programs\Microsoft VS Code • Flutter extension version 3.44.0

[√] Connected device (4 available) • sdk gphone x86 (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator) • Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.19043.1826] • Chrome (web) • chrome • web-javascript • Google Chrome 103.0.5060.134 • Edge (web) • edge • web-javascript • Microsoft Edge 102.0.1245.41

[√] HTTP Host Availability • All required HTTP hosts are available

• No issues found!

More environment information

  • Flame version: 1.2.1
  • Platform affected: web

Log information

None

More information

  • Using a SpriteComponent instead of a SpriteAnimationComponent works.
  • Same problem when running the game with flutter run -d chrome --web-renderer canvaskit

Kantino777 avatar Jul 27 '22 06:07 Kantino777

I'm not sure what is wrong, but the SpriteAnimationComponent is working like it should on all platforms on the example page: https://examples.flame-engine.org/#/Animations_Basic%20Animations

For your usecase I would use SpriteAnimationGroupComponent which can handle several different animation states.

spydon avatar Jul 27 '22 10:07 spydon

I still have the problem with SpriteAnimationGroupComponent: rendered on android emulator, not on web.

DinoPlayer
import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/sprite.dart';
import 'helpers/directions.dart';

class DinoPlayer extends SpriteAnimationGroupComponent<int>
    with HasGameRef {
  DinoPlayer() : super(size: Vector2.all(100.0), anchor: Anchor.center);

  late final SpriteAnimation _walkingRightAnimation;
  late final SpriteAnimation _walkingLeftAnimation;
  late final SpriteAnimation _idleAnimation;

  final double _animationSpeed = .15;
  Direction direction = Direction.none;

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    await _loadAnimations();
    animations = {
      0: _idleAnimation,
      1: _walkingLeftAnimation,
      2: _walkingRightAnimation
    };
    current = 0;
    // animation = _idleAnimation;
    // sprite = await gameRef.loadSprite('idle.png');
  }

  @override
  void update(double dt) {
    super.update(dt);
    updatePosition(dt);
  }

  updatePosition(double dt) {
    switch (direction) {
      case Direction.up:
        position.y--;
        break;
      case Direction.down:
        position.y++;
        break;
      case Direction.left:
        current = 1;
        //animation = _walkingLeftAnimation;
        position.x--;
        break;
      case Direction.right:
        current = 2;
        //animation = _walkingRightAnimation;
        position.x++;
        break;
      case Direction.none:
        current = 0;
        //animation = _idleAnimation;
        break;
    }
  }

  Future<void> _loadAnimations() async {
    final spriteSheet = SpriteSheet.fromColumnsAndRows(
        image: await gameRef.images.load('spritesheet.png'),
        columns: 30,
        rows: 1);

    _idleAnimation = spriteSheet.createAnimation(
        row: 0, stepTime: _animationSpeed, from: 0, to: 9);

    _walkingRightAnimation = spriteSheet.createAnimation(
        row: 0, stepTime: _animationSpeed, from: 10, to: 19);
    _walkingLeftAnimation = spriteSheet.createAnimation(
        row: 0, stepTime: _animationSpeed, from: 20, to: 29);
  }
}

Kantino777 avatar Jul 27 '22 10:07 Kantino777

@Kantino777 Web example of SpriteAnimationGroupComponent is also working as it should: https://examples.flame-engine.org/#/Animations_Basic%20Animations. One of my game also uses SpriteAnimationGroupComponent and is running perfectly fine on web. https://github.com/ufrshubham/dino_run

ufrshubham avatar Jul 30 '22 14:07 ufrshubham

@ufrshubham Good to know it works in the general case. Can you test the project https://github.com/Ivy-Walobwa/flutter_flame_game_example and check if you can see the dino character ? To know if the problem is specific to my environment. Because I don't see what could be wrong in the code

Kantino777 avatar Jul 30 '22 20:07 Kantino777

I checked the project shared by @Kantino777 and was able to reproduce the problem. The spritesheet used in that project is quite huge (20460 x 474 px) and it seems that Image is struggling to load this on web builds. It works if I lower the resolution of the whole spritesheet or even if I split it into multiple smaller chunks. The problem might be in Flutter because same behavior is observed when trying to display that spritesheet using Flutter's Image widget.

ufrshubham avatar Jul 31 '22 07:07 ufrshubham

@ufrshubham Thanks for checking and your investigation. Since this was just a tutorial, I am glad to see that the problem comes from this specific spritesheet. I shouldn't get this trouble when building my own game then.

Kantino777 avatar Jul 31 '22 08:07 Kantino777

We should probably introduce a warning when loading that big spritesheets, I realize this isn't the first time someone has had this problem.

spydon avatar Jul 31 '22 13:07 spydon