作为序言,我搜索了论坛,但没有发现与我的具体情况有关。我刚刚开始学习Java一周前,这是我第一次涉足面向对象编程。
我正在构建一个基本游戏(在机制方面,有点像Space Invaders)。我有一个“Projectile”类,一个“FallingThings”类(它是我对掉落物体(Money,Friend,Enemy)的类的父类)。射击的每个射弹都存储在ArrayList中,就像Money,Friend和Enemy的每个实例一样(每个都在它们自己的ArrayList中)。
实现碰撞检测时会出现问题。首先,它需要多个子弹才能使碰撞机制起作用(我想我可能在这里搞砸了一些数字,但我不是100%肯定)。现在,有时在我发射多个子弹(并且它们已经很久)之后,检测到碰撞而没有我发射另一个子弹并且一个FallingThings对象从屏幕上消失。此外,在其他时候,多个对象一次消失。最奇怪的是,所有这些都是不一致的,并且不总是以相同的方式再现。但是,我与玩家角色的碰撞完美无缺。
任何人都有一些关于我如何解决这个问题的想法?我的代码如下:
“FallingThings”类中的方法(ArrayLists在StartingClass(主类)中定义)。
public void checkBulletCollision(Rectangle rectangle) {
for (int j = 0; j < Character.getProjectiles().size(); j++) {
Projectile p = (Projectile) Character.getProjectiles().get(j);
if (p.isVisible() == true) {
for (int i = 0; i < StartingClass.getMoneys().size(); i++) {
Money m = (Money) StartingClass.getMoneys().get(i);
if (m.getR().intersects(rectangle)) {
m.remove(i);
System.out.println("bullet collision");
}
}
for (int i = 0; i < StartingClass.getEnemies().size(); i++) {
Enemy e = (Enemy) StartingClass.getEnemies().get(i);
if (e.getR().intersects(rectangle)) {
e.remove(i);
}
}
for (int i = 0; i < StartingClass.getFriends().size(); i++) {
Friend f = (Friend) StartingClass.getFriends().get(i);
if (f.getR().intersects(rectangle)) {
f.remove(i);
}
}
}
}
}
我对弹丸的更新方法:
public void update() {
y -= speedY;
if (y < 0) {
visible = false;
}
rectangle.setBounds(getRectangle());
}
我一直试图解决这个问题一整天,但仍然无法正确实施。我尝试过使用ListIterator,但这会导致程序冻结并抛出类型转换错误。
非常感谢你的帮助! =)
答案 0 :(得分:1)
我怀疑您遇到了问题,因为您在循环显示该列表时通过索引从列表中删除项目。删除项目会导致索引计数器退出分配。尝试使用实际的Iterator
。甚至无需考虑索引。 Iterator
有针对这些情况的删除方法..
Iterator<Enemy> iterator = StartingClass.getEnemies().iterator();
while (iterator.hasNext()) {
Enemy e = iterator.next();
if (e.getR().intersects(rectangle)) {
iterator.remove();
}
}
答案 1 :(得分:0)
我不明白 m.remove 的作用,您从列表中获取该项目,然后在该项目上调用“删除”。你想从列表中删除它吗?
StartingClass.getMoneys().remove(i);
答案 2 :(得分:0)
看起来问题是您要让所有类型的循环运行。因此,即使在用你的射弹移除金钱之后,你也可以使用相同的射弹移除敌人和敌人 - 如果弹丸是从更大的东西或从.44马格南射出的话,这是可能的。 无论如何,对我来说,看起来你需要打破你的迭代一旦你用一个射弹移除一个项目..所以你的代码应该是(使用泛型和增强的循环):
foreachprojectile:
for( Projectile projectile : Character.getProjectiles()){
if (projectile.isVisible() == true) {
Iterator<Money> iterator = StartingClass.getMoneys().iterator();
while (iterator.hasNext()) {
Money m = iterator.next();
if (m.getR().intersects(rectangle)) {
iterator.remove();
projectile.setVisible(false); // or any other method that does similar
break foreachprojectile; //Found a hit, so do not
//look for any more hits with current projectile
}
}
//And so on..
}
}
以上代码可能会完成你想要的;但是这个逻辑可以更好地封装,以清楚地传达意图。
答案 3 :(得分:0)
我弄清楚出了什么问题并解决了问题。事实证明问题不在我的for循环实现中(尽管使用listIterator仍然更有效且更不容易出错,所以我仍然选择改变我的代码的那个方面),而是在实现中我的碰撞检测。我忘记了抛射物和矩形(用于射弹)是两个不同的物体,因此,矩形没有与抛射物一起移动,导致各种各样的问题。
我通过将矩形绘制到屏幕来确定问题来检查它的表现,当然,它只是停留在一个地方,而不是与射弹一起移动。我对射弹的update()方法进行了一些更改,以便在调用时,矩形随子弹移动。这导致了正确的碰撞检测和正常运行的程序!
非常感谢大家的帮助,我在这里学到了很多关于编写高效代码和调试技术的知识!对此,我真的非常感激! =)