Flutter:在 null 上调用了更新
Flutter: update was called on null
我正在尝试使用 flutter 的库 Flame 制作游戏。但我每次都会收到这个错误。它是说更新是在 null 上调用的。但是我已经在initialize函数中进行了初始化。我尝试了几种方法,但似乎没有任何效果。请帮我修复错误。
import 'dart:math';
import 'dart:ui';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:small_game/components/Enemy.dart';
import 'package:small_game/components/enemy_spawner.dart';
import 'package:small_game/components/heath_bar.dart';
import 'package:small_game/components/highscoreText.dart';
import 'package:small_game/components/player.dart';
import 'package:small_game/components/score_text.dart';
import 'package:small_game/components/startText.dart';
import 'package:small_game/states.dart' as gameState;
class GameController extends Game{
Random rand;
Size screenSize;
double tileSize;
Player player;
EnemySpawner enemySpawner;
List<Enemy> enemies;
HealthBar healthBar;
int score;
ScoreText scoreText;
SharedPreferences storage;
gameState.State state;
HighScoreText highScoreText;
StartText startText;
GameController(this.storage){
initialize();
}
void initialize() async{
rand = Random();
resize(await Flame.util.initialDimensions());
player = Player(this);
state = gameState.State.menu;
enemies = List<Enemy>();
enemySpawner = EnemySpawner(this);
healthBar = HealthBar(this);
score = 0;
highScoreText = HighScoreText(this);
startText = StartText(this);
}
@override
void render(Canvas canvas) {
Rect background = Rect.fromLTWH(0, 0, screenSize.width, screenSize.height);
Paint backgroundPaint = Paint()..color = Color(0xffFCFCFA);
canvas.drawRect(background, backgroundPaint);
player.render(canvas);
if(state == gameState.State.menu){
startText.render(canvas);
highScoreText.render(canvas);
} else if(state == gameState.State.playing) {
enemies.forEach((Enemy enemy) => enemy.render(canvas));
scoreText.render(canvas);
healthBar.render(canvas);
}
}
@override
void update(double t) {
if(state == gameState.State.menu){
highScoreText.update(t);
startText.update(t);
} else if(state == gameState.State.playing) {
enemies.forEach((Enemy enemy) => enemy.update(t));
enemies.removeWhere((Enemy enemy) => enemy.isDead);
player.update(t);
scoreText.update(t);
healthBar.update(t);
enemySpawner.update(t);
}
}
void resize(Size size){
screenSize = size;
tileSize = screenSize.width / 10;
}
void onTapDown(TapDownDetails d){
enemies.forEach((Enemy enemy) {
if(state == gameState.State.menu){
state = gameState.State.playing;
}
if(enemy.enemyRect.contains(d.globalPosition)){
enemy.onTapDown();
}
});
}
void spawnEnemies(){
double x,y;
switch(rand.nextInt(4)){
case 0:
//TOP
x = rand.nextDouble() * screenSize.width;
y = -tileSize * 2.5;
break;
case 1:
//RIGHT
x = (tileSize * 2.5) + screenSize.width;
y = rand.nextDouble() * screenSize.height;
break;
case 2:
//BOTTOM
x = rand.nextDouble() * screenSize.width;
y = (tileSize * 2.5) + screenSize.height;
break;
case 3:
//LEFT
x = -(tileSize * 2.5);
y = rand.nextDouble() * screenSize.height;
}
enemies.add(Enemy(this, x, y));
}
}
我的错误:
I/flutter (20131): ══╡ EXCEPTION CAUGHT BY SCHEDULER LIBRARY
╞═════════════════════════════════════════════════════════ I/flutter
(20131): The following NoSuchMethodError was thrown during a scheduler
callback: I/flutter (20131): The method 'update' was called on null.
I/flutter (20131): Receiver: null I/flutter (20131): Tried calling:
update(0.0) I/flutter (20131): I/flutter (20131): When the exception
was thrown, this was the stack: I/flutter (20131): #0
Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
I/flutter (20131): #1 GameController.update (package:small_game/gameController.dart:69:17)
I/flutter (20131): #2 GameRenderBox._update (package:flame/game.dart:360:10)
I/flutter (20131): #3 GameRenderBox._tick (package:flame/game.dart:353:5)
I/flutter (20131): #4 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1033:15)
I/flutter (20131): #5 SchedulerBinding.handleBeginFrame.
(package:flutter/src/scheduler/binding.dart:951:11)
I/flutter (20131): #6 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
I/flutter (20131): #7 SchedulerBinding.handleBeginFrame (package:flutter/src/scheduler/binding.dart:949:17)
I/flutter (20131): #8 SchedulerBinding.scheduleWarmUpFrame.
(package:flutter/src/scheduler/binding.dart:780:7)
I/flutter (20131): #17 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19)
I/flutter (20131): #18 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
I/flutter (20131): #19 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
I/flutter (20131): (elided 8 frames from package dart:async and package dart:async-patch)
I/flutter (20131):
I/flutter (20131):
I/flutter (20131): This exception was thrown in the context of a scheduler callback. When the scheduler callback was registered (as
opposed to when the exception was thrown), this was the stack:
I/flutter (20131): #0 new _FrameCallbackEntry. (package:flutter/src/scheduler/binding.dart:112:33)
I/flutter (20131): #1 new _FrameCallbackEntry (package:flutter/src/scheduler/binding.dart:115:6)
I/flutter (20131): #2 SchedulerBinding.scheduleFrameCallback (package:flutter/src/scheduler/binding.dart:459:49)
I/flutter (20131): #3 GameRenderBox._scheduleTick (package:flame/game.dart:341:50)
I/flutter (20131): #4 GameRenderBox.attach (package:flame/game.dart:328:5)
I/flutter (20131): #5 RenderObjectWithChildMixin.attach (package:flutter/src/rendering/object.dart:2886:14)
I/flutter (20131): #6 AbstractNode.adoptChild (package:flutter/src/foundation/node.dart:132:13)
I/flutter (20131): #7 RenderObject.adoptChild (package:flutter/src/rendering/object.dart:1232:11)
I/flutter (20131): #8 RenderObjectWithChildMixin.child= (package:flutter/src/rendering/object.dart:2879:7)
I/flutter (20131): #9 RenderObjectToWidgetElement.insertChildRenderObject
(package:flutter/src/widgets/binding.dart:1020:18)
I/flutter (20131): #10 RenderObjectElement.attachRenderObject (package:flutter/src/widgets/framework.dart:4986:35)
I/flutter (20131): #11 RenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4752:5)
I/flutter (20131): #12 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3101:14)
I/flutter (20131): #13 Element.updateChild (package:flutter/src/widgets/framework.dart:2904:12)
I/flutter (20131): #14 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3961:16)
I/flutter (20131): #15 Element.rebuild (package:flutter/src/widgets/framework.dart:3738:5)
I/flutter (20131): #16 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3924:5)
I/flutter (20131): #17 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3919:5)
I/flutter (20131): #18 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3101:14)
I/flutter (20131): #19 Element.updateChild (package:flutter/src/widgets/framework.dart:2904:12)
I/flutter (20131): #20 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:998:16)
I/flutter (20131): #21 RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:969:5)
I/flutter (20131): #22 RenderObjectToWidgetAdapter.attachToRenderTree.
(package:flutter/src/widgets/binding.dart:915:17)
I/flutter (20131): #23 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2328:19)
I/flutter (20131): #24 RenderObjectToWidgetAdapter.attachToRenderTree
(package:flutter/src/widgets/binding.dart:914:13)
I/flutter (20131): #25 WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:795:7)
I/flutter (20131): #26 runApp (package:flutter/src/widgets/binding.dart:845:7)
I/flutter (20131): #27 main (package:small_game/main.dart:17:3)
I/flutter (20131): (elided 14 frames from package dart:async and package dart:async-patch)
您的 initialize
函数是异步的,这意味着它将 运行 在后台运行。因此,当首次调用更新时,startText
为 null 并为您提供 NPE。您可能想在 update
上添加一些检查以确保它在继续更新代码之前已初始化,或者使 initialize
同步然后稍后执行您需要的任何异步操作(自初始化 startText
当然不是其中之一)。
我正在尝试使用 flutter 的库 Flame 制作游戏。但我每次都会收到这个错误。它是说更新是在 null 上调用的。但是我已经在initialize函数中进行了初始化。我尝试了几种方法,但似乎没有任何效果。请帮我修复错误。
import 'dart:math';
import 'dart:ui';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:small_game/components/Enemy.dart';
import 'package:small_game/components/enemy_spawner.dart';
import 'package:small_game/components/heath_bar.dart';
import 'package:small_game/components/highscoreText.dart';
import 'package:small_game/components/player.dart';
import 'package:small_game/components/score_text.dart';
import 'package:small_game/components/startText.dart';
import 'package:small_game/states.dart' as gameState;
class GameController extends Game{
Random rand;
Size screenSize;
double tileSize;
Player player;
EnemySpawner enemySpawner;
List<Enemy> enemies;
HealthBar healthBar;
int score;
ScoreText scoreText;
SharedPreferences storage;
gameState.State state;
HighScoreText highScoreText;
StartText startText;
GameController(this.storage){
initialize();
}
void initialize() async{
rand = Random();
resize(await Flame.util.initialDimensions());
player = Player(this);
state = gameState.State.menu;
enemies = List<Enemy>();
enemySpawner = EnemySpawner(this);
healthBar = HealthBar(this);
score = 0;
highScoreText = HighScoreText(this);
startText = StartText(this);
}
@override
void render(Canvas canvas) {
Rect background = Rect.fromLTWH(0, 0, screenSize.width, screenSize.height);
Paint backgroundPaint = Paint()..color = Color(0xffFCFCFA);
canvas.drawRect(background, backgroundPaint);
player.render(canvas);
if(state == gameState.State.menu){
startText.render(canvas);
highScoreText.render(canvas);
} else if(state == gameState.State.playing) {
enemies.forEach((Enemy enemy) => enemy.render(canvas));
scoreText.render(canvas);
healthBar.render(canvas);
}
}
@override
void update(double t) {
if(state == gameState.State.menu){
highScoreText.update(t);
startText.update(t);
} else if(state == gameState.State.playing) {
enemies.forEach((Enemy enemy) => enemy.update(t));
enemies.removeWhere((Enemy enemy) => enemy.isDead);
player.update(t);
scoreText.update(t);
healthBar.update(t);
enemySpawner.update(t);
}
}
void resize(Size size){
screenSize = size;
tileSize = screenSize.width / 10;
}
void onTapDown(TapDownDetails d){
enemies.forEach((Enemy enemy) {
if(state == gameState.State.menu){
state = gameState.State.playing;
}
if(enemy.enemyRect.contains(d.globalPosition)){
enemy.onTapDown();
}
});
}
void spawnEnemies(){
double x,y;
switch(rand.nextInt(4)){
case 0:
//TOP
x = rand.nextDouble() * screenSize.width;
y = -tileSize * 2.5;
break;
case 1:
//RIGHT
x = (tileSize * 2.5) + screenSize.width;
y = rand.nextDouble() * screenSize.height;
break;
case 2:
//BOTTOM
x = rand.nextDouble() * screenSize.width;
y = (tileSize * 2.5) + screenSize.height;
break;
case 3:
//LEFT
x = -(tileSize * 2.5);
y = rand.nextDouble() * screenSize.height;
}
enemies.add(Enemy(this, x, y));
}
}
我的错误:
I/flutter (20131): ══╡ EXCEPTION CAUGHT BY SCHEDULER LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter (20131): The following NoSuchMethodError was thrown during a scheduler callback: I/flutter (20131): The method 'update' was called on null. I/flutter (20131): Receiver: null I/flutter (20131): Tried calling: update(0.0) I/flutter (20131): I/flutter (20131): When the exception was thrown, this was the stack: I/flutter (20131): #0
Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5) I/flutter (20131): #1 GameController.update (package:small_game/gameController.dart:69:17) I/flutter (20131): #2 GameRenderBox._update (package:flame/game.dart:360:10) I/flutter (20131): #3 GameRenderBox._tick (package:flame/game.dart:353:5) I/flutter (20131): #4 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1033:15) I/flutter (20131): #5 SchedulerBinding.handleBeginFrame. (package:flutter/src/scheduler/binding.dart:951:11) I/flutter (20131): #6 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8) I/flutter (20131): #7 SchedulerBinding.handleBeginFrame (package:flutter/src/scheduler/binding.dart:949:17) I/flutter (20131): #8 SchedulerBinding.scheduleWarmUpFrame. (package:flutter/src/scheduler/binding.dart:780:7) I/flutter (20131): #17 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19) I/flutter (20131): #18 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5) I/flutter (20131): #19 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12) I/flutter (20131): (elided 8 frames from package dart:async and package dart:async-patch) I/flutter (20131): I/flutter (20131): I/flutter (20131): This exception was thrown in the context of a scheduler callback. When the scheduler callback was registered (as opposed to when the exception was thrown), this was the stack: I/flutter (20131): #0 new _FrameCallbackEntry. (package:flutter/src/scheduler/binding.dart:112:33) I/flutter (20131): #1 new _FrameCallbackEntry (package:flutter/src/scheduler/binding.dart:115:6) I/flutter (20131): #2 SchedulerBinding.scheduleFrameCallback (package:flutter/src/scheduler/binding.dart:459:49) I/flutter (20131): #3 GameRenderBox._scheduleTick (package:flame/game.dart:341:50) I/flutter (20131): #4 GameRenderBox.attach (package:flame/game.dart:328:5) I/flutter (20131): #5 RenderObjectWithChildMixin.attach (package:flutter/src/rendering/object.dart:2886:14) I/flutter (20131): #6 AbstractNode.adoptChild (package:flutter/src/foundation/node.dart:132:13) I/flutter (20131): #7 RenderObject.adoptChild (package:flutter/src/rendering/object.dart:1232:11) I/flutter (20131): #8 RenderObjectWithChildMixin.child= (package:flutter/src/rendering/object.dart:2879:7) I/flutter (20131): #9 RenderObjectToWidgetElement.insertChildRenderObject (package:flutter/src/widgets/binding.dart:1020:18) I/flutter (20131): #10 RenderObjectElement.attachRenderObject (package:flutter/src/widgets/framework.dart:4986:35) I/flutter (20131): #11 RenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4752:5) I/flutter (20131): #12 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3101:14) I/flutter (20131): #13 Element.updateChild (package:flutter/src/widgets/framework.dart:2904:12) I/flutter (20131): #14 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3961:16) I/flutter (20131): #15 Element.rebuild (package:flutter/src/widgets/framework.dart:3738:5) I/flutter (20131): #16 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3924:5) I/flutter (20131): #17 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3919:5) I/flutter (20131): #18 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3101:14) I/flutter (20131): #19 Element.updateChild (package:flutter/src/widgets/framework.dart:2904:12) I/flutter (20131): #20 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:998:16) I/flutter (20131): #21 RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:969:5) I/flutter (20131): #22 RenderObjectToWidgetAdapter.attachToRenderTree. (package:flutter/src/widgets/binding.dart:915:17) I/flutter (20131): #23 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2328:19) I/flutter (20131): #24 RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:914:13) I/flutter (20131): #25 WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:795:7) I/flutter (20131): #26 runApp (package:flutter/src/widgets/binding.dart:845:7) I/flutter (20131): #27 main (package:small_game/main.dart:17:3) I/flutter (20131): (elided 14 frames from package dart:async and package dart:async-patch)
您的 initialize
函数是异步的,这意味着它将 运行 在后台运行。因此,当首次调用更新时,startText
为 null 并为您提供 NPE。您可能想在 update
上添加一些检查以确保它在继续更新代码之前已初始化,或者使 initialize
同步然后稍后执行您需要的任何异步操作(自初始化 startText
当然不是其中之一)。