以" 实用方式"我的意思是它可能不会妨碍游戏的速度。
我正在为RPG编程,而且正如你们许多人所知,他们已经完成了很多事件:
你走进一个事件触发的新房间
在chars和npcs
但是当你重新进入那个房间时没有任何反应。
我编写了我的游戏编码,以便每次地图更改时(让我们说它转到地图6)它会在类EventReg.hx中检查Bool数组,如果值(在这种情况下为6)是为true,并将其复制到PlayState.hx中的变量 eventAvailable 。
然后在更新函数中,它根据地图编号运行事件,但我觉得这种方法需要在PlayState.hx中以交换机的形式拥挤的大量代码(将当前地图的值作为参考)。
有没有人知道一些开源RPG,示例或教程处理这个问题? TIA!
示例:
//Event Helper
private var eventAvailable:Bool;
private var currentMap:Int = MapReg.currentMap;
override public function create():Void
{
//Checks if there's an even in the current map.
eventAvailable = EventReg.isEvent[currentMap];
if (eventAvailable)
setupEvent();
}
private function setupEvent():Void
{
switch(currentMap)
{
case 0: //code
case 1: //code
}
}
答案 0 :(得分:0)
处理事件的有效方法可能类似于Observer Pattern。我已经使用了这种模式的变体来处理我正在使用的平台游戏库,其中观察者将订阅某个特定事件。它对我来说非常好,所以我想我可以分享它。
这是我的基类:
1)BaxEventSubscriber
interface BaxEventSubscriber {
function getNotified(baxEventKey:String):Void;
}
2)BaxEvent
class BaxEvent implements BaxEventSubscriber
{
public var id:String;
/** Event will be fired when all prequisite events are triggered.
* Once a prequisite is satisfied, it will be removed from this list.
* When the list is empty, the event will trigger */
public var prequisiteEvents:Array<String>;
/**
* If serialExecution is true, the prequisites must be executed in a serialised order (first to last)
* In other words, every prequisite will be satisfied only if it is first in the prequisited list
*
* If serial execution is false (default, the prequisites can be satisfied in any order)
*/
public var serialExecution : Bool = false;
public function new (id:String)
{
if (id == null) {
throw "any Event should have an id";
}
this.id = id;
prequisiteEvents = new Array<String>();
}
public function addPrequisite(key:String):Void {
if (key == null || key.length == 0) {
return;
}
var isUnique:Bool = true;
for (i in 0...prequisiteEvents.length) {
var ss:String = prequisiteEvents[i];
if (ss == key) {
isUnique = false;
}
}
if (isUnique) {
prequisiteEvents.push(key);
BaxEventManager.getManager().addSubscriberForEvent(this, key);
}
}
public function getNotified(baxEventKey:String):Void {
this.eventTriggered(baxEventKey);
}
public function eventTriggered(key:String):Void {
var isPrequisite :Bool = false ;
for ( i in 0...prequisiteEvents.length) {
var ss:String = prequisiteEvents[i];
if (ss == key) {
isPrequisite = true;
}
}
if (isPrequisite) {
var ind:Int = prequisiteEvents.indexOf(key);
// If no serialExecution, checkout this event.
// Else, check it out only if it's the first on the prequisites list
if (! serialExecution || ind == 0 ) {
prequisiteEvents.splice(ind, 1);
}
}
// if all prequisites are satisfied, fite the Event
if (prequisiteEvents.length == 0) {
BaxEventManager.getManager().broadcastEvent(this.id);
}
}
}
3)BaxEventManager
class BaxEventManager
{
/** the names of registered Events */
public var events:Array<BaxEvent>;
/**
* Objects that need to be notified for a certain event
*
* structure:
* [key] = event name (as in events[])
* subscribers : Array<BaxEventSubscriber> : an array of subcribers for this Event
*/
public var eventSubscribers : StringMap<Array<BaxEventSubscriber>>;
private static var eventManager:BaxEventManager;
public static inline function getManager():BaxEventManager {
if (eventManager == null)
return eventManager = new BaxEventManager();
else
return eventManager;
}
private function new() {
trace(" BaxEventManager CONSTRUCT");
events = new Array<BaxEvent>();
eventSubscribers = new StringMap<Array<BaxEventSubscriber>>();
}
/**
* Registers an event's key, and an array with Subscribers for it. FailSafe, as it checks if event already exists
* @param key
*/
public function addEvent(key : String):Void {
//trace("check to add key :"+key);
var alreadyExists :Bool = false;
for ( i in 0...events.length) {
var ss :String = events[i].id;
if ( ss == key ) {
//trace("key " + key + " exists");
alreadyExists = true;
break;
}
}
if (!alreadyExists) {
events.push( new BaxEvent(key) );
var subscribers : Array<BaxEventSubscriber> = new Array<BaxEventSubscriber>();
eventSubscribers.set(key , subscribers);
}
}
public function addSubscriberForEvent(subscriber:BaxEventSubscriber, eventKey:String):Void {
this.addEvent(eventKey);
var subscribers :Array<BaxEventSubscriber> = eventSubscribers.get(eventKey);
subscribers.push(subscriber);
}
public function broadcastEvent(evt:String) : Void {
if (evt == null) {
return;
}
var subscribers :Array<BaxEventSubscriber> = eventSubscribers.get(evt);
if (subscribers != null && subscribers.length > 0) {
for ( i in 0...subscribers.length) {
var sub:BaxEventSubscriber = subscribers[i];
sub.getNotified(evt);
}
}
}
/**
* Clears up the registered Events and their subscribers.
* Make sure to Call this when resseting a level, as the subscribers might be nullified
*/
public function clearEvents():Void {
ArrayUtils.emptyArray(events);
eventSubscribers = null;
eventSubscribers = new StringMap<Array<BaxEventSubscriber>>();
}
}
在我的实际实现中,我还使用了不同类型的事件,这些事件定义事件是否应该在每个游戏会话中注册(和触发)一次,或者是否会被触发,或者将被无限触发。现在我正在考虑它,我应该将它包含在BaxEvent类中。
无论如何,关键在于这个设计
事件管理器是一个单例类,但您也可以将其设计为静态实用程序类。
BaxEvent实现Event订阅者的唯一原因是支持复杂事件,以便在满足其先决条件(其他事件)时触发它们。但是,如果这对您来说太过分了,您可以删除此功能并简化代码。