2011-08-06 8 views
5

जावास्क्रिप्ट/नोडजेएस गेम में कई कक्षाओं से निपटने पर, मुझे यह समझने में परेशानी हो रही है कि किस वर्ग को घटनाओं को उत्सर्जित करना चाहिए और किस वर्ग को सुनना चाहिए। http://pragprog.com/magazines/2011-08/decouple-your-apps-with-eventdriven-coffeescriptप्रत्येक ऑब्जेक्ट के साथ एक नोडजेएस गेम में कक्षा के रूप में, घटनाओं का इलाज कैसे किया जाना चाहिए?

मैं एक छोटे से खेल लिख रहा हूँ और निम्नलिखित नियंत्रकों में मेरी कक्षाओं विभाजित किया है:: मैं बनाने घटना पर ही आधारित खेल के लिए इस गाइड का पालन कर रहा हूँ

दुनिया - खेल दुनिया बनाता है और के एक नंबर के माध्यम से प्रगति कुछ सरल खेल तर्क निर्धारित करने के लिए 'मोड़' (यानी एक चरित्र को स्थानांतरित करना चाहिए, एक टावर शूट करना चाहिए)।

टावर - एक टावर 10x10 ग्रिड पर बैठता है और इसकी एक श्रृंखला है। जब कोई ऑब्जेक्ट रेंज में आता है, तो यह शूट कर सकता है।

mobs (दुश्मन) - एक भीड़ 10x10 ग्रिड पर फैलती है और हर 3 सेकंड में जाती है। किसी बिंदु पर, यह एक टावर की रेंज में घूमता है।

मैं पूरे दिन EventEmitters के बारे में पढ़ रहा हूं लेकिन मेरी घटनाओं को आर्किटेक्ट करने का सही तरीका नहीं लग रहा है। जब लोग आगे बढ़ते हैं तो मोब्स एक घटना को आग लगाना चाहिए, और टावर एक 'चाल' घटना के लिए सुनना चाहिए? या दुनिया को सभी घटनाओं को नियंत्रित करना चाहिए और टावर/मोब्स दुनिया को सुनना चाहिए?

उदाहरण कोड के लिए नीचे देखें।

पृष्ठभूमि: मैं नोडजेएस के लिए एक साधारण टॉवरडी गेम पर काम कर रहा हूं और पहले सर्वर को लागू करने का फैसला किया। मैं मोंगोडीबी में सभी इकाइयों को संग्रहित कर रहा हूं और यह निर्धारित करने के लिए भू-स्थानिक गणना का उपयोग कर रहा हूं कि वस्तुओं को शूट करने की सीमा है या नहीं। वर्तमान में मैं गेम को 'टिक' करने और तर्क प्रगति के लिए एक प्राथमिक 3 सेकंड लूप का उपयोग कर रहा हूं लेकिन मैं वास्तव में घटना-संचालित मॉडल में जाना चाहता हूं और संघर्ष कर रहा हूं।

दुनिया:

exports.World = class World extends EventEmitter 

    constructor: -> 
    ### Initial config ### 
    @gameTime = 3000 # every 3000ms, the game progresses 

    ### Start the game!! ### 
    @game = setInterval -> 
     world.gameLoop() 
    , @gameTime 

    ### Load the map ### 
    # First level: Hidden Valley 
    @maps = [] 
    @maps.push new map 'hiddenvalley' 

### Load the mobs ### 
    # First map has one mob: Warrior 
    @mobs = [] 

    # Let's create two of them 
    @mobs.push new mob @maps[0].mobs[0] 
    @mobs.push new mob @maps[0].mobs[0] 

(पूर्ण world.coffee देखें: https://github.com/bdickason/node-towerd/blob/master/controllers/world.coffee)

टॉवर:

exports.Tower = class Tower 
    constructor: (name) -> 
    name = name.toLowerCase() # In case someone throws in some weird name 

    # Check for anything within range 
    checkTargets: (callback) -> 
    mobModel.find { loc : { $near : @loc , $maxDistance : @range } }, (err, hits) -> 
     if err 
     console.log 'Error: ' + err 
     else 
     callback hits 

(पूर्ण towers.coffee देखें: https://github.com/bdickason/node-towerd/blob/master/controllers/towers.coffee)

भीड़:

exports.Mob = class Mob extends EventEmitter 

    move: (X, Y, callback) -> 
    @loc = [@loc[0] + X, @loc[1] + Y] 
    newloc = @loc 
    mobModel.find { uid: @uid }, (err, mob) -> 
     if(err) 
     console.log 'Error finding mob: {@uid} ' + err 
     else 
     mob[0].loc = newloc 
     mob[0].save (err) -> 
      if (err) 
      console.log 'Error saving mob: {@uid} ' + err 
    console.log 'MOB ' + @uid + ' [' + @id + '] moved to (' + @loc[0] + ',' + @loc[1] + ')' 

(mobs.coffee का पूरा स्रोत देखें: https://github.com/bdickason/node-towerd/blob/master/controllers/mobs.coffee)

परियोजना के पूर्ण स्रोत: https://github.com/bdickason/node-towerd

किसी भी घटना मदद की सराहना की जाएगी। मैं GitHub पर लगभग 15 NodeJS खेल पर डाला गया है और इस पद्धति का उपयोग कर अभी तक :(

उत्तर

2

मुझे लगता है कि "अभिभावकों", जैसे घटना प्रचार बुदबुदाती का समर्थन करता है एक कस्टम EventEmitter प्रयोग करेंगे किसी को भी नहीं मिला है। तो मैं यह करना होगा निम्नलिखित तरीके:।

  • भीड़ चलता है, यह {mob: @,x: x, y: y} की तरह एक पैरामीटर (घटना उस समय के विश्व के लिए ऊपर बुलबुले) के साथ ही एक "चाल" ईवेंट सक्रिय जब
  • दुनिया "चाल" के लिए सुनता है घटनाएं। जब इसे एक प्राप्त होता है, तो यह उन टावरों को देखने के लिए डेटाबेस में जांचता है जिन्हें अधिसूचित करने की आवश्यकता होती है और उन पर घटना को उत्सर्जित करने की आवश्यकता होती है।
+1

अहहा सुंदर पेरेंट इवेंट एमिटर चीज: डी सुनिश्चित करें कि आप सिस्टम के डिजाइन पर कुछ समय बिताएं। जैसे ऑब्जेक्ट का समूह देना ताकि आप "golbin.move" के लिए दुनिया को सुन सकें और कॉलबैक पैराम्स में गोब्लिन, वर्ल्ड इत्यादि में आप प्रत्येक स्तर पर पहुंच जाएं। –

+0

धन्यवाद thejh और Ivo, ये महान सुझाव हैं! मुझे थोड़ा सा समझ रहा है कि 'बुलबुले अप' अवधारणा है लेकिन बाकी सब कुछ स्पष्ट है। क्या आप त्वरित उदाहरण के साथ गोब्लिन या दुनिया में 'अनशिफ्ट' को स्पष्ट कर सकते हैं? –

+1

निश्चित रूप से, कल्पना करें कि गोब्लिन को एक चाल चलाना है। ग्लोबिन पर श्रोताओं को इस तरह की कुछ दिखती है 'goblin.bind (' move ', function (x, y) {'अब दुनिया पर श्रोताओं को' world.bind ('goblin.move', function (goblin, x 'जैसा दिखता है , वाई) {'और –