게임 디자인에서 프레임 별 함수 호출과 이벤트 중심 메시징


11

그만큼 전통적인 게임 디자인은 내가 아는 한, 사용 다형성과 가상 함수를 업데이트 게임 상태를 객체에. 다시 말해, 동일한 가상 함수 세트가 게임의 모든 객체에 대해 규칙적인 (예 : 프레임 당) 간격으로 호출됩니다.

최근에 나는 또 다른 것이 있다는 것을 발견했다. 에 게임 객체의 상태를 업데이트 할 수있는 이벤트 중심 메시징 시스템이 있음을 . 여기서 개체는 일반적으로 프레임별로 업데이트되지 않습니다. 대신, 매우 효율적인 이벤트 메시징 시스템 이 구축되고 유효한 이벤트 메시지를 수신 한 후에 만 ​​게임 개체가 업데이트됩니다.

이벤트 중심 게임 아키텍처Mike McShaffry의 게임 코딩 완료 잘 설명되어 있습니다.

다음 질문에 대해 친절하게 도움을 요청할 수 있습니까?

  • 두 가지 방법의 장점과 단점은 무엇입니까?
  • 하나는 다른 것보다 더 나은 곳은 어디입니까?
  • 이벤트 중심 게임 디자인은 모든 영역에서 보편적이고 더 좋습니까? 따라서 mombile 플랫폼에서도 사용하도록 권장됩니까?
  • 어느 쪽이 더 효율적이고 어느 쪽이 개발하기 어려운가요?

명확히하기 위해, 내 질문은 게임 디자인에서 다형성을 완전히 제거하는 것에 관한 것이 아닙니다. 이벤트 차이 메시징과 일반 (프레임 당) 호출을 가상 함수에 사용하여 게임 상태를 업데이트 할 때의 차이점과 이점을 이해하고 싶습니다.


예 : 이 질문은 여기서 약간의 논쟁을 일으켰습니다. 예를 들어 보겠습니다. MVC에 따르면 게임 엔진은 세 가지 주요 부분으로 나뉩니다.

  1. 응용 프로그램 계층 (하드웨어 및 OS 통신)
  2. 게임 로직
  3. 게임 뷰

레이싱 게임에서 게임 뷰는 화면을 가능한 빨리 30fps로 렌더링하는 역할을합니다. 게임 뷰는 플레이어의 입력을 수신합니다. 이제 이런 일이 발생합니다.

  • 플레이어가 연료 페달을 80 %까지 누름
  • GameView는 "Car 2 Fuel Pedal Pressed to 80 %"라는 메시지를 작성하여 Game Logic으로 보냅니다.
  • Game Logic은 메시지를 가져 와서 평가하고 새 차의 위치와 동작을 계산하고 GameView에 대해 "Draw Car 2 Fuel Pedal Pressed 80 %", "Car 2 Sound Acceleration", "Car 2 Coordinates X, Y"메시지를 생성합니다. .
  • GameView는 메시지를 받고 그에 따라 처리합니다

어디서 찾았어요? 일부 링크 또는 참조? 나는이 접근법을 모르지만 (일반적으로 꽤 weel 디자인 패턴을 알고 있으며 일반적으로 객체 지향 원칙을 잘 사용하도록 조언합니다) 이벤트 기반의 것이 더 낫습니다. 네트워크 시스템의 진화에 대한 생각 : from 비동기 호출에 대한 폴링. 계산 및 추상화 수준에서 최적화되어 있습니다.
nkint

안녕하세요 Nkint, 귀하의 의견에 감사드립니다. 나는 기본적으로 이벤트 중심 커뮤니케이션과 가상 함수 호출을 비교하고 싶었다. 내 질문을 약간 수정하겠습니다. Btw, game desing 패턴이 포함 된이 링크를보십시오 : gameprogrammingpatterns.com .
Bunkai.Satori

5
어쩌면 내가 바보 일지 모르지만 어떻게 다형성 사용 하지 않고 메시징 시스템을 작동 시킬 수 있습니까? 이벤트 수신자 인터페이스를 정의하기 위해 일종의 기본 클래스 (추상 또는 기타)가 필요하지 않습니까? (편집 : 당신이 적절한 반성을 가진 언어로 일하고 있지 않다고 가정합니다.)
Tetrad

