게임 개발에 유용한 프로그래밍 디자인 패턴은 무엇입니까? [닫은]


129

Design Patterns에 관한 책이 몇 권 있는데 기사를 읽었지만 게임 개발에 어떤 프로그래밍 디자인 패턴이 유용한 지 직관적으로 파악할 수는 없습니다.

예를 들어, Model View Controller, Singleton, Factory, Command 등과 같은 여러 디자인 패턴을 자세히 설명하는 디자인 패턴이있는 ActionScript 3이라는 책이 있습니다.

이것에 익숙하지 않은 사람으로서, 이것들 중 어느 것이 유용 할 것인지, 실제로 이것들 중 어느 것이 내가 배우고 사용해야하는 디자인 패턴인지 알아낼 수 없습니다. 아마도 내가 모르는 게임 프로그래밍 전용 디자인 패턴이 더 있을까요?

게임 개발에서 특정 디자인 패턴을 사용한 경험이 있다면 듣고 싶습니다. 사용 된 이유, 코드 샘플 또는 온라인 리소스에 대한 추론은 모두 유용 할 때 매우 유용합니다. 저는 현재 ActionScript 3 및 C ++ 구현에 가장 관심이 있지만 모든 언어의 경험과 예제를 통해 확실히 이점을 얻을 수 있습니다.

감사!


"아마도 모르는 게임 프로그래밍 관련 디자인 패턴이 더 있을까요?" -아니요, 이러한 패턴은 일반적이며 사용중인 언어의 기능을 확장하는 데 더 많이 적용됩니다. 그들은 당신의 신청의 주제와 아무 관련이 없습니다.
Kylotan

3
@Kylotan 제 생각에는 각 디자인 패턴이 효과적인 방식으로 특정 문제를 해결하기위한 것이기 때문에, 본질 상 일부 디자인 패턴은 특정 문제 세트가 주어진 다른 패턴보다 더 유용 할 것입니다. 이러한 문제는 게임 개발에 고유합니다. 분명히 어떤 지침이 있거나 경험에 따라 다른 디자인 패턴보다 자주 사용하는 특정 디자인 패턴이 있습니까?
jcurrie33

사람이 꺼지고 1000 개 다른 디자인 패턴을 학습하기 전에 읽어 보시기 바랍니다
BlueRaja - 대니 Pflughoeft

@ BlueRaja-DannyPflughoeft Secon 링크가 유효하지 않습니다. 다시 보낼 수 있습니까
Emadpres

답변:


163

