2012-04-14 2 views
2

농경/타워 방어 게임을 만드는 중이며 프로그래밍 할 때 매우 익숙합니다. 나는리스트를 사용하는데 큰 문제가있는 것 같다. <> 또는 XNA의 배열. 목록에서 원하는 색인을 반환 할 수 없습니다.C# 목록 및 ArgumentOutOfRangeException 문제

주요 질문은 내 심기 엔진 내부입니다. 필자는 다양한 속성을 가진 식물 목록 (spriteobjects)을 생성하여지도에 배치 할 수있는 식목 시스템을 성공적으로 구현했습니다. 이제는 그 공장에서 마우스 클릭을 기반으로 공장 목록의 특정 공장에 액세스 할 수있는 방법이 필요합니다. 나는 아주 가까이에있는 것처럼 느껴진다. 그러나 나는 해결할 수없는 ArgumentOutOfRangeException으로 끝났다.

초기화

public void Addplants() 
     { 
      switch (Mode) 
      { 
      case "Wotalemon": 
      NewPlant = new Plant(Texture, msRect); 
      NewPlant.AddAnimation("seed", 0, 16, 64, 64, 1, 0.1f); 
      NewPlant.AddAnimation("sprout", 64, 16, 64, 64, 1, 0.1f); 
      NewPlant.AddAnimation("wota", 128, 16, 64, 64, 1, 1.0f); 
      NewPlant.CurrentAnimation = "seed"; 
      NewPlant.DrawOffset = new Vector2(32, 48); 
      NewPlant.Position = Position; 
      NewPlant.Type = "wotalemon"; 
      NewPlant.Birthday = Days; 
      NewPlant.IsSelected = false; 
      plants.Add(NewPlant); 
      thisPlant = NewPlant; 
      //various plants after this 

업데이트/

나는 몇 가지 간단한 foreach는 여기에, 아무런 문제를 업데이트하지 않고 식물을 그리는 루프 사용 그리기 : 여기에 코드의 연습이다.

GetInfo를 최종적

public void GetInfo(Rectangle ms) 
     { 
      msRect = ms; 
      for (int i = 0; i < plants.Count; i++) 
      { 
       foreach (Plant NewPlant in plants) 
       { 
        if (NewPlant.BoundingBox.Intersects(msRect)) 
        { 
         SelectedIndex = i; 
         NewPlant.Tint = Color.Black; 
        } 
        else 
         NewPlant.Tint = Color.White; 
       } 

      } 
     } 

(이 방법은 spriteobject의 hitbox에서 속성과 mouseRectangle 사용), 여기서 문제이다

public void SelectPlant() 
     { 
      //if (SelectedIndex != null) 
      if (SelectedIndex > plants.Count | SelectedIndex < 0) 
       SelectedIndex = plants.Count; 
      SelectedPlant = plants[SelectedIndex]; 

     } 

예외가이 라인에 발생된다

SelectedPlant = plants[SelectedIndex]; 

디버거는 값을 0으로 표시합니다. 미리 시도하기 위해 다양한 방법을 시도했습니다 인덱스가 null이되도록 환기 시키십시오. Getinfo() 메서드에서 뭔가 중요한 것이 여기에 있습니다. 나는 내가 거기에 삽입 한 컬러 테스트가 완벽하게 작동하기 때문에 나는 성공에 매우 가깝다고 확신한다. 내가 마우스를 올려 놓으면 식물이 검은 색으로 변하고 마우스를 제거하면 정상으로 돌아옵니다.

이것은 정확히 에 마우스를 올려 놓고있는 식물의 색인에 selectedIndex를 설정하려는 경우를 제외하고 원하는 행동 유형입니다. 모든 조언을 크게 주시면 감사하겠습니다.

+0

if 문,'selectedIndex의 = plants.Count,'해야'의해 selectedIndex = plants.Count-1;' – asawyer

답변

2

전체적인 다른 문제를 다루기 때문에이 내용을 새로운 답변으로 추가하겠습니다. 이 코드를 살펴보면 :

msRect = ms; 
for (int i = 0; i < plants.Count; i++) 
{ 
    foreach (Plant NewPlant in plants) // <-- this is redundant 
    { 
     if (NewPlant.BoundingBox.Intersects(msRect)) 
     { 
      SelectedIndex = i; 
      NewPlant.Tint = Color.Black; 
     } 
     else 
      NewPlant.Tint = Color.White; 
    } 

} 

'식물'을 서로 두 번 반복합니다. 인덱스 (for (int i = 0 ...)를 사용한 다음 반복기 (foreach (Plant NewPlant ...)를 사용하여 다시 그 인덱스를 사용합니다.

msRect = ms; 
for (int i = 0; i < plants.Count; i++) 
{ 
    Plant NewPlant = plants[i]; 
    if (NewPlant.BoundingBox.Intersects(msRect)) 
    { 
     SelectedIndex = i; 
     NewPlant.Tint = Color.Black; 
    } 
    else 
     NewPlant.Tint = Color.White; 
} 

또는 같은 일 및 단락 처음에 SelectPlant()와 selectedIndex의 필요성을 수행

옵션은 다음 중 하나의 루프를 사용하여 올바른 인덱스를 설정하는 GetInfo을 변경할 수 있습니다 :

msRect = ms; 
foreach (Plant NewPlant in plants) // no need for indexes 
{ 
    if (NewPlant.BoundingBox.Intersects(msRect)) 
    { 
     SelectedPlant = NewPlant; // this is everything you need 
     NewPlant.Tint = Color.Black; 
    } 
    else 
     NewPlant.Tint = Color.White; 
} 

당신은 그러나이 논리를 캡처 할 SelectedPlant 같은 '글로벌'변수를 사용하여 조심해야 할 필요가 없습니다. 전체 GetInfo 방법을 으로 변경하면 SelectedPlant을 직접 수정하지 말고 선택한 식물을으로 반환하는 것이 좋습니다. 즉, void이 아닌 Plant을 반환하는 메서드 서명을 변경하고 위의 코드에서 SelectPlant = NewPlantreturn NewPlant으로 변경합니다. 아니면 하나의 라인으로 심지어 더 재미 : 입력

return plants.Where(p => p.BoundingBox.Intersects(ms)) 
+0

아주 심오한 답에 감사합니다. 비효율적 인 코드가 얼마나 비현실적인지 알지 못했지만, 새로운 코드 일 때 예상되는 것 같습니다. – user1332755

+0

문제가 없습니다. 아마도 이것을 upvote 또는 그것을 받아들일까요? – yamen

6

먼저 ||을 적절하게 만들고 >= plants.Count을 확인하십시오. 목록의 색인은 0입니다. 그런 다음 제안 된대로 개수 - 1로 설정하십시오.

+1

@OP가 : 당신이 원하는 만들 SelectedIndex를 plans.Count - 1 _even 일 때 원래의 SelectedIndex <0 (대체 값은 0으로 설정) –

+0

고마워. 그러나 이것은 여전히 ​​내 주요 문제를 해결하지 못합니다. GetInfo() 메서드는 여전히 동적 식물 인덱스를 반환하지 않습니다. 내가 심은 마지막 식물에 대한 지수 만 반환합니다. 누구든지 목록 색인을 마우스 위로 놓거나 목록에서 개체를 클릭하는 좋은 방법을 알고 있습니까? – user1332755