物体碰撞问题

Object Collision Issues

我正在制作一款基础游戏,快完成了。我试图进行对象碰撞并开始出现 IndexOutOfBounds 异常。我认为这意味着我存储对象的 arrayLists 没有指向任何内容,但我不知道为什么会这样,也不知道如何修复它。我也知道这是很多人问的问题,但是我一直无法通过查看其他帖子来弄清楚。我不太了解 arrayLists。

这里是class。相关代码主要在第 75 - 99 行。如果您能提供任何帮助,我们将不胜感激!

package Sprites;


import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;


public class Player implements KeyListener{

private int x;
private ArrayList<Integer> keysDown;
private ArrayList<Bullets> bullCount;
private ArrayList<Enemy> enemy;
private Bullets b;
private Enemy e;
private int size;
long start;
long elapsed;
boolean run;

public int getbY() {
    return b.getY();
}
public int getbX() {
    return b.getX();
}

public Player(int x1) {
    x = x1; //initial spawns of player
    run = true;
    keysDown = new ArrayList<Integer>();
    bullCount = new ArrayList<Bullets>();
    enemy = new ArrayList<Enemy>();
    start = System.nanoTime();
    for (int i = 240; i < 800; i = i + (800/10)){
        e = new Enemy(i, true);
        enemy.add(e);
        if (enemy.size() > 5) {
            enemy.remove(5);
        }
    }

}

public boolean isRun() {
    return run;
}
public void update() {
    move(); //player movement

    size = bullCount.size(); //bullet updates
    if (size > 0) {
        for(int i = 0; i < size; i++)  {
            bullCount.get(i).update();
            if (bullCount.get(i).getY() < 0) {
                bullCount.remove(i);
                return;
            }
        }
    }//end of bullet spawns

    for(int i = 0; i < 5; i++) {
        if (enemy.get(i).getY() >= 535) //end game
            run = false;
    }

    if (enemy.size() > 0) {
        for (int i = 0; i < 5; i ++) { //update enemys
            enemy.get(i).update();
        }
    }

    //bullet collision
    for (int i = 0; i < size; i++) {

        if(bullCount.get(i).getBounds().intersects(enemy.get(0).getBounds())) {
            enemy.remove(0);
            bullCount.remove(i);
        }

        if(bullCount.get(i).getBounds().intersects(enemy.get(2).getBounds())) {
            enemy.remove(2);
            bullCount.remove(i);
        }

        if(bullCount.get(i).getBounds().intersects(enemy.get(1).getBounds())) {
            enemy.remove(1);
            bullCount.remove(i);
        }

        if(bullCount.get(i).getBounds().intersects(enemy.get(3).getBounds())) {
            enemy.remove(3);
            bullCount.remove(i);
        }

        if(bullCount.get(i).getBounds().intersects(enemy.get(4).getBounds())) {
            enemy.remove(4);
            bullCount.remove(i);
        }

    }

}


public ArrayList<Enemy> getEnemy() {
    return enemy;
}
public void move() {

    if(keysDown.contains(KeyEvent.VK_A)) {
        if (x > 0 + 10) {
        x = x - 3;
        }
    }
    if(keysDown.contains(KeyEvent.VK_D)){
        if (x < 800 - 42) {
        x = x + 3;
        }
    }
    if (keysDown.contains(KeyEvent.VK_SPACE)) {

        elapsed = System.nanoTime() - start;

        if (elapsed > 185000000) {
        b = new Bullets(x);
        bullCount.add(b);
        start = System.nanoTime();
        }
    }
}

public ArrayList<Bullets> getBullCount() {
    return bullCount;
}

public int getPX() {
    return x;
}

public void keyPressed(KeyEvent e) {
    if (!keysDown.contains(e.getKeyCode()))
        keysDown.add(new Integer(e.getKeyCode()));
    }

public void keyReleased(KeyEvent e) {
    keysDown.remove(new Integer(e.getKeyCode()));

}

public void keyTyped(KeyEvent e) {

}
}

您的问题是您使用 size 变量来确定以下循环的迭代次数。 size 被初始化为 bullCount.size(),但是如果从 bullCount 中删除一个元素,该列表的大小会变小,并且循环将抛出 IndexOutOfBoundException :

for (int i = 0; i < size; i++) {

    if(bullCount.get(i).getBounds().intersects(enemy.get(0).getBounds())) {
        enemy.remove(0);
        bullCount.remove(i);
    }

您需要做两件事来修复循环:

for (int i = 0; i < bullCount.size(); i++) { // get the current size from the list

    if(bullCount.get(i).getBounds().intersects(enemy.get(0).getBounds())) {
        enemy.remove(0);
        bullCount.remove(i);
        i--; // if you remove an element, the indices of the following elements
             // are decremented, so you should iterate over the same value
             // of i in order not to skip an element
    }

此外,调用enemy.get(2)而不检查enemy.size()>2可能会抛出同样的异常。并且调用 enemy.remove(2) 将导致索引 3 中的元素移动到索引 2。这可能会破坏您的逻辑。

编辑:

使用嵌套循环您的逻辑可能会更好:

for (int i = 0; i < bullCount.size(); i++) {
    for (int j = 0; j < enemy.size(); j++) {
        if(bullCount.get(i).getBounds().intersects(enemy.get(j).getBounds())) {
            enemy.remove(j);
            bullCount.remove(i);
            i--;
            break;
        }
    }
}

这是假设一颗子弹只能摧毁一个敌人。