flame-engine / flame

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

SpriteButtonComponent throws error with button setter. (Unhandled Exception: Null check operator used on a null value) #3293

Closed puneet-739 closed 1 month ago

puneet-739 commented 2 months ago

What happened?

I am using SpriteButtonComponent, with flame (v1.18.0), everything was fine, but after updating to the latest flame version (v1.19.0), I got this error :-

E/flutter ( 8758): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value E/flutter ( 8758): #0 SpriteGroupComponent.updateSprite (package:flame/src/components/sprite_group_component.dart:103:13) E/flutter ( 8758): #1 SpriteButtonComponent.button= (package:flame/src/components/input/sprite_button_component.dart:50:5) E/flutter ( 8758): #2 DotButtonComponent.onLoad (package:pitu/pitu.dart:31:5) E/flutter ( 8758): #3 Component._startLoading (package:flame/src/components/core/component.dart:856:26) E/flutter ( 8758): #4 Component._addChild (package:flame/src/components/core/component.dart:606:20) E/flutter ( 8758): #5 Component.add (package:flame/src/components/core/component.dart:568:46) E/flutter ( 8758): #6 Pitu.onLoad (package:pitu/pitu.dart:22:5) E/flutter ( 8758): E/flutter ( 8758): #7 FlameGame.load (package:flame/src/game/flame_game.dart:105:5) E/flutter ( 8758): E/flutter ( 8758): #8 GameWidgetState.loaderFuture. (package:flame/src/game/game_widget/game_widget.dart:194:9) E/flutter ( 8758): E/flutter ( 8758): #9 _FutureBuilderState._subscribe. (package:flutter/src/widgets/async.dart:638:31) E/flutter ( 8758): E/flutter ( 8758):

What do you expect?

Just expecting my code to run error free after updating flame engine : ) '''' (oo) / \ ||

How can we reproduce this?

step 1: create a sample project in flutter. flutter create <project_name> step 2: add/update flame latest version (v1.19.0) flutter pub add flame step 3: create a class with extends SpriteButtonComponent class. step 4: in the onLoad() method, set the button setter with a Sprite object. class DotButtonComponent extends SpriteButtonComponent with HasGameReference<Pitu> { @override Future<void> onLoad() async { position = game.size / 2; anchor = Anchor.center; button = Sprite(Flame.images.fromCache('dot.png')); onPressed = () { log("hello world"); log("Me: After all this time?"); log("Error: Always"); }; } }

step 5: run the project. (don't forget to add your component with extends SpriteButtonComponet in FlameGame) note: if we use SpriteButtonComponent() Constructor and pass the Sprite, everything works fine.

What steps should take to fix this?

So, after digging the error I found the issue, So the issue is in the below code : /// Updates the sprite for the given key. void updateSprite(T key, Sprite sprite) { _sprites![key] = sprite; _resizeToSprite(); }

this belongs to the SpriteGroupComponent class, In SpriteGroupComponent, we set the sprites setter with a Map. As the SpriteButtonComponent extends SpriteGroupComponent (basically Button Component is made using Group Component), So this method is called in the SpriteButtonComponent class.

set button(Sprite value) { _button = value; updateSprite(ButtonState.up, value); }

And in the updateSprite() method, it updates the _sprites map, On using SpriteButtonComponent, the value of _sprites is still null because we have button and buttonDown (optional) setters we don't set sprites there. So it throws error. : (

Do have an example of where the bug occurs?

No response

Relevant log output

Error log: 

`E/flutter ( 8758): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value
E/flutter ( 8758): #0      SpriteGroupComponent.updateSprite (package:flame/src/components/sprite_group_component.dart:103:13)
E/flutter ( 8758): #1      SpriteButtonComponent.button= (package:flame/src/components/input/sprite_button_component.dart:50:5)
E/flutter ( 8758): #2      DotButtonComponent.onLoad (package:pitu/pitu.dart:31:5)
E/flutter ( 8758): #3      Component._startLoading (package:flame/src/components/core/component.dart:856:26)
E/flutter ( 8758): #4      Component._addChild (package:flame/src/components/core/component.dart:606:20)
E/flutter ( 8758): #5      Component.add (package:flame/src/components/core/component.dart:568:46)
E/flutter ( 8758): #6      Pitu.onLoad (package:pitu/pitu.dart:22:5)
E/flutter ( 8758): <asynchronous suspension>
E/flutter ( 8758): #7      FlameGame.load (package:flame/src/game/flame_game.dart:105:5)
E/flutter ( 8758): <asynchronous suspension>
E/flutter ( 8758): #8      GameWidgetState.loaderFuture.<anonymous closure> (package:flame/src/game/game_widget/game_widget.dart:194:9)
E/flutter ( 8758): <asynchronous suspension>
E/flutter ( 8758): #9      _FutureBuilderState._subscribe.<anonymous closure> (package:flutter/src/widgets/async.dart:638:31)
E/flutter ( 8758): <asynchronous suspension>
E/flutter ( 8758): 
`

Execute in a terminal and put output into the code block below

Output of: flutter doctor -v

[√] Flutter (Channel stable, 3.24.1, on Microsoft Windows [Version 10.0.17133.1], locale en-IN) • Flutter version 3.24.1 on channel stable at C:\src\flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 5874a72aa4 (12 days ago), 2024-08-20 16:46:00 -0500 • Engine revision c9b9d5780d • Dart version 3.5.1 • DevTools version 2.37.2

[√] Windows Version (Installed version of Windows is version 10 or higher)

[!] Android toolchain - develop for Android devices (Android SDK version 33.0.1) • Android SDK at C:\Users\BLACKSPACE\AppData\Local\Android\sdk X cmdline-tools component is missing Run path/to/sdkmanager --install "cmdline-tools;latest" See https://developer.android.com/studio/command-line for more details. X Android license status unknown. Run flutter doctor --android-licenses to accept the SDK licenses. See https://flutter.dev/to/windows-android-setup for more details.

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

[X] Visual Studio - develop Windows apps X Visual Studio not installed; this is necessary to develop Windows apps. Download at https://visualstudio.microsoft.com/downloads/. Please install the "Desktop development with C++" workload, including all of its default components

[√] Android Studio (version 2022.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 17.0.6+0-b2043.56-9586694)

[√] VS Code (version 1.92.1) • VS Code at C:\Users\BLACKSPACE\AppData\Local\Programs\Microsoft VS Code • Flutter extension can be installed from: https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[√] Connected device (3 available) • SM A336E (mobile) • RZCTA0CZP3P • android-arm64 • Android 14 (API 34) • Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.17133.1] • Chrome (web) • chrome • web-javascript • Google Chrome 127.0.6533.101

[√] Network resources • All expected network resources are available.

! Doctor found issues in 2 categories.

Affected platforms

All

Other information

No response

Are you interested in working on a PR for this?

ufrshubham commented 2 months ago

Seems like this change happened in #3185. Easiest change (and a little bit incorrect) to fix this would be to conditionally modify this map here https://github.com/flame-engine/flame/blob/76a9abaf3c70659323e02bf7b6531b4fbba1f7a2/packages/flame/lib/src/components/sprite_group_component.dart#L103

As a proper fix, I think SpriteButtonComponent should always start out with a map even if it is an empty one.

ufrshubham commented 2 months ago

@puneet-739 are you working on this? If so, I can assign this to you.

puneet-739 commented 2 months ago

@ufrshubham yes I am working on this, you can assign this to me.

spydon commented 1 month ago

Fixed in #3302