2
또한 효율성은 구현 세부 사항과 밀접한 관련이 있습니다. 나는 "어느 쪽이 더 효율적인지"가 현재 형태로 대답 할 수있는 질문이라고 생각하지 않습니다.
Tetrad

1
게임 오브젝트는 틱해야합니다. 게임 오브젝트는 서로 통신해야합니다. 이 두 가지가 모두 발생해야합니다. 첫 번째는 메시지가 중복되어 메시징과 관련이 없습니다 (어딘가에 모든 개체 목록이있을 update수 있습니다). 두 번째는 다양한 이유로 메시징으로 할 수 있습니다.
Tetrad

답변:


8

나는 발명의 어머니가 될 필요성을 완전히 믿는 사람입니다. 필요가 명확하고 명확하지 않으면 아무것도 코딩하지 않습니다. 이벤트 메시징 시스템을 설정하여 프로젝트를 시작하면 잘못되었다고 생각합니다. 인프라를 만들고 테스트 한 후 프로젝트에 필요한 모든 요소를 ​​잘 정의 된 작동 모듈로 설정 한 후에 만 ​​이러한 모듈을 서로 연결하는 방법에 중점을 두어야한다고 생각합니다. 각 모듈의 모양과 요구 사항을 이해하기 전에 이벤트 메시징 시스템을 설계하려고 시도하는 것이 잘못되었습니다.

두 가지 방법의 장점과 단점은 무엇입니까?

어떤 사람들은 설치하고 사용할 준비가 된 훌륭한 메시징 시스템이 있다고 주장합니다. 아마도 이것은 사실입니다. 확실히 사용자의 요구에 맞는 맞춤형 빌드 솔루션의 성능은 범용 메시지 버스보다 클 것입니다. 가장 큰 문제는 이미 구축 된 것을 사용하지 않고 메시징 시스템을 구축하는 데 얼마나 많은 시간을 할애 할 것인가입니다. 분명히 필요한 기능 세트를 갖춘 일종의 이벤트 시스템을 찾을 수 있다면 매우 쉬운 결정입니다. 그렇기 때문에 결정을 내리기 전에 필요한 내용을 정확하게 이해해야합니다.

하나는 다른 것보다 더 나은 곳은 어디입니까?

여기서 메모리와 리소스에 대해 이야기 할 수 있습니다. 리소스가 부족한 하드웨어를 개발하는 경우 이벤트 시스템을 사용하는 것이 문제가 될 수 있습니다. 실제로, 나는 문제가 당신이 필요로하는 것이라고 생각합니다. 이는 이미 언급했듯이 모든 조각이 어떻게 생겼는지 알 때까지 알 수없는 것입니다. 모든 시스템이 어떤 모습 일지 미리 알고있는 이러한 시스템을 구축 한 경험이 있다면이 질문에 미리 대답 할 수 있습니다. 나는 당신 이이 질문을하지 않을 것이기 때문에, 당신은이 경험이 없다고 생각합니다.

이벤트 중심 게임 디자인은 모든 영역에서 보편적이고 더 좋습니까? 따라서 모바일 플랫폼에서도 사용하도록 권장됩니까?

모든 분야에서 보편적이며 더 좋습니까? 그런 예쁜 담요 진술은 쉽게 거부됩니다. 오버 헤드를 추가하는 것은 워크로드를 공유해야합니다. 디자인의 오버 헤드를 보증하기에 충분한 이벤트를 사용하지 않으면 잘못된 디자인입니다.

어느 쪽이 더 효율적이고 어느 쪽이 개발하기 어려운가요?

효율성은 구현 방법에 따라 다릅니다. 잘 개발 된 전통적인 디자인은 요일마다 이벤트 기반 시스템보다 성능이 뛰어나다 고 생각합니다. 조각 간의 통신을 미세 관리하고 매우 효율적으로 만들 수 있기 때문입니다. 물론 이것은 경험과 시간의 관점에서 디자인을 완성하기가 더 어려워지고 더욱 효율적으로 만드는 데 도움이됩니다. 반면에,이 경험이 부족하거나 응용 프로그램을 제대로 개발할 시간이 없다면 요구에 맞는 이벤트 기반 디자인을 사용하는 것이 더 효율적입니다. 이벤트 기반 구조에 쉽게 맞지 않는 사용자 지정 이벤트 요구 사항이있는 경우 이벤트 기반 구조를 설계하기가 매우 어려워 질 수 있습니다. 특히 디자인을 효율적으로 유지해야합니다.


에릭 안녕, 내 질문에 대한 자세한 의견을 보내 주셔서 감사합니다. 내가 당신과 다른 사람들의 반응을 읽었을 때, 이벤트 메시지를 구현한다고해서 전반적인 게임 성능 향상에 기적을 일으키지 않을 것입니다. 대신 많은 일들이 복잡해질 것입니다. 이 질문을 닫기 전에 더 많은 답변을 원합니다. 이 책 전체가이 주제를 다루었으므로 고려해 보는 것이 좋습니다. 메시지 중간에 메시지 사용 여부를 결정할 수 있는지 잘 모르겠습니다. 이벤트 메시지가 사용되면 전체 객체 디자인도 조정해야합니다.
Bunkai.Satori

동의하지 않습니다. 전체 객체 디자인이 잘 캡슐화되어 있으면 모든 종류의 프레임 워크에서 사용할 수있을 정도로 유연해야합니다. 각 조각이 잘 캡슐화되어 있기 때문에 작업이 거의없는 대규모 프로젝트에서 통신 방법을 교체 할 수있었습니다.
Erick Robertson

7

여기 사과와 오렌지를 비교하고 있다고 생각합니다. 다형성은 전혀 메시징으로 대체되지 않습니다. 이벤트 / 메시징이 느슨하게 결합 된 구성 요소를 연결하기를 원할 것입니다. 예 : 충돌이 발생했을 때 엔티티에서 메시지를 보내거나 플레이어 점수를 업데이트하거나 사운드 효과를 유발할 수 있습니다. 따라서 이러한 개별 클래스는 다른 클래스를 모르고 메시지를 보내거나 처리합니다.

그러나 게임은 대부분 업데이트 루프 어딘가에있을 것입니다 당신이 있기 때문에 업데이트되는 루프를, 쉽게뿐만 아니라 모든 프레임을 업데이트해야하는 모든 게임 요소를 업데이트 할 수 있습니다. 그래도 메시징을 사용할 수 있습니다.

게임 엔터티를 추가 / 제거하는 일종의 구조가있는 경우 매 프레임마다 업데이트 메시지를 디스패치하는 대신 업데이트 루프에 포함시킬 수 있습니다 . 메시지를 사용하여 게임의 다른 하위 시스템을 연결하는 동안 게임 엔터티에서 직접 업데이트 를 호출하지 않는 이유 는 무엇입니까? 또한 이벤트와 유사한 시스템 의 신호 / 슬롯 개념 ( qt 예제 참조 )이 마음에 듭니다.

결론 : 더 나은 접근 방법이 없으며 독점적입니다.


안녕, Bummzack 마침내 첫 번째 답변이 도착했습니다. Event-Driven Architecture에 대해 언급했을 때 Appliaction, GameView, GameLogic의 세 가지 주요 계층이있는 MVC 시스템을 의미했습니다. 이 trhee 간의 모든 통신은 메시징을 통해 수행됩니다. 이것은 업데이트 루프가있는 기존 시스템과 크게 다릅니다. 시스템마다 아키텍처, 장점 및 단점이 다르며 성능 비용이 다릅니다. 따라서 일부 지역에서는 약간 더 나을 것이라고 믿습니다. 좋은 분석 후에는 어느 것이 더 낫다는 결론을 내릴 수 있어야합니다.
Bunkai.Satori

