gpt4 book ai didi

c# - 引擎脚本和类结构

转载 作者:太空宇宙 更新时间:2023-11-03 16:50:34 25 4
gpt4 key购买 nike

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

在“游戏制作者”类型的环境中,您有一个游戏脚本,它根据用户输入运行事件等。这通常不是 OO,也没有对类等的引用。

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

假设您在屏幕上与 NPC 互动,该事件将如何用 OO 语言处理?我假设我会在角色类中有一个事件,并且我假设该事件将分配给加载 map 的部分,但该事件将链接到哪里?哪个类将包含事件逻辑?

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

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 中的 map 。

map 实例包含对 map 中包含的所有对象和 NPC 的引用。

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

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

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

更新方法包含处理玩家输入的逻辑。因此玩家可以移动到 map 上的 NPC 并按下交互按钮。逻辑检查玩家面前的 NPC 并触发其交互事件...然后会发生什么?

最佳答案

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

但我不明白您关于“事件不是 OO”的论点,是什么让您相信这一点?不能面向对象的事件是怎么回事?

现在关于如何处理事件和整个流程,我没有使用 C# 的经验,但我已经完成了 C++ 的分享,这是我反复使用的一种方法,它足够灵活,可以满足我的需求:

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

Emitter 对象会将事件“ Hook ”到队列,EventManager 会将它们分派(dispatch)给“Listeners”。现在,Listener 对事件感兴趣,因此可以将自己注册到某些事件或其类型。一旦管理器向这些监听器分派(dispatch)了一个事件,它们就可以从那里执行与该事件相关的逻辑。

最终,我必须保留子类化的事件元类的设计对我来说不是很灵活,而且是一项乏味的工作,所以我采用了另一种方法,我可以将属性任意附加到事件对象,并且处理组件必须知道如何处理它。这当然会对性能产生影响,但在某种程度上这对我来说是必要的,因为我在 Lua 中触发和处理事件逻辑,而不是在 C++ 中。

如果您正在制作一款 RPG 游戏,那么事件和脚本几乎是您游戏的主体,在开始编写代码之前,您确实需要对这两个方面进行清晰的设计。我建议阅读有关 Gamedev.net 的事件处理文章一开始。

最后,我不确定它是否对你有帮助,但我在用 C++/Lua 制作网络游戏时发布了一次关于事件的帖子,考虑到网络的性质,设计可能比你需要的更复杂游戏,但你可以看看here无论如何。

更新:我将向您展示我将如何使用我的系统的示例,但我必须首先明确:您使用 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;
}

显然,这段代码将无法工作,因为它缺少所有实现细节,甚至在语法上也不正确,但它应该会给您一个想法。但是,正如我上面所说,如果您使用的是 XNA,则不需要执行此操作。

关于c# - 引擎脚本和类结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4089900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com