flame
flame copied to clipboard
SpriteAnimationComponent doesn't render on web
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 aSpriteAnimationComponent
works. - Same problem when running the game with
flutter run -d chrome --web-renderer canvaskit
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.
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 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 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
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 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.
We should probably introduce a warning when loading that big spritesheets, I realize this isn't the first time someone has had this problem.