이제 약간의 제안으로 플립 팬트 반응이 줄어 듭니다. 가능한 사용의 예로 더 많은 구현 권장 사항을 사용하지 마십시오.

  • 빌더 : 데이터를 기반으로 한 번에 하나의 구성 요소 기반 구성 요소 엔티티 설정
  • 팩토리 메소드 : 파일에서 읽은 문자열을 기반으로 NPC 또는 GUI 위젯 작성
  • 프로토 타입 : 하나의 일반 'Elf'문자를 초기 특성으로 저장하고 Elf 인스턴스를 복제하여 작성하십시오.
  • 싱글 톤 : 이 공간은 일부러 비워 두었습니다.
  • 어댑터 : 기존 코드처럼 보이는 레이어로 래핑하여 선택적 타사 라이브러리를 통합합니다. DLL에 매우 유용합니다.
  • 합성 : 렌더링 가능한 객체의 장면 그래프를 만들거나 위젯 트리에서 GUI를 만듭니다.
  • 외관 : 나중에보다 쉽게 ​​생활 할 수 있도록 더 간단한 인터페이스를 제공하여 복잡한 타사 라이브러리를 단순화합니다.
  • Flyweight : NPC의 공유 측면 (예 : 모델, 텍스처, 애니메이션)을 개별 측면 (예 : 위치, 건강)과 별개로 투명하게 저장합니다.
  • 프록시 : 서버에서 더 크고 복잡한 클래스를 나타내는 작은 클래스를 클라이언트에 작성하고 네트워크를 통해 요청을 전달하십시오.
  • 책임의 사슬 : 예를 들어, 처리자 사슬로 입력을 처리하십시오. 글로벌 키 (예 : 스크린 샷), GUI (예 : 텍스트 상자에 포커스가 있거나 메뉴가 표시된 경우), 게임 (예 : 캐릭터 이동)
  • 명령 : 게임 기능을 콘솔에 입력하거나, 저장 및 재생하거나, 게임 테스트를 돕기 위해 스크립팅 할 수있는 명령으로 게임 기능을 캡슐화합니다.
  • 중재자 : 게임 엔티티를 다른 컴포넌트에서 작동하는 작은 중재자 클래스로 구현합니다 (예 : 데이터를 AI 컴포넌트에 전달하기 위해 건강 컴포넌트에서 읽기).
  • 관찰자 : 게임 로직이 렌더링 코드에 대해 알 필요없이 시각적 표현을 변경하기 위해 캐릭터의 렌더링 가능 표현이 논리적 표현의 이벤트를 수신하게합니다.
  • 상태 : NPC AI를 여러 상태 중 하나로 저장합니다 (예 : 공격, 방황, 도망. 각각은 자체 update () 메소드와 필요한 다른 데이터를 가질 수 있습니다 (예 : 공격하거나 도망 치는 캐릭터, 방황하는 지역 등)
  • 전략 : 어떤 지형에 있는지 또는 A * 프레임 워크를 사용하여 길 찾기와보다 일반적인 계획을 수행하는 등 A * 검색을 위해 다른 휴리스틱 간 전환
  • 템플릿 방법 : 각 단계를 처리하는 다양한 후크 기능을 사용하여 일반적인 '전투'루틴을 설정합니다 (예 : 탄약 감소, 적중 확률 계산, 적중 또는 미스 해결, 피해 계산

영감이 부족하여 일부 패턴이 사라졌습니다.


싱글에 매우 계몽 논의는 여기에서 찾을 수 있습니다 : misko.hevery.com/2008/08/25/root-cause-of-singletons
앤드류 왕을

전략 패턴 +1 위에서 언급 한 정확한 목적으로 사용했습니다 (다른 A * 휴리스틱 연결).
Mike Strobel

1
이 답변에 감사드립니다, 그 곳은 어디에서나 들리는 평범한 "싱글 톤"보다 ​​디자인 패턴처럼 들립니다 ...
jokoon

훌륭한 예제 목록. 싱글 톤 패턴 (전역의 변장)을 만성적으로 남용 했음에도 불구하고, 합법적 인 용도가 있습니다. 자원 이 실제로 보유하고 있거나 원하는 자원 을 나타내는 경우 . 하드웨어 래핑 (예 : 키보드 / 마우스) 또는 재진입되지 않은 라이브러리 래핑 (일어나 모든 언어에 마법 동기화 키워드가있는 것은 아님)과 같은 것일 수 있습니다.
charstar

11
나는 여전히 하드웨어 리소스에 싱글 톤을 사용하지 않을 것입니다. 당신이 생각하는 항목 중 하나는 비디오 카드와 모니터가 몇 년이 지났을 때와 마찬가지로 나중에 곱하는 경향이 있습니다. 마찬가지로 일부 API에서는 게임 패드 1 개를 이해하기 위해 2 개의 조이스틱을 읽어야합니다. 따라서 하나만 필요하다면 하나만 인스턴스화하고 필요하지 않은 임의의 제한을 강요하지 마십시오.
Kylotan

59

나는 정확히 그 주제에 관한 책을 썼습니다 : Game Programming Patterns . 해당 장이 도움이 될 수 있습니다.


2
+1 나는 누군가가 그것에 연결되기를 바 랐고 나는 저자가 그것을 보았다! 구성 요소 패턴 설명이 도움이되었으므로 완전한 코드 예제를 사용하여 시연하려고합니다.
CodexArcanum

2
예-몇 년 전에 링크를 읽은 것을 기억합니다. 그 기사들을 끝내야합니다!
onedayitwillwill

2
이제 책이 완성되었습니다 :)
dusan

1
기존 프로그래밍 지식을 게임 프로그래밍으로 변환하는 데 도움이 된 놀라운 자료입니다. 작성해 주셔서 감사합니다!

게임 프로그래밍 패턴에 대한이 설명은 실제로 소프트웨어 디자인 패턴 북이 실제로하지 않은 방식으로 디자인 패턴을 이해하는 데 도움이되었습니다! 이것은 부분적으로 게임 개발의 힘 (나에게 말하고 전반적인 개발을 향상시킬 수있는 언어로 된 구체적인 예제)이지만 글쓰기가 우수하기 때문에 더 큰 부분입니다.
Kzqai

19

브랜든 아이크 (Brandon Eich)가 직장 에서 코더 (Corders) 를 기르는 것이 좋은 의미 는 패턴이 해킹과 해결 방법 이라는 것입니다. 이 패턴은 무료가 아닙니다. 무료 점심은 없습니다. 따라서 올바른 비트를 추가하는 언어의 진화를 찾아야합니다.

우리는 컴파일러 디자이너가 아닌 게임 프로그래머로서 우리가 사용하는 언어를 진화시키는 옵션을 거의 얻지 못하지만, 우리의 언어와 요구 사항에 더 잘 맞도록 자신 만의 스타일을 발전시키는 법을 배울 수 있습니다. 패턴은 이것의 일부이지만 패턴을 사용하지 않는 것은 또 다른 부분입니다. 특히 Brandon이 말했듯이 패턴은 눈에 띄는 성능이나 메모리 또는 코드 민첩성 비용 없이는 거의 없습니다. MVC는 게임에서 많은 것들을위한 훌륭한 패턴이 아닙니다. Singleton은 불충분 한 C ++ 정적 초기화 규칙에 대한 해결 방법이며 어쨌든 그렇게하지 않아야합니다. 팩토리는 복잡한 객체 생성을 단순화합니다. 아마도 객체를 시작하기가 더 간단해야합니다. 인기있는 패턴은 필요할 때 사용하는 도구입니다. 도구가 아닌 복잡한 것을 관리하기 위해 처음에는 복잡한 것을 만들기 위해 갈망해야합니다.

좋은 (게임) 코드는 패턴을 사용하거나 사용하지 않을 수 있습니다. 패턴을 사용한다면 괜찮습니다. 언어 구조에 관계없이 다른 프로그래머에게 코드 구조를 설명 할 수있는 훌륭한 커뮤니케이션 도구입니다. 패턴을 사용하지 않고 코드가 더 좋다고 생각한다면 코드를 두드리지 마십시오.


4
그렇습니다. 원본 책에서 분명하지만 간과되는 것 중 하나는 C ++ / Smalltalk가 아닌 C로 작성된 경우 "상속"패턴을 포함했을 수 있으며 동일한 토큰으로 일부 언어가 포함되어 있다는 것입니다 이미 내장 된 일부 GoF 패턴을 포함 할 수 있습니다.
Kylotan

13
원본 서적 (GoF가 아닌 Alexander의 원본 서적)에서 종종 간과 한 또 다른 사항은 패턴이 구현이 아니라 커뮤니케이션을 위한 도구라는 점이었습니다 . 디자이너는 구현에 대해 더 높은 수준으로 의사 소통 할 수있게되며 가능한 경우 반드시 사용해야하기 때문에 반복되지 않기 때문에 식별됩니다.

1
그러나 용어를 사용하는 것만으로도 문제에 대해 추론하고 그러한 접근 방식이 좋은 솔루션인지 인식 할 수 있습니다. 최상의 패턴은 일반적으로 숙련되고 숙련 된 작업자에 의해 시간이 지남에 따라 개선되었으며, 덜 숙련 된 작업자는 이러한 체계화 된 예가 없으면 동일한 패턴 자체를 발견 할 수 없습니다.
Kylotan

나는 용어를 갖는 것이 훌륭하고, 패턴의 정의의 일부는 그것이 어떤 문제에 대해 좋은 되풀이 해결책이라는 데 동의한다. 불행히도 기술이 부족한 근로자는 주로 싱글 톤을 찾아 문제가없는 경우에도 모든 문제에 적용하는 경향이 있습니다.

이 답변에 감사드립니다. 소프트웨어 디자인으로 인해 발생하는 문제를 해결하기 위해 디자인 패턴이 만들어진다는 것을 알고 안심합니다. 실제로 전체 코드를 작성하기 전에 전체 소프트웨어의 구조를 처음부터 끝까지 생각해야한다고 생각합니다. 한 번에 한 번에 한 번만 기능을 구현할 수는 없으며 언젠가는 각각의 특정 기능에 대해 생각하고 소프트웨어의 글로벌 구조를 망칠 수 있는지 또는 소프트웨어가 어떻게 사용되는지에 대한 방법을 찾아야합니다. 굴다. 여러 프로그래머에게 작업을 나누면 때때로 모순이 생길 수 있습니다.
jokoon

7

물론 다른 사람들이 말했듯이 모든 패턴은 올바른 환경에서 유용하며, 사용 방법을 배우는 과정의 일부는 사용시기를 배우는 것입니다. 그러나 Daniel Sanchez-Crespo Dalmau의 게임 프로그래밍에서 핵심 기술과 알고리즘 의 훌륭한 책 은 게임 프로그래밍 에 특히 유용한 6 개의 프로그래밍 패턴과 6 개의 사용성 패턴을 나열합니다.

프로그램 작성:

  • 싱글 톤 : 나는 많은 사람들이하는 것처럼 이것을 싫어하지 않습니다. 싱글 플레이어 플레이어 또는 키보드 리더와 같은 용도로 사용할 수 있습니다.
  • 팩토리 : 객체를 효율적으로 생성하고 파괴 할 수 있습니다.
  • 전략 : AI 전략을 우아하게 바꿀 수 있습니다.
  • 공간 인덱스 : 공간 데이터 세트에서 쿼리를 수행 할 수 있습니다.
  • 합성 : 유용한 객체 계층을 설정합니다.
  • Flyweight : 동일한 적과 같은 것을 일반화하여 메모리를 확보합니다.

사용성 :

  • 방어막 : 실수로 극적인 행동을 유발하지 않도록 보호합니다.
  • 상태 : 월드 / UI 상태의 시각적 신호.
  • 자동 모드 취소 : 게임을보다 직관적으로 작동시킵니다.
  • 자기 : 자동 조준 및 손쉬운 유닛 선택.
  • 초점 :주의가 산만해진 UI 요소 제거.
  • 진행 : 보편적으로 유용합니다.

물론이 책은 이들 각각에 대해 더 자세히 설명합니다.


입력 주셔서 감사합니다! 나는 그 책을 알지 못했지만 지금 당신의 게시물의 결과로 그것을 볼 것입니다. 다시 감사합니다!
jcurrie33

2
키보드 리더를위한 싱글 톤은 정확히 내가 물어봐야 할 상황입니다-메인 기능 초기에 글로벌 포인터로 설정할 수 없습니까? 실제로 두 개의 키보드 리더를 실수로 인스턴스화 한 적이 있습니까?

싱글 톤을 미워하십시오. 두 가지를 제대로 수행하지 못합니다. 글로벌 액세스 및 신성 종종 개발자는 글로벌 액세스 == 싱글 톤이라고 생각합니다. 이 매우 이상의 몇 가지 문제는 진정한 싱글을해야하고, 싱글 해결할 때 더 우아한이 더 가능성이 몇 가지.
deft_code

7

엔터티 시스템 은 좋은 종류의 패턴입니다. 그것은 OOP가 아니기 때문에 정확하게 디자인 패턴이 아닙니다. 그러나 OOP와 함께 사용할 수 있습니다.

좋은 링크들 (소개부터 시작) :


3
"그것은 엄청나게 OOP가 아니기 때문에 정확하게 디자인 패턴이 아니다." 디자인 패턴은 OOP와 관련이 없습니다. OOP 자체는 디자인 패턴입니다. 디자인 패턴은 OOP 외부가 아니라 소프트웨어 개발 외부에 나타납니다.

있다 OOP design patterns일반적으로 클래스 / 객체 사이의 관계와 상호 작용을 보여주는 것이다. 그리고 다른 많은 디자인 패턴이 있습니다. OOP는 개념이 아니라 개념의 집합입니다. Design pattern개념이기도합니다.
topright

6
시맨틱에 대해 이야기하는 대신 내가 준 응답의 유용성을 평가해서는 안됩니까?
Wernight

6

그들 모두. 싱글 톤 제외. [/경솔]


게임 개발에서 자주 사용하는 하나 또는 두 개의 디자인 패턴을 말하고 어떤 이유로 말할 수 있습니까? 디자인 패턴과 관련하여 초보자에게는 "모두"가 특별히 도움이되지는 않습니다. 답변 해 주셔서 감사합니다.
jcurrie33

5
"어떤 패턴을 사용 했습니까?" "어떤 변수 이름을 사용하셨습니까?" 개인 스타일과 요구 사항 및 도메인에 따라 다릅니다. 언젠가 이름이 지정된 패턴을 사용하게 될 것입니다. 당신은 아마 명명되지 않은 더 많은 것을 사용하고 아마도 새로운 것을 발명 할 것입니다.

@ jcurrie33 : 죄송합니다. 단일 싱글 톤을 파는 것에 저항 할 수 없었습니다. ;)
Kylotan

