2013년 9월 15일 일요일

코로나로 구현한 타겟을 추종하는 알고리듬

  아래 그림 (... 대충 그렸습니다. )으로 설명하겠습니다.


현재 프레임에서의 미사일 좌표와 각도를 각각 x_m[k], y_m[k], theta_m[k] 라고 하겠습니다. [k]는 현재 프레임을 나타내는 시간 인덱스입니다. 이 미사일의 타겟은 현재 화면 상의 적들 중에서 임의로 하나 잡습니다. 미사일이 추종해야 할 적의 좌표는 x_t[k], y_t[k] 라고 쓰겠습니다. 이제 매 프레임마다 다음과 같은 연산을 수행합니다.
  적좌표에서 미사일의 좌표를 빼면 미사일이 향해야 할 방향벡터가 나옵니다

          dxt = x_t[k] - x_m[k]
          dyt = y_t[k] - y_m[k]

이것의 단위벡터(크기가 1인 벡터)를 계산합니다. 이것은 벡터의 크기로 각 요소를 나눠주면 됩니다. . 단위벡터를 계산하는 이유는 적과의 거리와 상관 없이 내 미사일은 동일한 속도로 움직여야하기 때문입니다.

          dist = math.sqrt ( dxt*dxt + dyt*dyt )
          dxt = dxt/dist
          dyt = dyt/dist

이제 미사일의 좌표의 실제 증분값은 다음과 같이 계산합니다. 다음의 방정식이 미사일이 부드럽게 움직이도록하는데 중요한 역할을 합니다.

          dx[k] = a * dx[k-1] + (1-a) * dxt
          dy[k] = a * dy[k-1] + (1-a) * dyt

여기서 상수 a 는 0과 1사이의 값이고 0에 가까울수록 추종하는 속도가 더 빨라지고 1에 가까운 값이면 천천히 추종하게 됩니다. 그리고 dx[k-1]과 dy[k-1]은 직전 프레임에서의 dx, dy값입니다. (이것을 차분방정식이라도 합니다. 미분방정식과 유사한 개념입니다.) 이 좌표로부터 미사일이 향할 각도도 계산됩니다.
  최종적으로 미사일의 좌표와 각도는 다음과 같이 매프레임마다 갱신됩니다.

          x_m[k] = x_m[k-1] + dx[k]*vel
          y_m[k] = y_m[k-1] + dy[k]*vel
          theta_m[k] = atan2(dy[k], dx[k])*_r2d + 90

여기서 vel은 미사일의 직선 속도값이고 _r2d 변수는 라디안을 도로 바꿔주는 수(_r2d = 180/3.141592)입니다. vel 값이 크면 미사일의 직선속도가 빠르게 되고 작으면 느리게 됩니다.

아래는 실제로 미사일의 update()함수에 사용된 코드의 일부분입니다. bb변수가 미사일 객체입니다.


  위에서 소개한 간단한 차분방정식은 여러 경우에 응용될 수 있습니다. 제 게임의 예를 들면 옵션기기가 본체와 약간 시차를 두고 따라온다던지 또는 최종보스가 나를 향해서 천천히 회전한다든지 하는데 사용되었습니다.


  여러분들도 한 번 적용해 보시기 바랍니다.

댓글 없음:

댓글 쓰기