Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 引擎脚本和类结构_C#_Xna - Fatal编程技术网

C# 引擎脚本和类结构

C# 引擎脚本和类结构,c#,xna,C#,Xna,我已经开始用C#/XNA编写2d JRPG引擎,我对类结构和游戏事件有一些疑问 在“game maker”类型的环境中,您有一个基于用户输入运行事件等的游戏脚本。这通常不是面向对象的,也没有对类等的引用 现在在我自己的引擎中,编码游戏事件的最佳方式是什么 假设您在屏幕上与NPC交互,那么在OO语言中如何处理该事件?我假设在character类中有一个事件,并且我假设该事件将被分配到加载地图的部分中,但是该事件将链接到哪里?哪个类将包含事件逻辑 编辑:我应该注意到,我不想把它变成一个完全可定制的引

我已经开始用C#/XNA编写2d JRPG引擎,我对类结构和游戏事件有一些疑问

在“game maker”类型的环境中,您有一个基于用户输入运行事件等的游戏脚本。这通常不是面向对象的,也没有对类等的引用

现在在我自己的引擎中,编码游戏事件的最佳方式是什么

假设您在屏幕上与NPC交互,那么在OO语言中如何处理该事件?我假设在character类中有一个事件,并且我假设该事件将被分配到加载地图的部分中,但是该事件将链接到哪里?哪个类将包含事件逻辑

编辑:我应该注意到,我不想把它变成一个完全可定制的引擎,供其他人使用,因此一个完整的脚本语言实现并不是我真正想要的

class Character {
...
public delegate void InteractionEventHandler(object sender, EventArgs e);
...
public event InteractionEventHandler Interact;

...

}

class Map {

public Map(){

...

//add a new character to the NPC collection
newchar.Interact += ???
...
}

}
目前我的类结构相当简单,因为我需要在进一步研究之前解决这个问题,但它看起来是这样的

Main类包含Map类的一个实例

Map类通过内容管道加载xml格式的地图

映射实例包含对映射中包含的所有对象和NPC的引用

Map类创建这些对象的新实例,这些实例都继承自Drawable类,该类包含将对象绘制到屏幕所需的基本方法和属性。这些实例都添加到Map类中的集合中

Character类是从Drawable类继承的类之一,将包含Interact事件

正如我所说的,该项目是基于固定时间步长的XNA框架的,因此引擎在主类中运行Update和Draw方法


update方法包含处理播放器输入的逻辑。因此,玩家可以移动到地图上的NPC并按下“交互”按钮。逻辑检查玩家面前的NPC并触发其交互事件。。。那么会发生什么呢?

事件不应该附加任何逻辑;它们仅仅是一条信息,一种告诉感兴趣的组件发生了什么的技术,但如何处理事件是所述组件(又名监听器)的责任。在您的情况下,这就是您的NPC

但我不理解你关于“事件不是OO”的论点,是什么让你相信的?什么是不能面向对象的事件

现在如何处理事件和整个过程,我没有C语言的经验,但是我已经完成了C++的部分,这是我反复使用的一种方法,它对我的需求来说是足够灵活的:

我有一个事件元类,每个特定的事件都可以从中派生子类(即UI事件、NPC事件等)。还有一个EventManager,它创建和销毁所有事件(“发射器”,即需要触发事件的组件,将调用实例(即GameObjects)的管理器),最重要的是,它具有处理队列

发射器对象将把事件“挂钩”到队列,EventManager将把它们分派给“侦听器”。现在,侦听器对事件感兴趣,因此可以将自己注册到某些事件或其类型。一旦管理器将事件分派给这些侦听器,就由它们从那时起执行与该事件相关的逻辑

最终,拥有一个事件元类(我必须从中保持子类化)的设计对我来说不是很灵活,这是一项乏味的工作,因此我采用了另一种方法,可以将属性任意附加到事件对象,处理组件必须知道如何处理它。当然,这对性能有影响,但它对我来说是必要的,因为我触发和处理Lua中的事件逻辑,而不是C++。 如果你正在制作一个RPG游戏,事件和脚本几乎是游戏的主要部分,在开始编写代码之前,你需要对这两个方面进行清晰的设计。我建议先阅读关于事件处理的文章