6

패턴에 관한 것이 아니라 그 뒤에있는 기본 원칙에 관한 것입니다. 에서 "디자인 패턴 : 재사용 가능한 개체 지향 소프트웨어의 요소"(1995) ;의 갱 네 (감마, 에리히 리처드 헬름, 랄프 존슨과 존 브리 시즈)는 객체 지향 설계에 대한 두 원칙 권장 (1) 프로그램을 구현이 아닌 인터페이스 및 (2) 클래스 상속보다 객체 구성을 선호합니다.

이 두 가지 원칙은 많은 게임 개발 작업에서 매우 유용합니다. 예를 들어, 많은 게임 프로그래머는 딥 클래스 계층 을 사용하여 게임 엔터티를 나타냅니다. 컴포지션 기반 게임 오브젝트라는 컴포지션을 기반으로하는 다른 접근 방식이 있습니다. 이 접근법에 대한 기사 . 더 많은 링크 . 그것은 인 데코레이터 패턴의 예.


게임 디자인에 사용되는 구성 요소는 상태 저장 전략 패턴과 비슷합니다. 이는 C / C ++ / Java / C # 외부의 클로저와 내부의 구성 요소 개체로 자연스럽게 표현됩니다. 데코레이터 패턴은 프록시와 비슷합니다. 소유권과 데이터 흐름은 게임에서 컴포넌트 시스템에 대해 이야기 할 때 일반적으로 의미하는 것과 반대입니다.

