flame-engine / flame

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

SpriteAnimationComponent doesn't render on web #1822

Closed Kantino777 closed 1 year ago

Kantino777 commented 2 years ago

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 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 _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

Log information

None

More information

spydon commented 2 years ago

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.

Kantino777 commented 2 years ago

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 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 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 _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); } } ```
ufrshubham commented 2 years ago

@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

Kantino777 commented 2 years ago

@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

ufrshubham commented 2 years ago

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.

Kantino777 commented 2 years ago

@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.

spydon commented 2 years ago

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