I'm making a basic game, and it's almost done. I was trying to do object collision and started getting IndexOutOfBounds exceptions. I think this means that my arrayLists that I am storing object under are pointing to nothing, but I don't know why this is happening nor how to fix it. I also understand that this is a question that many people ask, however I have been unable to figure it out by looking at other posts. I do not understand arrayLists well enough.
Here is the class. The relevant code is mostly on lines 75 - 99. Any help you can give would be appreciated!
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) {
}
}
Your problem is that you use the size variable to determine the number of iterations of the following loop. size is initialized to bullCount.size(), but if you remove an element from bullCount, the size of that list becomes smaller, and the loop would throw IndexOutOfBoundException :
for (int i = 0; i < size; i++) {
if(bullCount.get(i).getBounds().intersects(enemy.get(0).getBounds())) {
enemy.remove(0);
bullCount.remove(i);
}
You need to do two things to fix the loop :
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
}
In addition, calling enemy.get(2) without checking that enemy.size()>2 may throw the same exception. And calling enemy.remove(2) will cause the element that was in index 3 to move to index 2. This will probably screw your logic.
EDIT :
Your logic will probably work better using a nested loop :
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;
}
}
}
This is assuming a bullet can only destroy one enemy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With