2016년 5월 22일 일요일

게임 인공지능 Chap.03 자동적으로 움직이는 게임 에이전트 생성법 - 1

자동적 에이전트란??

자신만의 예정된 일을 추구하면서 자신의 환경을 감지하고, 시간에 따라 그러한 환경에 작용하며, 그래서 미래에 감지할 것에 영향을 미치는, 그러한 환경 안에 또는 그 일부분으로 위치하고 있는 시스템을 말한다.

이러한 시스템으로 움직이는 에이전트는 다음과 같은 계층 구조를 가진다.
액션, 선택조종(steering), 이동력(locomotion) 이러한 속성을 띤 움직임을 가지는데 
책에서는 이런 다양한 타입의 행동을 하는 기본적인 운반기의 모델을 제시하고있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class MovingEntity : public BaseGameEntity{
protected:
  
  Vector2D    m_vVelocity;
  
  //개체가 향하는 방향을 가르키는 정규화된 벡터
  Vector2D    m_vHeading;
  //방향 벡터에 대해서 수직인 벡터
  Vector2D    m_vSide; 
  double       m_dMass;
  
  //개체의 최대 속도
  double       m_dMaxSpeed;
  //개체가 자신을 움직이기위해서 낼수있는 최대의 힘
  //로켓의 추진력이라고 생각하자
  double        m_dMaxForce;
  
  //가능한 최대 회전비율 (rad / s)        
  double       m_dMaxTurnRate;
// 나머지 생략
}
cs
이러한 속성값들을 가지고 있다.

이제 객체가 다양한 조종 행동에 접근할 수 있도록 하는 Vehicle클래스를 보자
1
2
3
4
5
6
7
8
9
10
11
12
class Vehicle : public MovingEntity{
private:
  //운반기가 통로, 벽, 에이전트 데이터에 접근할수있게 해주는
  //월드데이터를 가리키는 포인터
  GameWorld*            m_pWorld;
  //조종 행동들의 클래스
  SteeringBehavior*     m_pSteering;
// 생략
}
cs
이런식으로 자기의 조종행동 클래스에 접근할 수있게 해준다.

이걸 UML 도표로 보면
이런 그림이 나온다, 그림을 간단히 요약을 하면
Vehicle이 나머지 것을에서 정보를 받아와서 GameWorld에서 구현이 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void Vehicle::Update(double time_elapsed)
{    
  //시간의 경과
  m_dTimeElapsed = time_elapsed;
 
  //옛날 위치를 기록해뒀다가 나중에 업데이트 할수있다.
  Vector2D OldPos = Pos();
 
  Vector2D SteeringForce;
 
  //운반기 리스트에 있는 각각의 조종행동 으로부터 조합된 힘을 계산
  SteeringForce = m_pSteering->Calculate();
    
  //가속도 = 힘/질량
  Vector2D acceleration = SteeringForce / m_dMass;
 
  //속도를 갱신한다.
  m_vVelocity += acceleration * time_elapsed; 
 
  //운반기가 최대속도를 안넘도록 한다.
  m_vVelocity.Truncate(m_dMaxSpeed);
 
  //위치를 갱신한다.
  m_vPos += m_vVelocity * time_elapsed;
 
  //매 단계마다 지역좌표계가 갱신이 되어야 하는데 
  //운반기의 방향은 항상 자신의 속도에 따라서 정렬한다.    
  //운반기의 속도가 보기값보다 크다면 방향을 갱신한다.
  if (m_vVelocity.LengthSq() > 0.00000001)
  {    
    m_vHeading = Vec2DNormalize(m_vVelocity);
 
    m_vSide = m_vHeading.Perp();
  }
  //스크린을 환상체(toroid)로 간주한다.
  WrapAround(m_vPos, m_pWorld->cxClient(), m_pWorld->cyClient());
 
cs
운반기의 여러가지 물리적 역할을 갱신해준다(가속도, 방향, 위치확인)






댓글 없음:

댓글 쓰기