또한 구성 요소는 서로 대화하여 중재자, 관찰자 ​​및 작곡가와 같은 패턴을 가져와야합니다. "컴포넌트 기반 게임"은 그 자체로 복합 디자인 패턴입니다.
CodexArcanum

@CodexArcanum, Observer는 정의 자이지만 항상 중재자는 아닙니다 (대신 체인을 대신 사용할 수 있음). GameObject (GameObjectComponent로 구성)가 GameObjectComponent 자체 (필수 아님) 인 경우에만 Composer입니다.
topright

6

호기심 반복 템플릿 패턴은 가상의 방법과 가상 함수 호출에서 올 수있는 성능 저하를 피하기위한 정말 유용 할 수 있습니다.

실제로 인터페이스가있는 기본 클래스 유형의 컨테이너가 필요하지 않지만 비슷한 이름의 동작과 인터페이스를 원할 때 적절한 패턴이 될 수 있습니다.

예를 들어, 컴파일시 유형 유형의 편차가 알려진 여러 플랫폼 또는 엔진 (dx 대 opengl)에 대한 클래스를 컴파일 할 때이를 사용할 수 있습니다.


나는 항상 os 추상화 계층이 가상이라는 것을 싫어했습니다. 두 개의 os abtraction layer가 필요한 것은 아닙니다. CRTP를 사용하는 것이 훨씬 좋습니다.
deft_code