3
왜 이것이 다른지 알지 못합니까? 어딘가에 업데이트 루프가 필요하며 MVC를 고수하려는 경우 아마도 컨트롤러를 업데이트합니다. 그러면 컨트롤러가 모델과 뷰에 메시지를 보낼 수 있습니다. 그러나 컨트롤러는 일반적으로 뷰와 모델을 알고 있기 때문에 직접 업데이트 할 수도 있습니다. 그러나 이것은 다형성을 대체하지 않습니다. 귀하의 질문과 가정은 매우 이론적으로 들립니다. 예제 코드 나 참조로 백업 할 수 있습니까?
bummzack

위에서 언급 한 Game Coding Complete 책은 가상 메서드에 대한 직접 호출을 통한 이벤트 메시징을 권장합니다. 메시징 시스템은 더 복잡해 보이지만 모든 게임 개체가 게임 세계를 확인할 필요가 없다는 장점이 있습니다. 게임 세계는 게임 로직으로 한 번만 확인한 다음 상태를 변경해야하는 객체 만 처리합니다. 이것은 한 가지 차이점이며 비용 절감을 의미 할 수 있습니다. 게임 오브젝트가 메시지를 통해 통신하도록 결정하면 각 프레임이라고 부르지 않으므로 두 가지 접근 방식은 상호 배타적입니다.
Bunkai.Satori

1
원래 질문 아래 Tetrad의 의견을 반영하는 답변에 투표를했습니다. @ Bunkai.Satori '게임 세계는 한 번만 확인됩니다'는 업데이트 루프이며, 업데이트가 필요한 모든 것이 그것을 얻습니다. 이벤트 메시지는 거의 수행되지 않지만 Update () 루프의 모든 프레임을 검사하는 것은 낭비가 될 수 있지만 엔진 (PlayerDied, MonsterDied 등)에서 여전히 중요합니다. Update () 루프 자체.
James

1
제 2 판이 있다면, 메인 루프 제어 장을보십시오. 3 판에서 같은 이름을 붙여야합니다. 그것은 정말로 당신의 질문에 대답해야합니다.
Ray Dey

4

이것은 bummzack의 답변에 대한 주석으로 시작되었지만 오래 걸렸습니다.

실제로 비 동기화하지 않으면 (새 스레드에서 이벤트 디스패치) 객체는 여전히 동기식으로 메모를 가져옵니다. 이벤트 디스패처가 셀에 링크 된 목록이있는 기본 해시 테이블을 사용한다고 가정하면 순서는 오브젝트가 해당 셀에 추가 된 순서입니다.

또한, 어떤 이유로 함수 포인터를 사용하기로 결정하지 않는 한, 메시지를받는 각 오브젝트는 IEventListener (또는 호출 한 것)를 구현해야하므로 여전히 가상 함수 호출을 사용하고 있습니다. 이벤트는 다형성을 사용하여 빌드하는 고급 추상화입니다.

게임 내 여러 시스템을 동기화하기 위해 게임 내 다양한 ​​이벤트에 대한 세탁 방법 목록을 호출해야하는 이벤트를 사용하거나 다양한 오브젝트와 시스템의 반응이 발생하여 이벤트를 명확하게 정의 할 수 없거나 원하는 이벤트를 사용하십시오. 미래에 일어난 일들에 더 많은 반응을 추가하기 위해.

그것들은 훌륭한 도구이지만 bummzack과 같이 다형성과 사건이 같은 문제를 해결한다고 가정하지 마십시오.


안녕하세요 Bearcdp, 답변 주셔서 감사합니다. 이해가 되네요. 이벤트 메시지에 투표하는 것은 마음 속에 한 가지가 있습니다. 즉, 장면에 200 개의 개체가 있습니다. 모든 오브젝트에서 프레임 별 함수 호출을 사용하는 경우 프레임마다 콜리 전이 있는지 200 개의 오브젝트를 모두 확인해야합니다 (예 : 호출 간격을 관리 할 수 ​​있음) 이벤트 메시징을 사용하면 게임 월드를 한 번만 검사합니다. 충돌이 5 개있는 경우 프레임 당 200 개의 콜리슨 감지 테스트 대신 충돌 이벤트에 대한 메시지가 5 개의 개체 만 통지됩니다. 당신의 의견 것입니다?
Bunkai.Satori

