2012-08-16 8 views
2

내가 만들고있는 게임에서지도 세그먼트 (클러스터)를 잡기 위해 들쭉날쭉 한 배열을 사용하고 있습니다. 배열의 위치는지도의 클러스터 위치에 해당합니다. 또한 내부 배열 (들쭉날쭉 한 부분)에 더 이상 클러스터가로드되지 않은 경우 (사용되지 않은 시간 초과 후 클러스터가 배열에서 제거됨) 외부 배열의 요소가 null로 다시 설정되어지도의 메모리 사용량을 유지합니다. 하위. 게임 맵에서 클러스터를 얻기 위해 시도 할 때C# jagged array 버그 (요소가 항상 설정되지는 않음)

이 문제는 무작위로 겉으로 발생 :

getCluster(int, int) 방법은 거의 모든 IT를 검색하기 전에 클러스터를 확인해야하는 loadCluster(int, int) 방법은 배열에로드
public Cluster getCluster(int xIndex, int yIndex) 
{ 
    lock (xAxis) 
    { 
     loadCluster(xIndex, yIndex); 
     return xAxis[xIndex][yIndex]; 
    } 
} 

public void loadCluster(int xIndex, int yIndex) 
{ 
    lock (xAxis) 
    { 
     if (xAxis[xIndex] == null) 
      xAxis[xIndex] = new Cluster[(int)worldSize.Y]; 
     if (xAxis[xIndex][yIndex] == null) 
      xAxis[xIndex][yIndex] = new Cluster(this, new Vector2(xIndex * 256, yIndex * 256), worldLoader.loadClusterData(xIndex, yIndex)); 
    } 
} 

때로는 loadCluster(int, int)이 클러스터를 추가하는 데 실패합니다.

특정 클러스터에서는 발생하지 않지만 내부 배열이 추가되지 않은 경우 항상 발생합니다 (그러나 대부분의 경우 내부 배열을 전혀 만들지 않습니다). 또한 Visual Studio가 계속되는 null 포인터 예외를 잡으면 loadCluster(int, int)을 다시 스테핑하여 다시 호출하면 (적어도 지금까지는) 정상적으로 작동합니다. 에 대한 추가 호출을 getCluster(int, int) 메서드에 추가하면이 버그의 빈도도 크게 줄어 듭니다.

정직하게도이 기능이 작동하지 않는 이유는 무엇입니까? 클러스터가 현재 사용중인 경우 x 축이 [] []

public override void Update(GameTime gameTime) 
{ 
    for (int x = 0; x < worldSize.X; x++) 
    { 
     if (xAxis[x] == null) continue; 
     int loaded = 0; 
     for (int y = 0; y < worldSize.Y; y++) 
     { 
      if (xAxis[x][y] == null) 
      { 
       continue; 
      } 
      xAxis[x][y].Update(gameTime); 

      if (xAxis[x][y].clusterLoaded) 
      { 
       loaded++; 
      } 
      else if (xAxis[x][y].clusterTimer == 0) 
      { 
       xAxis[x][y] = null; 
      } 
     } 

     if(loaded == 0) xAxis[x] = null; 
    } 
} 

Cluster.clusterLoaded는 부울 보여주는 편집 기타 코드 : 어떤 도움이 많이

편집을 감상 할 수있다. Cluster.clusterTimerclusterLoaded이 거짓이되면 카운트 다운되는 int입니다. clusterLoaded이 다시 참이면 최대 값으로 재설정됩니다. Cluster.Update(GameTime)이 실행될 때마다 1 씩 감소되고 clusterLoaded은 false입니다. loaded은 현재 내부 배열의 얼마나 많은 클러스터가로드되었는지 계산하는 데 사용됩니다.

+0

(int) worldSize.Y> yIndex를 보장하는 코드는 없습니다. 그런 주장을 추가하십시오, 그래서 그 경우에 깨지십시오. – Artak

+0

배열을 변경하는 모든 코드 (정리에서 제거되는 비트 포함)를 게시 할 수 있습니까? –

+0

잘 보였지만 코드의 다른 부분은 yIndex가 결코 worldSize.Y보다 크지 않도록합니다. 비록 내가 수표를 넣을지라도. 어쨌든, xIndex와 yIndex가 배열의 제한 범위 내에있을 때에도 버그가 발생합니다. – Kalia

답변

3

여기서 가장 먼저 변경해야 할 것은 loadCluster 메소드를 수정하여 xAxis [xIndex] [yIndex] 값을 바로 반환하는 것입니다. 그러면 getCluster 메소드를 잠글 필요가 없습니다. 코드의 다른 섹션은 무엇입니까 - 설명에서 멀티 스레드 문제 인 것처럼 보입니다. xAxis 변수에 고정되어 있지만 다른 곳에서 무엇을하는지는 알지 못합니다. 언어의 또 하나의 포인트 어레이는 핵심 기능이므로 버그가 있다는 것은 예상치 못한 일입니다.

+0

loadCluster는로드 만하고 아무것도 리턴하지 않는 것은 의도적 인 것이므로 개인/보호 된 상태로 만들 것입니다. 그러나 멀티 스레딩 포인트는 흥미 롭습니다. 라이브 미니 맵을 생성하고 간섭을 일으킬 수있는 BackgroundWorker가 있습니다. 나는 그것에게 약간 시험을 줄 것이다. – Kalia

+0

아하. 그것은 정말로 스레딩 문제로 보입니다. BackgroundWorker를 비활성화하면 오류가 발생하지 않습니다. 나는 또한 문제의 근원을 찾을 수 있었다.Update 메서드 주위에 자물쇠를 두지 않았으므로 BackgroundWorker가 그곳을 망칠 수 있어야합니다. 많은 감사합니다! – Kalia

+0

당신은 천만에요. 기쁜 데 도움이되었습니다. – Artak