2011-09-22 4 views
5

먼저 막연하게 보일 수도있는 질문을 사과하겠습니다.하지만 좀 더 구체적으로 묻는 경험이 없습니다.C# 2D 게임에서 객체의 구조

저는 C#에서 2D 어드벤처 게임 (you-click-on-an-object-and-happen-happen sort)을 수행하기위한 엔진을 구축하고 있습니다. 당신이 상상할 수 있듯이, 당신이 물건과 상호 작용할 때 다른 일이 일어날 수 있습니다. 그것이 문이라면, 다른 방에 들어가기를 기대합니다. 사람이라면, 당신은 그들과 이야기하기를 시작할 것입니다. 제 생각은이 행동을 성취하는 것입니다. 이 같은 대표로 :

나는 그것의 클래스에 포함되지 어떤 행동과 특별한 개체를 만들려면 때문에 나는이 솔루션 기품 찾을
public abstract class GameObject { 
    public delegate void onAction(); 
    public onAction Click; 
} 

public class Door : GameObject { 
    public Door() { 
     Click = new onAction(ChangeRoom); 
    } 
    private void ChangeRoom() { 
     //code to change room here 
    } 
} 

public class Person : GameObject { 
    public Person() { 
     Click = new onAction(StartTalking); 
    } 
    private void StartTalking() { 
     //code to display dialogue here 
    } 
} 

, 나는 단순히이 작업을 수행 할 수 있습니다

specialObject.Click += new onAction(SpecialMethod); 

그러나 이것은 또한 복잡한 일입니다. 내 엔진이 엔진 자체를 변경하지 않고 다른 데이터를로드하여 다른 게임을 수행 할 수 있기를 원합니다. 따라서 엔진 내부의 SpecialMethod를 하드 코딩하는 것은 옵션이 아니며 데이터의 일부 여야합니다. 일반 객체의 경우 직렬화를 통해 모두 수행 할 수 있지만 읽은 내용은 대리자와 관련하여 문제가됩니다. 그것을 할 수있는 방법을 제안 해 주시겠습니까?

피고 : 아직 개념 수준에 있고 위의 코드가 아직 구현되지 않았기 때문에 최상의 결과를 얻을 수있는 솔루션을 제안 할 수 있으며 심지어 대리인을 완전히 피할 수 있습니다.

+0

규칙 엔진을 설명하는 것처럼 들리네. http://martinfowler.com/bliki/RulesEngine.html – Jodrell

+1

이 질문을 http://gamedev.stackexchange.com/ – Luca

+0

에 게시 할 수 있습니다. @luca에 감사드립니다. 링크. 언뜻보기에는 분명하지만,이 포럼은 나보다 조금 더 프로 보입니다. –

답변

1

먼저 글쓰기 엔진이 부족할 때 경험이 부족할 수 있습니다. 나는 당신이 원하는만큼 엔진과 하드 코드없이 첫 번째 게임을 작성한 다음 경험에서 배우고 엔진을 쓴다는 것을 제안 할 것입니다 ... D

만약 당신이 원한다면 아직 확인했습니다 http://www.adventuregamestudio.co.uk/을보고 편집자와 함께하고 객체 모델을 생각하십시오. 도움이 될거야.

게임을 데이터 중심으로 만들기 위해서는 코드를 동적으로로드하고 실행할 수 있어야합니다. "스크립팅 언어 일 필요는 없습니다." 스크립팅 언어를 추가하고 엔진을 만드는 방법을 배우는 동시에 학습하는 것이 좋습니다. .NET Framework에는 C# 코드를로드하고 런타임에 컴파일 할 수있는 훌륭한 리플렉션 시스템이 있습니다. 나는 이것이 C#에서 스크립팅의 종류라고 지적해야하지만 스크립팅 언어의 적절한 정의가 부족합니다.

내 제안에 많은 경험이 없으므로 방을 정의하고 뭔가를 클릭했을 때 일어날 일을 정의하는 기본 노드 시퀀스가있는 XML 파일을 사용하는 것이 좋습니다. "엔진"에 모든 명령을 구현해야하지만 유사한 게임을 쉽게 새 방을 만들 수 있습니다. XML은 계층 적 구조로 인해 엔진의 "스크립팅"기능을 확장하는 조건, 루프 등을 추가 할 수 있기 때문에 매우 확장 가능한 접근 방식이 될 것입니다.

+0

몇 가지 생각을하고 여러 옵션을 탐색 한 결과 실제로이 답변이 가장 유용하다는 것을 알았습니다. 그것은 당신이 일을 지나치게 복잡하게 만들 필요가 없다는 것을 상기시켜 주었고, 제가 처음으로 사용할 수있는 아이디어를 나에게주었습니다. 감사합니다! –

1
당신은 당신의 엔진에 하드 코드에 SpecialMethod 기능이 필요하지 않습니다

, 당신은 당신의 엔진을 사용하는 다른 게임에서 사용할 수 있습니다 :

var starTrekDoor = new Door(); 
starTrekDoor.Click += SlideDoorUpward; 
:
var medievalDoor = new Door(); 
medievalDoor.Click += OpenDoorNormally; 

그러나 다른 게임에서

Click 이벤트가 노출되는 한 아무 것도 엔진에 하드 코딩 할 필요가 없습니다. 엔진을 DLL 참조로 사용할 수있는 게임에 넣을 수 있습니다.

+0

만약'medievalDoor.Click + OpenDoorNormally'가 엔진 레벨에서 정의되고, 그가 맹금류라고 생각되는 경우 게임 데이터를 변경할 때마다 엔진 코드를 수정해야합니다. – InBetween

0

어떤 특별한 행동을 실행하는 '결정'이 게임 개체 자체에 남아있는 경우 문제가 보이지 않습니다. 엔진을 결정하기를 원할 경우 엔진이 실제로 원하지 않는 게임 정의의 결정을 내리는 것처럼 호환되지 않는 디자인 스펙을 가지고 있다고 생각합니다.

게임 개체에 ISpecialBehaviorProvider 필드를 만들고 필요할 때 적절한 값으로 설정하십시오 (생성자, 공개 속성, 무엇을 가지고 있는지).

사용자가 을 클릭 할 때마다 엔진에서 항상 GameObject.Click을 실행합니다. 그러나 specialBehaviorProvider이 null 인 경우 GameObject.Click을 '클래스'코드로 실행하십시오. 그렇지 않으면 ISpecialBehaviorProvider.SpecialMethod을 호출하십시오.

이 방법으로 엔진은 호출 할 메소드를 결정하지 않습니다.

+0

예, 제 아이디어는 엔진이 게임 체크를하지 않고 적절할 때'GameObject.Click'을 실행하는 것입니다. 하지만 여전히, 나는 "외부에서"어떤 객체의 특수한 동작을 전달할 수 있어야합니다. 다음 대답이 제시 할 때, 나는 스크립팅에 대해 배울 것입니다. –

0

여기서 주목할 점은 이것들이 클래스이기 때문에 입니다. polymorphism은 가상의 Click 메소드를 사용하면 꽤 이상적입니다.

대리인은 실제로 직렬화 방식에 따라 serializer에서 까다로울 수 있습니다.BinaryFormatter 이 될 것이지만, 나는 그 serializer가 일반적으로 모든 비용으로 회피되는 경향이있다.

가능한 경우 맞춤 설정에 표준 구현의 하위 클래스를 지정하고 다형성을 사용하는 것이 좋습니다. 을 데이터를 통해 순전히으로 정의해야한다면, 본질적으로 스크립팅 엔진을 구현할 수 있습니다. IronPython이 유용 할 수 있습니다. 게임 lua는 꽤 일반적입니다 (Lua.NET을 아주 쉽게 사용할 수 있어야합니다). 그런 다음 작업과 연결된 선택적 스크립트를 가질 수 있으며 (데이터에 정의 된) 스크립트를 호출 할 수 있습니다.

+0

나는 개체의 행동의 90 %가 다형성에 의해서만 정의 될 수 있다고 말하고 싶습니다. 문제는 (평소와 같이) 나머지 10 %에 있습니다. BinaryFormatter를 피하는 이유는 무엇입니까? (나는이 분야에서도 꽤 새로운 편이다.) –

3

필요한 것은 스크립팅입니다.

기본적으로 스크립트는 동작을 설명하는 소스 코드가 포함 된 외부 리소스 (즉, 외부 파일)입니다.

C#에는이 옵션이 다릅니다.

.NET 언어에서 어셈블리를 내보낼 수 있습니다. 또는 다른 언어 (예 : Python)를 통합하고 런타임에 스크립트를 실행할 수도 있습니다. 본질적으로 스크립트는 적절한 시간에로드, 해석 또는 컴파일되고 실행됩니다. 스크립트가 응용 프로그램 상태 (데이터 구조)를 수정할 수 있으면 외부 데이터 (데이터 기반 개발)로 객체 비헤이비어를 정의 할 수 있습니다.

이 문제에 관한 많은 문헌이 있지만, GPU Programming Gems 6 (4 절)을 제안합니다. 그러나 훌륭한 스크립팅 엔진을 통합하는 데 필요한 노력은 대단히 중요합니다. 그런 식으로 XML 파일 (here 내 질문에 대한 간단한 논리를 알아 내려고, XML 내용을 정의하기 위해 또 다른 question 합류); 슬프게도, 나는 당신이 필요로하는 융통성에 거의 달려 있다는 것을 알았습니다.

+0

+1 스크립팅. IronLanguages는 .NET 응용 프로그램에 통합하기가 쉽고 C#과의 상호 운용성이 매우 뛰어납니다. https://github.com/IronLanguages/main – robbrit

관련 문제