【发布时间】:2019-10-09 01:00:03
【问题描述】:
我正在 libgdx 中进行 Missile Command 重制。
我有 3 个数组列表:bullets、missiles 和 houses。
我一直在尝试遍历列表以检测missiles 和houses 以及missiles 和bullets 之间的冲突,但是到目前为止我尝试过的所有内容都收到了这个非常广泛的错误消息:
Exception in thread "LWJGL Application" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at com.mygdx.game.Screen.MCGameScreen.render(MCGameScreen.java:112)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
我尝试遍历导致(可能是missiles)数组列表检查由于碰撞而已被删除的位置的某些内容的所有方式都存在相同的问题。我不想“重用”数组中的对象,我更愿意删除它们。
这是创建新导弹的代码,并将它们添加到missiles 数组中,每 2 秒创建一个新导弹,在屏幕顶部给定一个随机位置,并添加到 missiles。
timer += delta;
if(timer >= 2) {
Sprite temp = new Sprite(missile);
temp.setPosition((float) (Math.random() * Gdx.graphics.getWidth() - temp.getWidth()), Gdx.graphics.getHeight());
missiles.add(temp);
timer = 0;
}
这是创建新子弹的代码,并将其添加到bullets数组中,每次按下空格键时,都会创建一个新子弹,设置到坦克位置的中心,并添加到@ 987654334@.
if(keycode == Input.Keys.SPACE) {
Sprite temp = new Sprite(bullet);
temp.setPosition(tank.getX() + tank.getWidth()/2 - temp.getWidth()/2, tank.getY() + tank.getHeight());
bullets.add(temp);
}
这是我在创建要添加到列表的temp 变量时使用的预设精灵的初始化,以及数组列表本身。
bullet = new Sprite(new Texture("bullet.png"));
bullets = new ArrayList<>();
missile = new Sprite(new Texture("missile.png"));
missiles = new ArrayList<>();
house = new Sprite(new Texture("house.png"));
houses = new ArrayList<>();
这是我尝试检查碰撞的第一种方法,我也使用相同的循环来移动导弹和子弹。
for(int i = bullets.size()-1; i >= 0; i--) {
bullets.get(i).translateY(bulletSpeed);
if(bullets.get(i).getY() >= Gdx.graphics.getHeight() + bullet.getHeight()) {
bullets.remove(i);
}
for(int j = missiles.size()-1; j >= 0; j--) {
if(missiles.get(j).getBoundingRectangle().overlaps(bullets.get(i).getBoundingRectangle())) {
missiles.remove(j);
bullets.remove(i);
}
}
}
for(int i = missiles.size()-1; i >= 0; i--) {
missiles.get(i).translateY(missileSpeed);
if(missiles.get(i).getY() <= 0) {
missiles.remove(i);
}
for(int j = houses.size()-1; j >= 0; j--) {
if(houses.get(j).getBoundingRectangle().overlaps(missiles.get(i).getBoundingRectangle())) {
houses.remove(j);
missiles.remove(i);
}
}
}
这是我尝试过的第二种方法,我将所有内容拆分为单独的循环,以防数组的索引在被删除后仍在循环中使用。
for(int i = bullets.size()-1; i >= 0; i--) {
bullets.get(i).translateY(bulletSpeed);
if(bullets.get(i).getY() >= Gdx.graphics.getHeight() + bullet.getHeight()) {
bullets.remove(i);
}
}
for(int i = missiles.size()-1; i >= 0; i--) {
missiles.get(i).translateY(missileSpeed);
if(missiles.get(i).getY() <= 0) {
missiles.remove(i);
}
}
for(int i = missiles.size()-1; i >= 0; i--) {
for(int j = bullets.size()-1; j >= 0; j--) {
if(missiles.get(i).getBoundingRectangle().overlaps(bullets.get(j).getBoundingRectangle())) {
missiles.remove(i);
bullets.remove(j);
}
}
}
for(int i = missiles.size()-1; i >= 0; i--) {
for(int j = houses.size()-1; j >= 0; j--) {
if(missiles.get(i).getBoundingRectangle().overlaps(houses.get(j).getBoundingRectangle())) {
missiles.remove(i);
houses.remove(j);
}
}
}
我也尝试过这种变体,使用增强的 for 循环。
for(Sprite missile: missiles) {
missile.translateY(missileSpeed);
if(missile.getY() <= 0) {
missiles.remove(missiles.indexOf(missile));
}
}
for(Sprite bullet: bullets) {
bullet.translateY(bulletSpeed);
if(bullet.getY() >= Gdx.graphics.getHeight() + bullet.getHeight()) {
bullets.remove(bullets.indexOf(bullet));
}
}
for(Sprite missile: missiles) {
for(Sprite bullet: bullets) {
if(missile.getBoundingRectangle().overlaps(bullet.getBoundingRectangle())) {
missiles.remove(missiles.indexOf(missile));
bullets.remove(bullets.indexOf(bullet));
}
}
}
如果您需要我遗漏的任何细节,请告诉我!
【问题讨论】: