XNA를 사용한 게임 아키텍처에 관한 질문


12

그래서 마침내 XNA를 가지고 놀았고 2D 게임을 만들면서 놀았습니다 (iOS에서 그것을 개발 한 친구의 많은 예술 자산이 있습니다)

많은 것들이하기 쉽고 상자에서 나오는 것처럼 보이지만 대부분의 문헌 (예를 들어 구입 한 책들)은 2D에 너무 많은 관심을 기울이지 않기 때문에 많은 것들에 푹 빠져 있습니다.

다음 질문에 대한 설명이나 자세한 정보를 알려 주셔서 감사합니다.

  1. 게임 서비스의 요점은 무엇입니까? 객체를 서비스로 등록하는 다른 관용구를 이해하여 다른 GameComponent가 그것을 잡을 수는 있지만 어떻게 공개 또는 정적으로 만들 수 있습니까? 예를 들어 필자의 책은 Game.cs 클래스에 SpriteBatch 객체를 등록 할 것을 권장했습니다. 어쨌든 Game (Singleton) 인스턴스가 하나만 있어야하기 때문에 단순히 공개 / 정적으로 만드는 것이 어떻게 바람직한 지 잘 모르겠습니까?

  2. GameComponent 또는 RenderableGameComponent에서 상속해야 할 때 혼란 스럽습니다. 모든 엔티티가 단일 관리자에 의해 작성되고 소유되고 다른 것들과 동일하게 관리자 / 컨트롤러 디자인을 따르려고합니다. 나는 현재 각 Manager / Controller가 GameComponent에서 상속 받았지만, Game 객체가 모든 Manager를 소유하고 수동으로 업데이트를 호출하고 그립니다.

  3. Initialize가 ContentLoad () 전에 호출되는 것을 알았습니다. Initialize 에서 일부 엔티티 (예 : Sprite, Player 등)를 만들고 싶기 때문에이 성가신 것을 알았습니다. SpriteSheets 또는 Textures는로드 요청이 아직 발생하지 않았으므로 아직 발생하지 않았습니다. 아마도 초기화가 잘못되었거나 사람들이 ContentLoad에서 텍스처를 더 아래로 할당합니까?

그것들은 정말로 이해하지 못하는 나의 가장 큰 " WTF "인 것 같습니다

답변:


11

귀하의 질문에 대한 대답은 간단합니다. 간단 하고 작동 하는 것을 이상적으로 수행하십시오 . 내장 아키텍처를 사용하는 것은 종종 쉽지 않습니다. 왜냐하면 당신이 찾은대로 원하는 방식으로 게임을 구성하기 위해 농구대를 뛰어 넘어야하기 때문입니다.

질문 1에 답하기 위해 "서비스를 사용하는 이유는 무엇입니까?" . 짧은 대답은 서비스가 자체 포함 된 게임에서 절대로 발생 하지 않는 커플 링 (버전 관리, 종속성, 확장 성) 문제를 피하는 좋은 방법 이라는 것입니다 . 대부분의 시간을 그냥 멤버 수 있도록 간단합니다 public(심지어 아마도과 static더 흥미로운 문제에 대한 걱정은 서둘러 경우).

두 번째 질문에 답하기 위해 "게임 오브젝트의 모든 인스턴스에 DrawableGameComponent를 사용하는 이유는 무엇입니까?" 게임 아키텍처에 대한 나의 생각 . 짧은 대답은 GameComponent단순히 자신 만의 클래스를 작성 Draw하고 Update자신 과 같은 메소드를 호출하는 것 이상의 이점이 없다는 것입니다. GameComponent원하는 아키텍처와 정확히 일치하는 경우 반드시 사용하십시오. 그러나 거의 항상 그렇지 않습니다.

타사 소 비용 라이브러리를 구축하는 경우에만 서비스 및 구성 요소 사용이 흥미로워집니다. 그것을 가지고 - XNA 자신이 수행 IGraphicsDeviceService하고 GamerServicesComponent, 예를 들면. 이는 게임 개발시 일반적으로 겪지 않는 특정 디커플링 요구 사항을 충족합니다.

마지막으로 세 번째 질문에 대한 답변은 매우 간단합니다 LoadContent. 특별한 것은 없습니다 Initialize.

전체 Microsoft.Xna.Framework.Game어셈블리가 선택 사항 임을 지적하는 것이 좋습니다. 그것은 매우 유용한 출발점을 제공하지만 결코 일을하는 "올바른 방법"으로 간주되어서는 안됩니다.


그것을 보는 매우 흥미로운 방법. 내 대답보다 훨씬 더 현실적이고 땅에 떨어졌습니다. +1 자격이 있습니다.
Jesse Emond

질문이 하나 더 있습니다! Texture2D를 그릴 때 원점은 어떻습니까? 텍스처의 하단 중앙에 원점을 배치하는 것이 일반적입니까? 애니메이션을 만들려고하는데 폭과 높이가 같지 않으면 (0,0)에서 원점을 갖는 것이 텍스처가 약간 이동하는 것을 발견했습니다
Setheron

@Setheron : 원래 질문과는 관련이 없으므로 새로운 질문을 만들어야합니다. 이 질문에 대한 편집 내용을 되 돌리겠습니다. 의 원점 SpriteBatch.Draw은 텍스처의 왼쪽 상단 (또는 사용하는 경우 소스 사각형)을 기준으로 텍스처 픽셀 좌표로 지정됩니다.
앤드류 러셀

1
@Andrew : 최근에 게임을 리팩터링하여 전적으로 public/ static속성 대신 서비스를 기반으로했습니다 . 왜? 테스트 가능성. 속성 접근 방식으로 항목을 전환하는 것은 거의 불가능하지만 모든 것이 초기화되어 IServiceProvider테스트 방법에 필요한 클래스로 채워질 수 있다면 사소한 것입니다 . 또한 Game테스트에서 객체 자체 를 인스턴스화 할 필요가 없으므로 매우 지저분합니다.
Matthew Scharley

옆으로, 나는 여전히 Game객체 에 대한 많은 공공 재산을 가지고 있습니다 . 그들은 인터페이스를 통해 액세스 할 수 있으며 인터페이스를 통해 Game.Services모든 것을 전달하여 다시 필요한 것을 얻습니다.
Matthew Scharley

3

첫 번째 질문에 대해서는 실제 답변을 실제로 모른다는 것을 인정해야합니다. 싱글 톤이 일반적으로 나쁜 디자인 패턴 인 이유와 같은 이유 일 것입니다. 이 링크 의 인용문을 알려 드리겠습니다 .

우리가 생각한 첫 번째 (및 서비스 도입의 이유 중 하나)는 게임에서 GraphicsDevice 참조를 사용할 수있게하는 것이 었습니다. 원래 게임에는 GraphicsDevice를 소유하고 Game.GraphicsDevice와 같은 속성을 통해이를 공개했습니다. 이것에 대한 문제는 GraphicsDevice를 게임에 단단히 묶어 다른 사람이 장치를 (예 : 렌더러) 소유 할 수 없으며 누군가가 최신 버전의 Game을 제공하지 않고 향후 업데이트 된 GraphicsDevice를 사용하지 못하게한다는 것입니다. 이전 버전과 호환되지 않습니다.

두 번째 질문의 경우 구성 요소 기반 접근 방식을 따르는 경우 구성 요소를 사용하는 것이 더 유용 할 것 Sprite입니다. 모든 스프라이트를 업데이트하고 그리는 방법을 알고있는 관리자. 동의합니다. 소리는 같지만 객체 기반 접근 방식을 정말로 좋아하기 때문에 구성 요소 기반 디자인을 선호합니다.

세 번째 질문의 경우, LoadContent 메서드에 모든 형식의 내용 (자산, 글꼴 등)을로드해야합니다. 초기화에 대해서는 일반적으로 Initialize 함수 내에 Player 객체를 만든 다음 해당 내용을 LoadContent 내에로드합니다. 또는 원하는 경우 LoadContent 내에서 모두 수행 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.