2013-11-24 3 views
1

그래서 좀비 시뮬레이션 게임을 만들고 있습니다. 내가 가지고있는 것은이 시점에서 무작위로 뛰어 다니는 수많은 플레이어와 좀비 다. 생존자가 좀비와 충돌 할 때 생존자를 제거하고 좀비로 바꾸기를 원하지만 본질적으로 좀비로 변하게합니다.엔티티를 제거하고 그 자리에 새 엔티티를 추가하십시오.

충돌 감지가 잘 작동합니다 (필자는 intersect 메서드로 awt 사각형을 사용하고 있습니다). 그러나 나는 좀비의 배열 목록과 생존자의 배열 목록을 가지고 있습니다. 충돌이 발생하면 좀비 목록에 좀비를 추가합니다. 그런 다음 그 목록에서 생존자를 제거합니다. 몇 시간 동안 작동 한 다음 무작위로 범위를 벗어나는 인덱스 예외를 throw합니다.

java.lang.IndexOutOfBoundsException: Index: 13, Size: 13 
    at java.util.ArrayList.rangeCheck(Unknown Source) 
    at java.util.ArrayList.remove(Unknown Source) 
    at com.caveragestudios.zombiesim.World.update(World.java:53) 
    at com.caveragestudios.zombiesim.Main.update(Main.java:93) 
    at com.caveragestudios.zombiesim.Main.run(Main.java:69) 
    at java.lang.Thread.run(Unknown Source) 

고급 for 루프, 일반 for 루프 및 while 루프가있는 반복기를 사용해 보았습니다. 아무것도 작동하는 것 같지 않습니다. 이것은 지금 내 코드입니다. 다른

for (int i = 0; i < survivors.size(); i++) { 
     Survivor s = survivors.get(i); 
     for (int ii = 0; ii < zombies.size(); ii++) { 
      Zombie z = zombies.get(ii); 
      if (z.bounds.intersects(s.bounds)) { 
       zombies.add(new Zombie(s.position, this)); 
       survivors.remove(i); 
      } 
     } 
    } 

모든 나는 그것이 종류의 망쳐 놨과 범위 예외 중 인덱스를 던졌습니다 목록을 수정하려고 할 때 그것을 그냥 제대로 작동 할 것으로 보인다. 어떤 아이디어?

답변

0

글쎄, 나는 이것을 스스로 알아낼 수 있었다. Masud에서 올바른 방향으로 밀기. 문제는 반복하면서 목록을 수정할 수는 없지만 반복기의 데이터가 여전히 필요하다는 것이 었습니다.

내가 한 일은 충돌하는 생존자들로 채워지는 두 개의 새로운 목록을 만드는 것입니다. 그런 다음 하나를 호출하여 충돌하는 좀비로 채워집니다.

그런 다음 정상적으로 반복되지만 기본 목록에서 직접 추가 및 제거하는 대신 직접 새 목록에 추가합니다. 그런 다음 반복이 완료된 후 그에 따라 새 목록을 제거하고 추가했습니다. 이것은 최종 코드입니다.

List<Survivor> toRemove = new ArrayList<Survivor>(); 
    List<Zombie> toAdd = new ArrayList<Zombie>(); 

    Iterator<Survivor> survIt = survivors.iterator(); 
    Iterator<Zombie> zombIt = zombies.iterator(); 
    while (survIt.hasNext()) { 
     Survivor s = survIt.next(); 
     while (zombIt.hasNext()) { 
      Zombie z = zombIt.next(); 
      if (z.bounds.intersects(s.bounds)){ 
       toAdd.add(new Zombie(s.position, this)); 
       toRemove.add(s); 
       System.out.println("collided"); 
      } 
     } 
    } 

    for (Survivor s : toRemove) { 
     survivors.remove(s); 
    } 

    for (Zombie z : toAdd) { 
     zombies.add(z); 
    } 
2

외부 목록 survivors 색인 i을 내부 목록 zombies에 사용했습니다. 색인 변수가 zombies.get(i)에 잘못되었습니다.


for (int i = 0; i < survivors.size(); i++) { 
    Survivor s = survivors.get(i); 
    for (int ii = 0; ii < zombies.size(); ii++) { 
     Zombie z = zombies.get(ii);// Here use ii instead of i 
     //.............. 
    } 
} 

콜렉션 사용 Iterator.remove에서 요소를 제거합니다. 컬렉션에서 안전하게 제거하려면 아래 코드를 변경하십시오.

Iterator<Survivor > survIt=survivors.iterator();  
Iterator<Zombie> zombIt=zombies.iterator(); 
while(survIt.hasNext()){ 
     Survivor s=survIt.next();  

     while(zombIt.hasNext()){ 
      Zombie z=zombIt.next(); 

      if (z.bounds.intersects(s.bounds)) { 
      zombies.add(new Zombie(s.position, this)); 

      survIt.remove(); //Use Iterator.remove. 

      }     
     } 
    } 
+0

와우 나는 그것을 놓쳤다는 것을 믿을 수 없다. 그러나 나는 그것을 바꿨고, 여러 번 일하다가 부서지지 않고 첫 번째 충돌에서 깨졌습니다. 그래서 그게 유일한 문제는 아니라고 생각합니다. – Darren

+0

Darren, Iterator.remove를 사용하여 컬렉션에서 요소를 제거하십시오. – Masudul

+0

그래도 목록에서 특정 개체를 제거 할 수 없다고 생각합니다. while (survivors.iterator(). hasNext())와 같은 것을 사용해야합니다. 그렇다면 그것은 막혀서 프로그램의 나머지 부분을 계속 진행하지 않을 것입니다. 나는 그것을 시도하고 그것이 효과가 있다고 믿지 않는다. – Darren

관련 문제