디자인패턴 8

업데이트 메서드

2022.01.31 - [이론/디자인패턴] - 게임 루프 게임 루프 게임 루프 게임 루프는 게임 시간 진행을 유저 입력, 프로세서 속도(!)와 디커플링 한다. 유저 입력은 알겠는데 프로세서 속도와 디커플링 한다는게 무슨 말일까? 굉장히 간단한 게임 루프를 보 tsyang.tistory.com 업데이트는 어떻게 게임 루프에 루프는 간략하게 다음과 같다. while(true) { processInput(); update(); render(); } update() 안에서는 게임의 개체들을 시뮬레이션한다. 그런데 어떻게? update() 안에 직접 각각의 개체들을 움직이는 코드를 작성해야 할까? 만약에 개체의 종류가 수백 가지라면? 코드가 점점 유지 보수하기 어려워질 것이다. 당연히 이런 경우 해결책은 간단하다..

타입 객체

왜 씀? 타입 객체 패턴은 다양한 '종류'를 정의할 때 컴파일이나 코드 변경 없이 새로운 타입을 추가하거나 변경할 수 있도록 해준다. 판타지 배경의 RPG 게임을 만든다고 하자. 이 게임의 몬스터는 여러 종족으로 나뉜다. 종족에 따라 최대 체력, 공격 속성 등이 달라진다. OOP 방식으로 구현 고블린, 오크, 용 등은 모두 몬스터의 일종이다. 따라서 몬스터라는 상위 클래스를 만드는 게 자연스럽다. (IS-A 관계) class Monster { public: virtual ~Monster(){} //공격 문구를 받아온다. virtual std::string attack() = 0; }; 하위 몬스터는 다음과 같이 구현될 것이다. class Goblin : public Monster { public: std..

게임 루프

게임 루프 게임 루프는 게임 시간 진행을 유저 입력, 프로세서 속도(!)와 디커플링 한다. 유저 입력은 알겠는데 프로세서 속도와 디커플링 한다는게 무슨 말일까? 굉장히 간단한 게임 루프를 보자. while(true) { processInput(); update(); render(); } processInput에서 유저의 입력을 처리하고, update에서 게임을 시뮬레이션 하고, render에서는 화면을 그린다. 당연한 얘기지만, 컴퓨터가 좋을 수록 1초에 돌릴 수 있는 루프의 횟수가 증가한다. 즉, 게임이 빨리 돌아가게 된다. 즉, 게임의 속도가 프로세서의 속도와 커플링 되어있는 것이다. https://youtu.be/r4EHjFkVw-s 144hz로 게임을 플레이하면 속도가 빨라지는 폴아웃4 어떻게 디..

이중 버퍼

왜쓰나? 여러 순차 작업의 결과를 한 번에 보여주고 싶을 때. 변경 중인 상태에 접근할 수 없게 하고 싶을 때. 코드가 변경하려는 상태를 다시 읽는 경우. 이중 버퍼를 사용하는 가장 대표적인 예는 게임 렌더링이다. class FrameBuffer { public: void clear();//픽셀을 모두 하얀색으로 채운다. void draw(int x, int y);//x,y 픽셀을 검은색으로 바꾼다. }; class Scene { public: void draw(); FrameBuffer& getBuffer(); private: FrameBuffer buffer_; }; 이처럼 FrameBuffer와 화면에 흑백 그림을 그려주는 Scene이 있다고 하자. Scene은 화면에 곰돌이 한 마리를 그린다. v..

컴포넌트 패턴

컴포넌트 패턴 컴포넌트 패턴은 한 개체가 여러 분야의 코드를 커플링 없이 다룰 수 있게 해준다. 문제 1 매 업데이트마다 인풋을 받아서 위치를 계산하고 바뀐 위치로 스프라이트를 그리는 Player 클래스가 있다고 하자. void Player::update() { //인풋으로 플레이어의 속도를 결정함. //속도를 이용해 위치를 바꿈 //옮겨진 위치로 플레이어의 스프라이트를 그림. } Player에는 앞으로 여러 기능들이 더 추가 될탠데 그때마다 update가 수정된다. 딱 봐도 코드가 더러워 질 것이라는 예감이 든다. 심지어 각 분야의 작업자들은 다른 분야의 코드를 보게된다. 2 이번에는 GameObject를 상속하는 Zone, Decoration, Prop 오브젝트가 있다고 해보자. Zone은 충돌하지만..

디자인 패턴 - 행동패턴

개요 행동 패턴에는 다음 패턴들이 포함되어 있다. (취소선은 다루지 않음) 전략(Strategy) 상태(State) 탬플릿 메서드(Template Method) 명령(Command) 책임 연쇄(Chain of Responsibility) 관찰자 (Observer) 메멘토 (Memento) 중재자 (Mediator) 방문자 (Visitor) 반복자 (Iterator) 인터프리터 (Interpreter) 전략패턴, 반복자패턴은 이미 익숙한 개념이므로 패스, Interpreter는 특정 상황(ex. 문자열 명령어 파싱)에 한정적으로 쓰여서 패스. 상태패턴 2D 횡스크롤 게임이 있다고 가정하다. 캐릭터는 점프, 앉기, 달리기... 등의 여러 동작이 가능하다. 이런 동작들을 구현할 때 많은 예외에 부딪힐 것이다...

디자인 패턴 - 구조

개요 구조 패턴에는 다음의 패턴이 포함된다. Adapter Proxy Facade Decorator Bridge Flyweight Composite 이 글에서는 위 패턴들을 '간단하게' 다룬다. 어답터 패턴 다른 인터페이스에 adapter 클래스를 만들어서 사용하고자 하는 인터페이스와 호환되도록 하는 것이다. 위 다이어그램처럼 외부에서 가져온 ForeignCat은 cry()메서드가 없지만 어댑터를 통해 기존 인터페이스와 호환되게 동작하도록 만들어줄 수 있다. 프록시 패턴 클래스에 접근할 때 프록시 클래스를 통해 접근하는 것. 프록시 클래스에서는 통계나 로그 캐싱등을 해줄 수 있다. class Animal { public: virtual void speak() = 0; }; class Cat final :..

디자인 패턴 - 생성 패턴

개요 생성 패턴에는 다음의 패턴이 포함된다. Factory Factory Method Abstract Factory Builder Singleton Prototype 이 글에서는 위 패턴들을 '간단하게' 다룬다. 팩토리(Factory) 패턴 팩토리는 오브젝트를 찍어내는 공장 같은 것이다. //타입을 받아 클래스를 반환한다. public class AnimalFactory { public Animal Create(AnimalType animalType) { switch (animalType) { case AnimalType.Cat: return new Cat(); case AnimalType.Dog: return new Dog(); } return null; } } 위 방식처럼 ~~ Factory 클래스를..