所以我只是在学习如何创造一个太空入侵者类型的游戏。我可以让坏人搬家,太棒了!英雄动作,太棒了!!子弹移动,太棒了!!然而,一旦他们离开屏幕,我试图移除我的子弹,以免占用所有资源,一旦它摆脱子弹,它会强行关闭我。它离开了屏幕。点击-2的int然后我们使用remove()和boom。强制关闭。
这是我的代码。我想知道他们是否同时访问size()并因此而导致力量关闭。
//I removed everything that doesn't pertane to the bullets.
public class GameScreen{
Bullet bullet = world.bullet;
public GameScreen(Game game) {
super(game);
world = new World();
}
//Draws our bullets.
int bulletLength = bullet.bullets.size();
for(int i = 0; i < bulletLength; i++) {
Placement part = bullet.bullets.get(i);
x = part.x * 32 + 11;
y = part.y * 32;
g.drawPixmap(Assets.bullet, x, y);
}
持有我的子弹的类。
public class Bullet {
public List<Placement> bullets = new ArrayList<Placement>();
public Bullet() {
}
public void shoot(int x, int y){
bullets.add(new Placement(x,y));
}
public void advance(){
int len = bullets.size(); // gets all bullets.
for(int i = 0; i < len; i++) {
bullets.get(i).y --;
if (bullets.get(i).y <= -2){//removes them once they are off the screen.
bullets.remove(i);
}
}
}
这是我用来跟踪展示位置的方法。
package com.learning.planecomander;
public class Placement {
public int x, y;
public Placement(int x, int y) {
this.x = x;
this.y = y;
}
}
答案 0 :(得分:1)
当您浏览列表以删除项目符号时,您可以从列表中删除项目符号但会立即影响列表,而不是在完成循环后。由于您在开始时遍历列表的长度,因此您将删除列表的末尾,因为您已删除元素。一个例子可能比那个描述更有帮助。
假设你有一个包含三个项目符号的列表(我将其称为a,b,c以使示例更容易)。在通过列表时,a和c很好但是b需要被删除。
i = 0; 子弹[0] = a; 子弹[1] = b; 子弹[2] = c;
第一个循环顺利,第二个循环就像这样开始
i = 1; 子弹[0] = a; 子弹[1] = b; 子弹[2] = c;
我们删除b,但循环继续
i = 2; 子弹[0] = a; 子弹[1] = c;
OH CRAP ARRAYINDEXOUTOFBOUNDS!计划崩溃!
解决此问题的方法是使用临时列表来存储需要删除的项目符号,然后在完成更新循环后,拨打bullets.removeAll(temp)
答案 1 :(得分:0)
两次传球是一个很好的答案。它使循环更简单,易于理解。如果您想在一次通过中执行此操作,请按相反的顺序遍历列表,当您删除子弹时,您可以转到下一个项目,而不必担心在ArrayList的末尾爆破。
或者,您可以将项目符号保留在链接列表中,并使用Iterator运行列表,您也可以使用它来从列表中删除项目。从链接列表的开头中间或末尾删除始终是恒定时间操作。而从ArrayList的开头删除可能更昂贵。如果您需要随机访问列表中的元素,那么它们可能效率低下。但请记住,如果你只处理少数几个对象,那么它并不重要。
对于奖励积分,您可能希望将所有对象放在一个列表中,然后让您的中央循环处理它们并让您的游戏对象以多态方式响应死亡,思考,移动,绘制或其他任何内容认为合适。