Удаление объекта из ArrayList приводит к задержке - PullRequest
0 голосов
/ 15 февраля 2012

У меня есть ArrayList , который содержит самолеты (враги) в моей игре на андроид. Эти самолеты перемещаются с одной стороны экрана на другую, и пользователь должен избегать их. Когда значение x плоскости становится меньше -50, оно удаляется из ArrayList. Когда это происходит, все самолеты на экране в настоящий момент слегка «прыгают». Они исчезают на несколько миллисекунд, а затем перерисовываются, но на 2 пикселя позади того места, где они должны быть.

Вот метод рисования, где плоскости - ArrayList

public void onDraw(){
        bg1.onDraw(c);
    bg2.onDraw(c);
    chopper.onDraw(c);

    score.onDraw(c);

    // PAINTS THE PLANE OR DELETES IF OFF SCREEN
    for (int i = 0; i < planes.size(); i++) {
        Plane p = planes.get(i);
                    if(p.getX()<-50){
                            planes.remove(p);
                    }else{
                            p.onDraw(c);

                            if (p.getX() < 170) {
                                    detectPlaneCollision(p, c);
                            }
                    }

           }
}

Есть ли способ исправить это? Должен ли я использовать другую структуру данных?

Спасибо

Tom

Ответы [ 3 ]

1 голос
/ 15 февраля 2012

Я думаю, что ваша проблема не имеет ничего общего с вашим выбором структуры данных, но вместо этого, потому что вы изменяете List, пока вы зацикливаетесь на этом .

Представьте, что в вашем списке три плоскости - [P1, P2, P3].

  • На первой итерации вашего цикла i равно 0, вы обрабатываете P1
  • P1 имеет getX() < -50, поэтому вы удалите его, составив список сейчас [P2, P3]
  • На следующей итерации цикла i теперь 1, поэтому вы обрабатываете P3.
  • Это означает, что P2 никогда не обрабатывается и поэтому никогда не будет отрисован, поэтому он ненадолго исчезнет.

Попробуйте использовать Iterator, который позволит вам безопасно удалять элементы, зацикливаясь на List.

Iterator<Plane> i = planes.iterator();

while (i.hasNext()) {
  Plane p = i.next();

  if (p.getX() < -50) {
    i.remove();
  } else {
    p.onDraw(c);

    if (p.getX() < 170) {
      detectPlaneCollision(p, c);
    }
  }
}

Хотя, поскольку вас не волнует порядок, в котором вы обрабатываете свои Plane объекты, вы можете хранить их в Set, а не List. Set не нужно беспокоиться о сохранении порядка элементов при их добавлении и удалении.

0 голосов
/ 15 февраля 2012

Я думаю, что в этом коде есть ошибка.

Что если i==0 и planes[0] будут удалены?

planes[n] переместится в позицию planes[n-1].Например, planes[1] переместится в положение planes[0].

Затем i будет увеличено, поэтому i==1.

Следовательно, исходный planes[1] (который теперь planes[0])будут пропущены.

0 голосов
/ 15 февраля 2012

Если вы много удаляете и добавляете из списка, рассмотрите возможность использования LinkedList. ArrayList более подходит, если в наборе данных очень мало изменений.

Хотя вы также должны учитывать тот факт, что получение элементов из LinkedList несколько медленнее, чем из ArrayList, имейте это в виду при использовании LinkedList.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...