자신만의 예정된 일을 추구하면서 자신의 환경을 감지하고, 시간에 따라 그러한 환경에 작용하며, 그래서 미래에 감지할 것에 영향을 미치는, 그러한 환경 안에 또는 그 일부분으로 위치하고 있는 시스템을 말한다.
이러한 시스템으로 움직이는 에이전트는 다음과 같은 계층 구조를 가진다.
액션, 선택조종(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 |
댓글 없음:
댓글 쓰기