전체 글 102

[게임 프로그래밍 패턴][18]더티 플래그

개요더티 플래그는 계속 변경되는 기본 값을 통해 파생 값을 만들어야 할때 사용할 수 있는 패턴이다. 이는 계산과 동기화 두가지 경우가 있다. 계산은 지역 변환 행렬을 통해 월드 변환 행렬을 구하는 경우등이 있고 동기화는 로컬의 상태를 서버에 갱신하는 경우등이 있다. 더티 플래그는 파생 값이 기본 값에 동기화되어 있는지를 나타내는 플래그로 기본 값이 수정되면 true가 되고 파생 값을 갱신하면 false가 된다. 이를 통해 현재 파생 값을 그냥 쓰면 될지 기본값을 통해 갱신해야 할지 알 수 있다. 사용 예시계산에 사용하는 경우는 위에서 말한 지역 변환 행렬과 월드 변환 행렬이 있다. 업데이트에서 transform 계층 구조를 가진 오브젝트들의 지역 변환 행렬을 갱신한다고 하자. 이때 갱신된 오브젝트의 더티..

[게임 프로그래밍 패턴][17]데이터 지역성

개요데이터 지역성은 캐쉬 효율을 극대화 하기위한 패턴이다. 메모리는 접근 속도가 느리기에 한 데이터에 접근시 그 데이터와 인접한 데이터 블럭을 캐쉬로 가져와 저장해둔다. 캐쉬에 저장된 데이터에 접근하면 속도가 훨씬 빠르다. 성능이 중요한 부분은 데이터 지역성을 신경쓰면 좋다. 사용 예시연속 배열만약 각 객체별로 여러 컴포넌트를 가리키는 포인터가 있고 그러한 객체들의 포인터를 가진 전역 객체 포인터 배열이 있다고하자. 그리고 각 데이터들은 힙에 랜덤하게 할당되어있다고 하자. 그리고 게임 루프는 각 객체의 AI 컴포넌트들을 순회하며 업데이트하고, 그 다음 물리 컴포넌트들을 순회하고...하는 식으로 컴포넌트들끼리 묶어 처리한다고 하자. 이렇게 되면 캐쉬 효율이 매우 낮다. ai 업데이트들을 처리할때 한 ai ..

[게임 프로그래밍 패턴][16]서비스 중개자

개요서비스 중개자는 서비스 제공자 인터페이스를 상속한 구체 서비스 제공자를 인터페이스로 보관하는 서비스 중개자를 하나 두고 중개자를 통해 서비스를 제공하는 패턴이다. 싱글턴 패턴과 유사한데 클래스에서 자기 자신의 인스턴스를 관리하는 것이 아닌 중개자라는 다른 클래스에서 해당 서비스 제공자의 인터페이스 포인터에 서비스 제공자를 저장해둔다는 점이 다르다. 특징싱글톤과 비교되는 서비스 중개자의 특징은 서비스 제공자 객체가 바뀔수 있다는 점이다. 싱글턴은 보통 초기화 이후 이를 계속 유지하지만 서비스 중개자는 컴파일, 런타임 시점등에서 갈아 끼울 수 있다. 이를 이용하여 곳곳에서 사용하는 서비스를 한번에 수정할 수 있다. 예를 들면 오디오 서비스에서 실제 오디오 출력 서비스를 로그 출력으로 수정하는 식으로 바꿀..

[게임 프로그래밍 패턴][15]이벤트 큐

개요이벤트 큐는 한 개체의 다른 개체에 대한 특정 요청을 즉시 처리하는 것이 아닌 큐에 저장해두었다가 나중에 처리하는 것을 말한다. 크게 이벤트를 보내는 경우와 메세지를 보내는 경우가 있는데 이벤트는 큐에 특정 사건 발생시 이벤트를 넣고 등록된 리스너들에게 이를 전달하는 것이다. 이는 함수 호출등으로 구현된다. 메세지는 특정 기능을 요청하는 메세지를 큐에 넣으면 리스너가 그 내용들을 원할때 큐에서 꺼내 처리하는 것이다. 오디오 기능을 메세지를 통해 제공할 수 있다.n대m이벤트 큐는 큐에 요청을 넣는 개체 n개와 그 요청을 처리하는 개체 m개로 n대m으로 표현할 수 있다. 일대다, 다대일, 다대다 등이 많이 쓰이며 일대일은 이벤트큐보다는 그냥 큐 자료구조를 사용하는게 낫다. 특징이벤트 큐로 얻을 수 있는 ..

[게임 프로그래밍 패턴][14]컴포넌트 패턴

개요컴포넌트 패턴은 한 개체의 기능을 한 클래스에 몰아 넣는것이 아닌 여러 컴포넌트 클래스로 나누어 구현하는것을 말한다.개체 클래스는 여러 컴포넌트를 소지하게 된다. 각 컴포넌트는 메소드와 데이터를 가져 동작과 상태를 모두 나누어 가지게 된다. 특정 기능을 컴포넌트로 분리하여 구현하면 개체에 몰려있던 커플링을 분리할 수 있고 한 클래스에 코드가 몰리는것도 막을 수 있다. 또한 독립적으로 작동하는 컴포넌트라면 일반화하여 다른곳에 재활용 할 수도 있다. 언리얼 엔진의 컴포넌트나 유니티의 컴포넌트도 비슷한 개념인 것 같다.  컴포넌트간 상호작용각 컴포넌트가 완전히 독립적으로 동작하면 좋겠지만 서로 통신이 필요할 수도 있다. 이때 다음 세가지 방식으로 구현할 수 있다. 개체의 멤버 데이터를 통해 통신개체가 가진..