어쩌면 나는 나이가 들었지만 DX / OpenGL 또는 플랫폼 인터페이스에 CRTP를 사용하지 않을 것입니다. 컴파일하기에는 너무 느립니다. typedef를 사용하고 싶습니다. CRTP는 클래스간에 인터페이스와 구현을 공유하고 싶지만 하나의 구조체 만 선택하려는 경우가 아니라 다른 관계가없는 경우에 좋습니다.

4

수년에 걸쳐 발전해 왔고 나에게 크게 유용했던 디자인 패턴은 "브로커 정의 세트"라고합니다. GOF 용어로 요약하는 방법은 논란의 여지가 있지만 StackOverflow에서 작성한이 질문에 대해 자세히 설명합니다.

핵심 개념은 생물 종과 같은 모델의 일부 속성이 설정되어 속성의 각 가능한 값에 해당 정의 객체 (값당 단일 공유 객체)가 있으며, 중앙 브로커를 통해 액세스합니다 (GOF 방식으로 레지스트리, 팩토리 또는 둘 다일 수 있음). 필자의 사용법에서는 일반적으로 스칼라 키를 통해 액세스하여 런타임 형태 목적으로 약한 바인딩을 용이하게합니다.


나는 이것이 어떻게 싱글 톤인지 보지 못하고 플라이급 패턴을 논의 할 때 "레지스트리"라는 단어가 중복됩니다. 이것은 단지 플라이급입니다.

