Upload
young-ha-kim
View
573
Download
8
Embed Size (px)
DESCRIPTION
Game Design patterns, Visitor, State, FSM pattern NHN Next Game Dev project study materials
Citation preview
디자인패턴스터디VISITOR, STATE, FINITE STATE MACHINE
VISITOR PATTERN
VISITOR PATTERN 언제쓰는가
• 의도: 클래스를변경하지않고새로운작업을정의하는방법
• 서로다른 object 들이모여있는배열, 트리, 또는맵과같은집합이있는데
• 각 object에대해서수행할작업이존재한다.
• 하지만각 object 내에서해당작업에대한코드를넣고싶지않을때
• 그렇다고각 object의 type을식별해서 casting 하고싶지않을때
• VISITOR PATTERN이 구현된코드를통해서살펴보겠습니다
VISITOR PATTERN 구조
VISITOR PATTERN 구현예제
• ELEMENT 추상클래스• 자연의원소(element)들을이용한 skill을가지고게임을한다고가정한다• 원소는 Water, Fire, Air가있다고하자
• WATER, FIRE, AIR 클래스는 ELEMENT를상속받음
• VISITOR 추상클래스• Water, Fire, Air에대해서 visit() 함수를구현할수있도록 virtual 함수선언
• GET_SKILL_VISITOR 클래스 (VISITOR 상속)• 각 Element를획득했을때실행될함수들을구현
• LOSE_SKILL_VISITOR 클래스 (VISITOR 상속)• 각 Element를잃었을때실행될함수들을구현
ELEMENT 추상클래스
// ELEMENT 추상클래스
class Element
{
public:
virtual void Accept(Visitor& v) = 0; // 자식들이 Visitor를받을수있도록
virtual void ToString() = 0; // 이건그냥화면에보여주기위함
};
ELEMENT 구현클래스들
class Water : public Element
{
public:
void Accept(Visitor &v) { v.visit(this); }
void ToString() { printf_s("Water\n"); }
};
class Fire : public Element
{
public:
void Accept(Visitor& v) { v.visit(this); }
void ToString() { printf_s("Fire\n"); }
};
class Air : public Element
{
public:
void Accept(Visitor& v) { v.visit(this); }
void ToString() { printf_s("Air\n"); }
};
VISITOR 추상클래스
class Visitor
{
public: // 입력받을각클래스에따라서함수선언
virtual void visit(class Water* element) = 0;
virtual void visit(class Fire* element) = 0;
virtual void visit(class Air* element) = 0;
};
VISITOR 구현클래스들
class GetSkill_Visitor : public Visitor {
virtual void visit(Water* element) {
printf_s("GetSkill ");
element->ToString();
}
virtual void visit(Fire* element) {
printf_s("GetSkill ");
element->ToString();
}
virtual void visit(Air* element) {
printf_s("GetSkill ");
element->ToString();
}
};
class LoseSkill_Visitor : public Visitor {
virtual void visit(Water* element) {
printf_s("LoseSkill ");
element->ToString();
}
virtual void visit(Fire* element) {
printf_s("LoseSkill ");
element->ToString();
}
virtual void visit(Air* element) {
printf_s("LoseSkill ");
element->ToString();
}
};
MAIN 함수
Element *elementArr[] = {
new Water(), new Air(), new Fire() // 각클래스생성, 배열에넣기
};
GetSkill_Visitor getSkill; // VISITOR 생성
LoseSkill_Visitor loseSkill; // VISITOR 생성
for (int i = 0; i < 3; i++)
elementArr[i]->Accept(getSkill); // GetSkill VISITOR를배열의각원소에실행
for (int i = 0; i < 3; i++)
elementArr[i]->Accept(loseSkill); // LoseSkill VISITOR를배열의각원소에실행
실행결과
VISITOR PATTERN 장단점
• 단점:
• 새로운클래스를추가할때마다, VISITOR 클래스마다 METHOD를추가해야한다
• 클래스설계전에 VISITOR 패턴의사용을염두에두고만들어야한다
• 이미만들어진코드에적용하면복잡해질수있다
• 장점:
• 클래스마다인터페이스가다를때, 각클래스로부터데이터얻는법을캡슐화할수있음
• 현재코드가없거나코드를변경할수없는클래스에대한기능을추가할수있다
• 서로관련이있는작업들을하나의클래스로묶을수있다
• 서로관련이없는클래스들로부터데이터를모아서처리할수있게한다
STATE PATTERN
STATE PATTERN 언제쓰는가
• 의도: state가변하면 object의동작이변하도록. 마치다른클래스처럼동작하도록
• 구현방법:
• Wrapper 클래스를만들어서외부에는단일인터페이스를노출시킨다
• State 추상클래스정의
• State 추상클래스를상속받아서각 state를정의및구현한다
• 현재 state에대한 pointer를 context 클래스에서유지한다
• State를바꾸기위해서는 state pointer를바꾼다
STATE PATTERN 구조
STATE PATTERN 구현예제
• Player 클래스는현재 state (super, normal)에따라서공격력과방어력이달라짐
• Player가 state를가리키는 wrapper 클래스이며,
• 각 state별로 attack와 defend 함수들이다르게작동하도록만듬
PLAYER 클래스
class Player
{
public:
void SetCurrent(State* s)
{
m_Current = s;
}
void Attack() { m_Current->Attack(); }
void Defend() { m_Current->Defend(); }
private:
class State* m_Current;
};
STATE 추상클래스
class State
{
public:
virtual void Attack() = 0;
virtual void Defend() = 0;
};
STATE의구현클래스들
class SuperMode : public State
{
public:
void Attack() {
printf_s(“2x damage!!\n");
}
void Defend() {
printf_s("Armor 2x!\n");
}
};
class NormalMode : public State
{
public:
void Attack() {
printf_s(“1x damage...\n");
}
void Defend() {
printf_s("Armor none...\n");
}
};
MAIN 함수
Player myPlayer;
SuperMode superMode;
myPlayer.SetCurrent(&superMode); // 슈퍼모드르 state 세팅
myPlayer.Attack();
myPlayer.Defend();
NormalMode normalMode;
myPlayer.SetCurrent(&normalMode); // 보통모드로 state 변경
myPlayer.Attack();
myPlayer.Defend();
출력결과
FINITE STATE MACHINE
FSM이왜필요?
• 액션게임을만들었다고하자
• 플레이는방향키를밑으로누르면앉을수도있고 (duck),
• B를누르면띌수도있다고하자.
• 그리고띄는중에방향키를밑으로누르면다이빙한다고하자
• 이를그림으로나타내면좌측과같다
FINITE STATE MACHINE 개념
• Fixed set of states
• Machine이가질수있는상태의집합은유한하다 (즉, 가능한상태들이정해져있다)
• 앞의액션게임예제에는, standing, ducking, jumping, diving이다
• 항상하나의 state에있어야함• 동시에 jumping과 diving을할수없다. State 중복을막는것이 FSM 사용이유
• Input 또는 event를 FSM 에게보낸다
• Input에따라서 state가변할수있다 (transitions)
FINITE STATE MACHINE 장단점
• 장점• 제한된상태를적용함으로써복잡한코드를간단하게만든다
• 단점• 하나의상태로모든것을관리하기어렵다
• Concurrent state machines 등활용
FINITE STATE MACHINE 구현
• 앞의 State와비슷한데, 차이점은• State 사이의전환은 State 클래스자체적으로한다
• FSM에게 Input또는 Event를입력하면 FSM이 State전환을한다