2
게임 세계를 검사 ?? 그게 무슨 뜻이야? 메시지를 보내는 데 필요한 5 개를 분리하기 위해 동일한 200 개의 검사를 실행해야합니다. 가상 기능 개념을 사용하면 게임 월드는 한 번만 확인되고 (각 오브젝트의 기능은 차례로) 메시징 시스템의 오버 헤드없이 상태 변경이 필요한 5 개만으로 이동합니다.
Steve H

1
세상이 스스로 충돌하지 않는 Steve H의 말을 들어보십시오. 나는 주로 PlayerJump, EnemyHit와 같은 높은 수준의 사건에 이벤트를 사용합니다. 충돌 검사 효율성을 처리하려면 게임에서 개체의 실제 위치를 구성 할 데이터 구조를 선택해야하므로 충돌이 필요한 개체의 우선 순위를 지정할 수 있습니다. 충돌 한 객체 쌍을 모두 결정하면 관련 충돌 데이터 (두 객체, 속도 / 위치 / 정규 데이터 등)로 이벤트를 전달할 수 있습니다.
michael.bartnett

Steve와 Beardcp 님, 귀하의 의견에 감사드립니다. 당신이 쓴 것은 말이됩니다. 가능한 많은 이벤트 메시징 시스템 구현이있을 수 있습니다. 위에서 언급 한 책에서 알 수 있듯이 프레임 별 가상 기능 개념을 완전히 대체 할 수 있습니다. 그러나 메시징 시스템은 프레임 당 가상 기능 개념과 공존 할 수 있습니다.
Bunkai.Satori

함수 포인터와 관련하여 왜 "어떤 이유로"라고 말합니까? 그것은 내가 처음부터 작성한 시간에 이벤트 시스템을 구현 한 방법과 거의 같습니다 (일류의 기능을 가진 언어로 작업하지만 같은 생각입니다. 함수를 이벤트 허브 객체에 전달하고 객체는 리스너 함수를 매핑합니다. 이벤트) 그래서 그 접근 방식에 단점이 있는지 궁금합니다.
jhocking

2

하나 또는 다른 것을 선택하는 것은 꽤 잘못되었다고 말할 것입니다. 일부 객체는 모든 프레임을 호출해야하지만 일부는 그렇지 않습니다. 당신은 당신이 렌더링 할 객체가있는 경우 필요한 A가 그것에 호출 모든 프레임을 렌더링 할 수 있습니다. 이벤트는이 변경을 수행 할 수 없습니다. 모든 시간 기반 물리 객체에 대해서도 마찬가지입니다 . 매 프레임마다 호출 해야합니다 .

그러나 객체 관리 객체 또는 사용자 입력 객체 또는 이와 유사한 것을 프레임마다 호출하지는 않습니다. 프레임의 모든 객체에 대한 대량 가상 호출은 끔찍한 아이디어입니다.

특정 객체에 사용되는 설계 는 시스템 전체에 대한 일부 이데올로기가 아닌 해당 객체의 요구를 기반으로해야합니다 .

첫 문장을 더 명확하게 편집했습니다.


안녕하세요 DeadMG, 설명하겠습니다 : 위에서 언급 한 경우, 디자인은 Appliaction layer (하드웨어 액세스), Game Logic, Game View의 세 가지 주요 부분으로 나뉩니다. 프레임 단위로 렌더링되는 것은 게임 뷰입니다. 그러나 Game View는 사용자 입력 (예 : 체 이싱 게임에서 브레이크 페달을 밟음)을 기록 할 때 처리를 위해 "Car 2 Brake Pressed"메시지를 Game Logic에 보냅니다. Game Logic은이 동작을 평가하고 자동차의 동작을 계산하며 "Car 2 Block Tires", "Car 2 Move to X, Y"라는 메시지를 게임보기로 보냅니다. 이런 식으로 모든 차량에서 브레이크를 밟으면 프레임 당 점검 할 필요가 없습니다.
Bunkai.Satori

@Bunkai : 이벤트 중심 디자인과 각 프레임이라고하는 디자인이 있습니다. 그것은 내 대답에 거의 동의합니다.
DeadMG

이 질문이 오늘 약간 논란의 여지가
있었기 때문에 이해해 드리겠습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.