我一直在寻找解决方案一段时间,但找不到任何东西。
这个问题很奇怪,所以我会给出一些背景知识。我正在进行塔防游戏,并且在对敌人实施状态效果时(减速,着火等)我遇到了一个奇怪的问题。当塔用射弹杀死敌人时一切都很好,但由于某种原因当敌人被状态效应杀死时,我得到一个空对象引用错误(两者都用方法“Enemy.damage(damage:int)”处理“)。关于这一点的奇怪之处在于状态效果存储在一个仅在3个点中引用的数组中。在ENTER_FRAME事件中(一个ENTER_FRAME事件用于处理游戏中的每个方面),在构造函数(status = new Array();)和destroy方法中。
一个奇怪的部分是,如果“status”变量为null,则destroy方法中的其他变量会在很久以前给我错误。真正奇怪的部分是我在得到错误之前就进行了空检查。
这是我收到错误的地方:
//STATUS EFFECTS
if (status == null) {
trace("test");
}
if (status != null && status.length != 0) {
for (var i:int = 0; i < status.length; i++) {//LINE 101
status[i].applyEffect();
}
}
这是错误:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at game.enemies::Enemy/update()[C:\flash\game\enemies\Enemy.as:101]
“test”永远不会打印出来,即使使用空检查我仍然会收到错误
编辑:这是敌人类:http://pastebin.com/LAyMMB1P
StatusEffect&amp; FireEffect类:http://pastebin.com/GTGDmjt8(我只能发布2个链接,每个链接都在自己的文件中)
状态变量在StatusEffect.destroy()和此处引用:
override public function onHit(e:Enemy) {
if (upgradeLevel >= 1) {
var onFire = false;
for (var i:int = 0; i < e.status.length; i++) {
if (e.status[i].name_ == "fire") {
onFire = true;
}
}
if (!onFire) {
e.status.push(new FireEffect(e));
}
}
if (upgradeLevel >= 2) {
if (enemiesHit.indexOf(e) == -1) {
enemiesHit.push(e);
e.damage(1);
}
if (upgradeLevel == 2 && enemiesHit.length == 2) {
destroy();
}
} else {
e.damage(super.damage);
destroy();
return;
}
}
答案 0 :(得分:1)
这种情况正在发生,因为你可能会在第101行的for循环中间摧毁你的敌人。
销毁敌人会将状态数组设置为null,因此在下次迭代时检查i < status.length
,状态是否为空,从而导致错误。
为了说明,单步执行代码,让我们假设第101行status
数组中有两个项目:
第一个循环,索引为0
的项目会在其上调用applyEffect()
。
applyEffect()
内{li> 可以调用specificApplication()
方法。
在specificApplication()
内调用super.enemy.damage(1);
方法。
在enemy.damage()
方法中,您可以调用enemy.destroy
方法
在enemy.destroy
方法中,您设置了status = null
。
现在来自第101行的循环循环,但状态现在为空。
如果敌人被摧毁,可以通过打破你的循环来解决这个问题。
for (var i:int = 0; i < status.length; i++) {//LINE 101
status[i].applyEffect();
if(!status) break;
}
您还有一些拼接问题:
enemy.status.splice(enemy.status.indexOf(this), 1);
虽然它上面的那一行没有任何问题,但让我们逐步完成代码:
Enemy
类的第101行:
for (var i:int = 0; i < status.length; i++) {
循环遍历状态数组。对于此示例,我们假设您在数组中有两个项目。
项目A位于0
位置。项目B位于数组中的1
位置。
第一个循环,i
的值为0
。
您致电status[i].applyEffect()
,i == 0
,即项目A.
在applyEffect
内,请说明您的情况已经满足,因此请致电destroy
(StatusEffect
班级)
在StatusEffect.destroy()
方法中,您拼接status
数组。
现在status
只有一个项目B项,而项目B现在的索引为0(而不是1)。
你的循环循环,现在是i == 1
。
但是,索引1处不再有任何项目,因此循环退出,跳过项目B.
要解决这个问题,请反向迭代,然后当你拼接时你的指数不会出现问题:
var i:int = status.length
while(i--){
status[i].applyEffect();
}
顺便说一句,如果您使用var status:Vector.<StatusEffect>
而不是var status:Array
,那将更加清晰。您可以通过这种方式检查编译时间并输入安全性。