使用列表会导致意外行为
Working with Lists results in unexpected behavior
什么
我正在尝试编写一个系统,其中包括使用列表来管理其他对象可以通过各种方式与之交互的对象。特别是,我正在研究 2d 游戏的碰撞检测。我的问题是我划分的系统运行异常,我无法识别。我的眼睛已经盯着这个问题好几个小时了,现在眼睛越来越痛,所以我在这里寻求支持。
进入正题
问题是:无法与列表中另一个对象之前添加的对象进行交互,如果这样做,游戏就会崩溃,告诉我无法使用前一个对象所在位置的内存。我可能是错的,但我对列表的理解让我相信情况不应该如此,我应该能够访问列表任何位置的任何数据,对吧?
与最后添加到列表中的对象进行交互非常好,没有问题,当该对象稍后从列表中删除时,可以与前一个对象进行交互非常好,依此类推。
向我们展示详细信息
这是将对象添加到列表的代码,它被调用每一帧,因为列表每帧都会清除自己以保持数据最新。
for (var k = 0; k < player.leftEmitter.projectiles.Count; k++) {
var projectile = player.leftEmitter.projectiles[k];
var targets = projectile.collider.targets;
if (!testNPC.disposed) targets.Add(testNPC.collider);
if (!testNPC2.disposed) targets.Add(testNPC2.collider);
}
for (var l = 0; l < player.rightEmitter.projectiles.Count; l++) {
var projectile = player.rightEmitter.projectiles[l];
var targets = projectile.collider.targets;
if (!testNPC.disposed) targets.Add(testNPC.collider);
if (!testNPC2.disposed) targets.Add(testNPC2.collider);
}
这里是与对象交互时调用的代码,也是每帧调用。
for (var i = 0; i < targets.Count; i++) {
var box = targets[i];
if (!box.parent.disposed) {
if (colliderRect.GetGlobalBounds().Intersects(box.colliderRect.GetGlobalBounds()) && !hasEntered) {
hasEntered = true;
OnColliderEnter(box);
} else if (!colliderRect.GetGlobalBounds().Intersects(box.colliderRect.GetGlobalBounds()) && hasEntered) {
hasEntered = false;
OnColliderExit(box);
}
}
}
我找到了解决方案,只需检查目标对撞机是否已被处置,然后再迭代其 OnColliderEnter()
功能即可完全解决问题。其实这与列表无关,也与我对它们的理解无关。只是我没有妥善处理处置。我很欣赏 C# 的垃圾收集器,但有时很难记住像这样简单的事情到处检查。
什么
我正在尝试编写一个系统,其中包括使用列表来管理其他对象可以通过各种方式与之交互的对象。特别是,我正在研究 2d 游戏的碰撞检测。我的问题是我划分的系统运行异常,我无法识别。我的眼睛已经盯着这个问题好几个小时了,现在眼睛越来越痛,所以我在这里寻求支持。
进入正题
问题是:无法与列表中另一个对象之前添加的对象进行交互,如果这样做,游戏就会崩溃,告诉我无法使用前一个对象所在位置的内存。我可能是错的,但我对列表的理解让我相信情况不应该如此,我应该能够访问列表任何位置的任何数据,对吧?
与最后添加到列表中的对象进行交互非常好,没有问题,当该对象稍后从列表中删除时,可以与前一个对象进行交互非常好,依此类推。
向我们展示详细信息
这是将对象添加到列表的代码,它被调用每一帧,因为列表每帧都会清除自己以保持数据最新。
for (var k = 0; k < player.leftEmitter.projectiles.Count; k++) {
var projectile = player.leftEmitter.projectiles[k];
var targets = projectile.collider.targets;
if (!testNPC.disposed) targets.Add(testNPC.collider);
if (!testNPC2.disposed) targets.Add(testNPC2.collider);
}
for (var l = 0; l < player.rightEmitter.projectiles.Count; l++) {
var projectile = player.rightEmitter.projectiles[l];
var targets = projectile.collider.targets;
if (!testNPC.disposed) targets.Add(testNPC.collider);
if (!testNPC2.disposed) targets.Add(testNPC2.collider);
}
这里是与对象交互时调用的代码,也是每帧调用。
for (var i = 0; i < targets.Count; i++) {
var box = targets[i];
if (!box.parent.disposed) {
if (colliderRect.GetGlobalBounds().Intersects(box.colliderRect.GetGlobalBounds()) && !hasEntered) {
hasEntered = true;
OnColliderEnter(box);
} else if (!colliderRect.GetGlobalBounds().Intersects(box.colliderRect.GetGlobalBounds()) && hasEntered) {
hasEntered = false;
OnColliderExit(box);
}
}
}
我找到了解决方案,只需检查目标对撞机是否已被处置,然后再迭代其 OnColliderEnter()
功能即可完全解决问题。其实这与列表无关,也与我对它们的理解无关。只是我没有妥善处理处置。我很欣赏 C# 的垃圾收集器,但有时很难记住像这样简单的事情到处检查。