最后,我不确定它是否会对您有所帮助,但我曾经在用C++/Lua制作网络游戏时发布过一次关于事件的帖子,考虑到网络游戏的性质,设计可能比您需要的更复杂,但您还是可以查看它

更新:我将向您展示一个如何使用我的系统的示例,但我必须首先明确:您使用C#和XNA是有原因的,我不会错认为XNA提供了您所需要的,因此我建议不要使用我的事件管理系统或任何人的系统,由于我的紧密耦合到C++及其模板机制,可能对你没有用。框架应该为您提供您所需要的,所以请首先检查一下

// singleton
class EventManager {
  public:
  Event* createEvt<EventType*>();
  void subscribe(Event*, Listener*);
  void hook(Event*);
  void update();
}

class Listener {
  // tells evt manager we want to listen to these events
  void register(Event* someEvtType, Handler* myMethod);

  // adds event to the queue (called by the EventManager)
  void enqueue(Event* someEvt); 

  // processes events in the queue
  void process();

  protected:
  // calls every subscribed handler to process the event
  // a handler is only a functor that is bound to an event
  // when calling "register()"
  void dispatch(Event*);

  map<Event*, list<Handler*>> myHandlers; // an event could have multiple handlers (methods)
}

class GameObject : public Listener {

}

class NPC : public GameObject {
  protected:
    void walkTo(NPCEvent_Walk* evt);
    void talk(NPCEvent_Talk* evt);
}

// inside wherever you're gonna trigger the event, i presumed on mouseclick here
void InputManager::mouseClicked(MouseEvent* evt) {
  // we want the NPC to move
  NPCEvent_Walk* evtWalk = EventManager->createEvt<NPCEvent_Walk>();
  evtWalk->setX(...);
  evtWalk->setY(...);
  // and talk
  NPCEvent_Talk* evtTalk = EventManager->createEvt<NPCEvent_Talk>();
  evtTalk->setText(...);

  // when the master queue is empty, these events will be
  // dispatched to their registered Listeners which will
  // process them on their own terms
  EventManager->hook(evtWalk);
  EventManager->hook(evtTalk);
}

// as an NPC, i'd like to be notified of NPCEvents
NPC::NPC() {
  register(NPCEvent_Walk*, &NPC::walkTo);
  register(NPCEvent_Talk*, &NPC::talk);
}

void NPC::walkTo(NPCEvent_Walk*) {
  // move it
  // ...

  // are we done?
  //  return true;
  // if we need more updates, return false and we will be called again
  //  return false;
}

void NPC::talk(NPCEvent_Talk*) {
  // update UI components or whatever
  // ...
  return true;
}
//单例
类事件管理器{
公众:
事件*createvt();
无效订阅(事件*,侦听器*);
无效挂钩(事件*);
无效更新();
}
类侦听器{
//告诉evt经理我们要收听这些事件
无效寄存器(事件*somevettype,处理程序*myMethod);
//将事件添加到队列(由EventManager调用)
无效排队(事件*somevt);
//处理队列中的事件
无效过程();
受保护的:
//调用每个订阅的处理程序来处理事件
//处理程序只是绑定到事件的函子
//调用“register()时”
无效派送(事件*);
map myHandlers;//一个事件可以有多个处理程序(方法)
}
类游戏对象:公共侦听器{
}
NPC类:公共游戏对象{
受保护的:
无效步行(NPCEvent_步行*evt);
无效谈话(NPCEvent_talk*evt);
}
//在你要触发事件的任何地方,我猜是在鼠标点击这里
void InputManager::mouseClicked(MouseEvent*evt){
//我们希望全国人大采取行动
NPCEvent_Walk*evtWalk=EventManager->createvt();
evtWalk->setX(…);
evtWalk->setY(…);
//说
NPCEvent_Talk*evtTalk=Ev