애니메이션은 여전히 논리와 렌더링간에 완벽하게 분리 될 수 있습니다. 애니메이션의 추상 데이터 상태는 그래픽 API가 애니메이션을 렌더링하는 데 필요한 정보입니다.
예를 들어, 2D 게임에서, 그려야 할 스프라이트 시트의 현재 부분을 표시하는 영역을 표시하는 사각형 영역 일 수 있습니다 (시트로 구성된 시트가있는 경우 캐릭터의 다양한 단계를 포함하는 80x80 30 개의 그림을 말할 수 있습니다) 점프, 앉기, 이동 등). 또한 렌더링에 필요하지 않은 모든 종류의 데이터 일 수 있지만 현재 애니메이션 단계가 만료 될 때까지 남은 시간 또는 애니메이션 이름 ( "walking", "standing")과 같은 애니메이션 상태 자체를 관리하기위한 것일 수도 있습니다. 등) 모든 것을 원하는 방식으로 표현할 수 있습니다. 그것이 논리 부분입니다.
렌더링 부분에서는 평소와 같이 모델에서 사각형을 가져오고 렌더러를 사용하여 실제로 그래픽 API를 호출합니다.
코드에서 (여기에서 C ++ 구문 사용) :
class Sprite //Model
{
private:
Rectangle subrect;
Vector2f position;
//etc.
public:
Rectangle GetSubrect()
{
return subrect;
}
//etc.
};
class AnimatedSprite : public Sprite, public Updatable //arbitrary interface for classes that need to change their state on a regular basis
{
AnimationController animation_controller;
//etc.
public:
void Update()
{
animation_controller.Update(); //Good OOP design ;) It will take control of changing animations in time etc. for you
this.SetSubrect(animation_controller.GetCurrentAnimation().GetRect());
}
//etc.
};
그것이 데이터입니다. 렌더러가 해당 데이터를 가져 와서 그립니다. 일반 스프라이트와 애니메이션 된 스프라이트 모두 같은 방식으로 그려 지므로 여기에서 다형성을 사용할 수 있습니다!
class Renderer
{
//etc.
public:
void Draw(const Sprite &spr)
{
graphics_api_pointer->Draw(spr.GetAllTheDataThatINeed());
}
};
TMV :
다른 예를 생각해 냈습니다. RPG가 있다고 가정하십시오. 예를 들어, 세계지도를 나타내는 모델은 세계에서 캐릭터의 위치를지도의 타일 좌표로 저장해야 할 수 있습니다. 그러나 캐릭터를 움직이면 한 번에 몇 픽셀 씩 다음 정사각형으로 이동합니다. 이 "타일 사이"위치를 애니메이션 오브젝트에 저장합니까? 캐릭터가 맵의 다음 타일 좌표에서 "도착"했을 때 모델을 어떻게 업데이트합니까?
월드 맵은 플레이어 위치를 직접 알지 못합니다 (Vector2f 또는 플레이어 위치를 직접 저장하는 것과 같은 것은 없지만 대신 플레이어 객체 자체에 대한 직접 참조가 있으며, 이는 AnimatedSprite에서 파생됩니다) 렌더러에 쉽게 전달하고 필요한 모든 데이터를 가져올 수 있습니다.
일반적으로 타일 맵이 모든 것을 할 수는 없습니다. 모든 타일 관리를 담당하는 "TileMap"클래스가 있으며, 아마도 내가 넘겨 준 객체 사이의 충돌 감지를 수행 할 수도 있습니다. 지도의 타일 그런 다음 다른 "RPGMap"클래스를 사용하거나 타일 맵과 플레이어에 대한 참조가 있고 플레이어와 플레이어에 대한 실제 Update () 호출을 모두 호출하고 싶습니다. 타일 맵.
플레이어가 움직일 때 모델을 업데이트하는 방법은 수행하려는 작업에 따라 다릅니다.
플레이어가 타일 사이를 독립적으로 이동할 수 있습니까 (젤다 스타일)? 입력을 처리하고 모든 프레임에 따라 플레이어를 이동하십시오. 아니면 플레이어가 "오른쪽"을 누르기를 원하고 캐릭터가 자동으로 타일 하나를 오른쪽으로 이동 하시겠습니까? RPGMap 클래스가 플레이어가 목적지에 도착할 때까지 플레이어 위치를 보간하고 그 동안 모든 이동 키 입력 처리를 잠그십시오.
어느 쪽이든, 더 쉽게 만들고 싶다면 변수의 값을 변경하는 대신 실제로 자신을 업데이트하는 논리가 필요한 경우 모든 모델에 Update () 메서드가 있습니다-컨트롤러를 포기하지 않습니다 그런 식으로 MVC 패턴에서 코드를 "한 단계 위"(컨트롤러)에서 모델로 이동하면 컨트롤러는 모델의 Update () 메소드를 호출합니다 (이 경우 컨트롤러는 RPGMap). 로직 코드를 쉽게 바꿀 수 있습니다. 클래스의 코드를 직접 변경하거나 완전히 다른 동작이 필요한 경우 모델 클래스에서 파생하여 Update () 메서드 만 재정의 할 수 있습니다.
이 접근법은 메소드 호출과 그와 같은 것들을 줄입니다-순수한 MVC 패턴의 주요 단점 중 하나였습니다 (GetThis () GetThat ()을 매우 자주 호출하게 됨)-코드를 더 길고 읽기가 어렵고 속도가 느려집니다. 컴파일러가 그런 것들을 많이 최적화하면 처리 할 수 있습니다.