2016-03-30 9 views
2

そして "実用的な方法"私は、それがゲームのスピードを妨げないような方法で意味します。HaxeFlixelのゲーム内イベントを「実用的な方法」でコーディングする方法は?

私はRPGのプログラミングだ、とあなたの多くは知っている、彼らはイベントのFULLです:

  1. あなたはイベントがいくつかの会話が起こる

  2. をトリガーする新しい部屋に入ります文字とnpcsの間の話を展開する

  3. しかし、あなたがその部屋に再び入ると何も起こりません。

(この場合は6で)値であればブール値の配列があるEventReg.hxマップが変化(のは、それが6のマップに行くとしましょう)するたびに、それはクラスでチェックするように、私は私のゲームをコード化真であり、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

役立つリンクがいくつかあります。次のイベントを持つhaxeflixel rpgベースコードプロジェクトがあります:https://github.com/kevinresol/flixel-rpgまた、私はhaxeflixelに束縛されていないイベントのためにmsignalを愛しています(したがって、ループの種類がなく、うまくいかないかもしれません)。https://github.com/massiveinteractive/msignal – 5Mixer

+0

パフォーマンスのボトルネック?利用可能なイベントのチェック?フレーム更新機能?すべての部屋で何百ものイベントが開催されていない限り、これはパフォーマンスに何ら変わるものではないと思いますが、そうはいかないでしょう。一般に、パフォーマンスは、ゲームロジックではなく、画像のレンダリング、グラフィックス、オーディオ、アセットのロードおよびアンロードなどの影響を受けます。 –

+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サブスクライバを実装する唯一の理由は、複雑なイベントをサポートすることであり、その前提条件(他のイベント)が満たされると、イベントは発生します。しかし、これがあなたにとって過酷な場合は、この機能を削除してコードを単純化することができます。

関連する問題