SO 스레드에서 나는 사람들이 Singleton을 클래스로 설정했기 때문에 Singleton을 그것의 일부로 식별했다는 것을 이해했습니다. Registry가 진행되는 한 Factory와 교체하거나 결합 할 때 어떻게 중복 될 수 있는지 알지 못합니다.
혼돈

-1, 패턴이 빠른 의사 소통에 관한 한, 이것은 내가 본 가장 큰 실패 일 것입니다. 나는이 설명을 진지하게 받아 들일 수 없다.

예수여, 쿠키 커터가되지 않아서 용서해주세요. GOF 용어로 즉시 요약 할 수 없기 때문에 "엔터티 시스템"답변도 투표하지 않겠습니까?
혼돈

1
어느 정도의 "쿠키 커터"또는 적어도 의미 상 명료도는 패턴이 유용해야하는 정확한 것입니다. "플라이급"및 "단일"과 같은 용어는 일반적으로 이해되며 상호 배타적입니다. 첫 번째는 여러 인스턴스간에 데이터를 자동으로 공유하는 것입니다. 두 번째는 정확히 하나의 인스턴스를 갖는 것입니다. 나는 당신의 디자인 선택이 쓸모 없거나 나쁘다고 말하지는 않지만, "충분히 근접한"패턴 이름을 만들면 모든 사람들이 더 혼란스러워집니다. (특히 CW에서 개인적으로
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.