I'm trying to delete two objects from their respectives arrays when they collide.

But I'm getting IndexOutOfBonds on the third for inside draw(). I know that the reason is because I'm removing an object from an array while it's on a loop, but I can't figure out a way to do it without this error coming up.

MAIN TAB:

int naveX, naveY;
int movimentoTotal;
int tempoInimigo;

boolean tiroVisivel;
boolean naveDireita, naveEsquerda;
boolean removerTiro, removerInimigo;

ArrayList<Tiro> tiros;
ArrayList<Inimigo> inimigos;

void setup() {
  size (800, 600);

  naveX = 375; 
  naveY = height - 120;

  naveDireita = naveEsquerda = false; 

  tiros = new ArrayList<Tiro>();
  inimigos = new ArrayList<Inimigo>();
}

void draw() {
  translate (0, -(naveY - 480));
  background (0);

  nave();
  movimentoNave();

  naveY = naveY - 1;
  movimentoTotal = movimentoTotal + 1;

  int numTiros =  tiros.size();
  for (int i = numTiros - 1; i >= 0; i = i - 1) {
    tiros.get(i).display();
    tiros.get(i).update();
    if (tiros.get(i).deletarTiro == true || removerTiro == true) {
      tiros.remove(tiros.get(i));
    }
  }
  //println (numTiros);

  if (millis() > tempoInimigo + 1500) {
    tempoInimigo =  millis();
    inimigos.add(new Inimigo());
  }

  int numInimigos = inimigos.size();
  for (int i = numInimigos - 1; i >=0; i = i - 1) {
    inimigos.get(i).display();
    inimigos.get(i).update();
    if (inimigos.get(i).deletarInimigo == true || removerInimigo == true) {
      inimigos.remove(inimigos.get(i));
    }
  }

  //println("Número inimigos é: " + numInimigos);

  for (int i = numTiros - 1; i >= 0; i = i - 1) {
    for (int j = numInimigos - 1; j >= 0; j = j - 1) {
      float distance = dist(tiros.get(i).tiroX, tiros.get(i).tiroY, inimigos.get(j).inimigoX, inimigos.get(j).inimigoY);
      if (distance < 6) {
        removerTiro = true;
        removerInimigo = true;
      }
    }
  }
}

void nave() {
  stroke (255);
  fill (255, 0, 0);
  rect (naveX, naveY, 50, 100);
}

void movimentoNave() {
  if (naveEsquerda == true && naveX > 0) {
    naveX = naveX - 5;
  }
  if (naveDireita == true && naveX < width - 50) {
    naveX = naveX + 5;
  }
}



void keyPressed() {
  //create a new shot.
  if (key == ' ') {
    tiros.add(new Tiro(naveX + 20, naveY - 30));
  }

  if (key == 'a' || key == 'A') {
    naveEsquerda = true;
  }
  if (key == 'd' || key == 'D') {
    naveDireita = true;
  }

  if (key == 'r' || key == 'R') {
    setup();
  }
}

void keyReleased() {
  if (key == 'a' || key == 'A') {
    naveEsquerda = false;
  }
  if (key == 'd' || key == 'D') {
    naveDireita = false;
  }
}

ENEMYS TAB:

public class Inimigo {

  public int inimigoX =  int (random(15, width - 15));
  public int inimigoY =  -100 - movimentoTotal;
  public boolean deletarInimigo;

  public Inimigo() {
    //this.inimigoX = inimigoX;
    //this.inimigoY = inimigoY;
    deletarInimigo = false;
    removerInimigo = false;
  }

  void mostrar() {
    stroke (255);
    fill (0, 100, 255);
    rect (inimigoX, inimigoY, 30, 50);
  }

  void deletar() {
    if (inimigoY > height - movimentoTotal) {
      deletarInimigo = true;
    }
  }
}

PROJECTILES TAB:

public class Tiro {

  public int tiroX;
  public int tiroY;
  public boolean deletarTiro;

  public Tiro (int tiroX, int tiroY) {
    this.tiroX = tiroX;
    this.tiroY = tiroY;
    deletarTiro = false;
    removerTiro = false;
  }

  void display() {
    stroke (255);
    fill (255, 0, 100);
    rect (tiroX, tiroY, 10, 20);
  }

  void update() {
    if (tiroY > 0 - movimentoTotal) {
      tiroY = tiroY - 10;
    } else {
      deletarTiro = true;
    }
  }
}

Answers

  • edited March 2017 Answer ✓

    Problem is you cached the size() of both ArrayList containers as numTiros & numInimigos.

    Caching is very nice on performance and very commendable btW. :-bd

    However, after calling remove(), the values stored on them aren't correct anymore! :-SS

    You need to update them before the 3rd for ( ; ; ) loop: *-:)

    numTiros =  tiros.size();
    numInimigos = inimigos.size();
    

    BtW, the double 3rd for ( ; ; ) loops don't need to be backwards as the previous 1s; given remove() isn't used there! :P

    And some important performance extra tips:

    a) Cache the element object right after the 1st get():

    for (int i = tiros.size(); i-- != 0; ) {
      final Tiro t = tiros.get(i); // cache element
      t.display();
      t.update();
      // rest of code...
    }
    

    b) When using remove(), prefer the index value overloaded version, rather than the Object 1.
    Knowing the index is totally & incomparably faster than searching the Object to remove(): :-B

    if (t.deletarTiro || t.removerTiro)  tiros.remove(i);  // remove by index!
    
  • Oh, I understand now. I'm really new to procesing and getting back to programming after a few years.

Sign In or Register to comment.