[게임 프로그래밍 패턴][13]타입 객체

개요타입 객체는 타입 사용 객체가 타입 객체 인스턴스를 가짐으로써 한 타입을 나타내는 패턴이다. 즉 각 인스턴스가 하나의 타입을 의미하는 타입 클래스가 있으며 해당 타입 클래스의 인스턴스를 하나 가져 해당 타입의 인스턴스를 나타내는 타입 사용 클래스가 존재한다. 이를 통해 추가적인 상속이나 클래스없이 인스턴스만으로 새로운 타입들을 만들어 나갈 수 있다.타입 객체의 인스턴스가 가진 데이터로 한 타입을 나타내는 패턴이기에 만들고자하는 타입들이 데이터로 구분될때 유용하다. 물론 타입 사용 클래스등에서 미리 구현된 기능들을 타입 객체의 데이터를 통해 적절히 조합하여 사용하는 방식으로 타입 객체에서 동작도 정의할 수 있다. 앞서 배웠던 바이트 코드 등이 하나의 예시가 될 수 있다.타입 객체 패턴은 만들고자 하는 ..

[게임 프로그래밍 패턴][12]하위 클래스 샌드박스

개요하위 클래스 샌드박스는 상위 클래스가 외부와의 커플링 및 기능 구현을 주로 담당하고 하위 클래스에서는 상위 클래스에서 제공해주는 기능들로 가상 메소드를 구현하는 구조를 이야기한다. 이는 한 상위 클래스 아래에 만들어질 여러 하위 클래스들의 커플링을 한곳으로 모으는 것과 중복되는 코드를 상위 클래스에 모아 재활용할 수 있도록 하기위해 사용된다. 스킬 클래스들을 만든다 할 때 오디오, 파티클, 플레이어 이동등의 기능 및 외부 커플링을 상위 클래스에서 메서드로 모두 구현하고 하위 스킬 클래스에서는 이들을 이용하여 스킬 사용을 나타내는 가상 메서드를 구현하는 구조가 예시이다.  상위 클래스 기능 제공 정도위에서 말한 여러 이점때문에 상위 클래스에서 기능 제공을 맡는다. 하지만 상위 클래스에 너무 많은 코드와..

[게임 프로그래밍 패턴][11]바이트 코드

개요바이트 코드 패턴은 특정 행동을 바이트 명령어로 정의하여 사용하는 패턴이다. 마법 시스템을 정의한다고 할 때 targetHP수정, TargetPosition 수정 등의 명령어들을 정의해두고 일련의 바이트 코드 하나를 마법으로 사용하는 식이다. 여기서 더 나아가 스택 머신과 그에 따른 명령어들을 추가하여 프로그래밍 언어처럼 각종 값 저장과 연산들을 사용할 수도 있다. 일련의 명령어는 한 명령어를 한 바이트로 표현하여 바이트 배열로 표현 할 수 있다. 즉 한 바이트 배열이 하나의 마법처럼 사용 될 수 있다. 또한 스택에 데이터를 삽입하는 리터럴 명령어 뒤의 바이트는 명령어가 아닌 삽입할 숫자 리터럴을 나타낸다.이렇게 바이트 배열로 마법을 정의하는 시스템을 만들었으면 기획자나 담당자가 스킬을 만들어낼 수 ..

[게임 프로그래밍 패턴][10]업데이트 메서드

개요업데이트 메서드 패턴은 게임의 메인 루프에서 각 개체의 업데이트를 호출해주는 방식을 이야기한다. 각 개체의 코드에서 업데이트를 구현함으로써 자신의 동작을 자신이 캡슐화 할 수 있다. 구현방법상속개체 상위 클래스에서 virtual update 메소드를 제공하고 개체들이 이를 오버라이드하여 구현한다. 메인 루프에서는 상위 클래스 포인터 컬렉션의 요소들에 Update들을 호출한다. 컴포넌트개체가 가지는 컴포넌트들에서 update를 구현한다. 여러 컴포넌트를 조합하여 개체의 동작을 만들어 낼 수 있다. 위임개체는 update virtual 메소드를 구현한 위임용 객체의 포인터를 가지고 있고 개체의 update에서는 해당 포인터의 update를 호출한다. 위임용 객체를 갈아 끼움으로써 개체의 update를 수..

[게임 프로그래밍 패턴][9]게임 루프

개요게임 루프는 게임의 매 프레임의 동작을 수행하기 위한 루프 패턴을 의미한다. 입력 처리, Update, Render를 반복하는 루프로 구현된다.  기본가장 기본적인 구현 방법은 입력 처리, Update, Render를 그냥 반복하는 것이다. 가장 간단하지만 처리 속도에 따라 게임의 속도가 달라진다는 문제가 있다. 빠르면 대기위 방식에서 루프의 시작과 끝에서 걸린 시간을 측정하고, 즉 해당 프레임에 소모된 시간을 측정하고 Update에서 사용한 고정 시간보다 짧다면 그만큼 대기한후 다음 프레임으로 넘어가는 방식이다. cpu 속도가 빠른 경우에는 정상적인 속도로 진행된다.하지만 느리다면 여전히 게임의 속도도 느려진다. 가변 속도 방식이전 프레임의 처리 시간을 저장해두고 다음 프레임의 update에 해당 ..