2011-01-14 4 views
0

나는 그 팀이 인수에 전달되는 위치를 볼 수 있다면 내 FogOfWar 클래스에 다음 함수, 그것은 계산이 :전쟁의 안개를 계산하는 가장 빠른 방법은 무엇입니까?

내 문제가
package mwoke { 
    public class FogOfWar { 
     public var game:Game; 
     public var team:int; 
     private var cache:Vector.<CachePos> = new Vector.<CachePos>(); 
     private var chars:Vector.<Character> = new Vector.<Character>(); 

     public function FogOfWar($game:Game, $team:int) { 
      game = $game; 
      team = $team; 
     } 

     public function think():void { 
      cache.length = 0; 
      chars.length = 0; 

      var ent:Character; 
      for(var i:int = 0; i < game.entities.length;++i) { 
       if(game.entities[i] == null) continue; 
       if(!(game.entities[i] is Character)) continue; 
       ent = Character(game.entities[i]); 
       if(ent.team != team) continue; 
       if(ent.vision <= 0.0) continue; 
       chars.push(ent); 
      } 
     } 

     public function canSee(x:Number, y:Number):Boolean { 
      if(x < game.minX) return false; 
      if(y < game.minY) return false; 
      if(x >= game.maxX) return false; 
      if(y >= game.maxY) return false; 

      for each(var v:CachePos in cache) { 
       if(v.x == x && v.y == y) { 
        return v.result; 
       } 
      } 
      var res:Boolean = false; 

      for each(var ent:Character in chars) { 
       if(Game.distance(x, y, ent.x, ent.y) < ent.vision) { 
        res = true; 
        break; 
       } 
      } 

      var tmp:CachePos = new CachePos(); 
      tmp.x = x; 
      tmp.y = y; 
      tmp.result = res; 
      cache.push(tmp); 
      return res; 
     } 
    } 
} 
internal class CachePos { 
    public var x:Number; 
    public var y:Number; 
    public var result:Boolean; 
} 

, 그, 그것을 할 수있는 게임 만 3 문자 초당 4000 번만 실행하면 그리 그리 크지 않습니다.

캐시를 구현할 수 있으므로 가장 일반적인 위치를 캐시하지만 최적화를 위해 수행 할 수있는 작업은 무엇입니까?

+0

Game.distance 방법은 어떨까요? 충분히 빠릅니까? – vulkanino

+0

그것은'Math.sqrt ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))''이고 옵티마이 저를 사용하여 인라인됩니다. –

+0

모든 문자를 벡터이므로 모든 엔티티를 반복 할 필요가 없습니다. –

답변

2

캐릭터의보기 반경이있는 경우지도의 어느 부분이 표시되는지 알려주는 친숙한 문자가 이동하면서 업데이트되는 데이터 구조를 유지 관리 할 수 ​​있습니다.

그런 다음지도에서 해당 위치의 데이터 구조 값을 확인하는 것과 같이 빠르게 볼 수 있는지 확인합니다.

편집 : 당신은 또한 (다소 비싼) Math.sqrt 함수에 대한 호출을 방지 제곱 거리 대신 절대 거리를 사용할 수

. 기본적으로 Game.DistanceSquared < entity.VisionDistanceSquared 수표를 만드십시오.

+0

음, 그러면 모든 프레임을 모든 프레임으로 생성해야 할 것입니다. –

+0

글쎄요, 새로운 아이디어는 훌륭합니다. 구현할 것입니다. –

0

캐릭터 위치 및 반경을 나타내는 객체 목록을 스프라이트의 표시 항목으로 유지하는 방법 (표시 목록에 포함되지 않음), 누군가가 움직일 때마다 원이 문자 또는 중간 클래스에 의해 업데이트됩니다 . 그렇게하면 매번 루프를 계속 진행할 필요가 없습니다.

점이 FOW 내에 있는지 확인하려는 경우 모든 원으로 스프라이트에 히트 테스트를 수행 할 수 있습니다. 추가 이점은 FOW를 그리기 위해 데이터를 사용할 수도 있다는 것입니다.

주의 사항; 나는 내부 함수를 사용하는 것이 더 빠르다는 것을 안다. (히트 테스트와 같이) 테스트하지 않았기 때문에 더 잘 작동하지 않을 수도있다. 이것을 사용하는 트릭은 표시 목록에 포함시키지 않는 것입니다. 일단 표시 목록에 fow 스프라이트를 추가하면 성능이 저하됩니다.

관련 문제