2010-12-20 12 views
12

मैं खिलाड़ी के आस-पास के मिनी मानचित्र के साथ एक ब्राउज़र गेम बना रहा हूं। मुझे यह ट्रैक करने की ज़रूरत है कि अन्य खिलाड़ी कहां हैं और जब भी कोई चलता है तो इस मिनी मानचित्र को अपडेट करें। मैं इसे नोडजेएस और कॉच डीबी में कार्यान्वित कर रहा हूं। मेरा डिज़ाइन निम्नानुसार है:मैं नोडजेएस में "नींद" का अनुकरण कैसे करूं?

मेरे पास सभी बदलते गेम डेटा के लिए डेटाबेस है। इस डेटाबेस में, मेरे पास एक दस्तावेज़ है जिसमें दो आयामी सरणी में मूल नक्शा डेटा शामिल है, जिसमें ग्रिड पर प्रत्येक वर्ग को इस सरणी में किसी तत्व द्वारा दर्शाया जा रहा है। चूंकि मेरे पास मानचित्र के साथ-साथ कई अलग-अलग उपयोगकर्ता भी हो सकते थे, इसलिए मुझे यह सुनिश्चित करने के लिए कुछ रास्ता चाहिए कि मुझे कोई पढ़ा न जाए क्योंकि कोई और इसे लिख रहा है (यदि उपयोगकर्ता का एक टन पढ़ रहा है तो मुझे दोषपूर्ण जानकारी मिल सकती है और एक दस्तावेज़ को लिखना)। मैंने इस डेटाबेस में अलग-अलग दस्तावेज़ रखने का निर्णय लिया जो व्यक्तिगत वर्गों का प्रतिनिधित्व करते हैं, और प्रत्येक दस्तावेज़ में ऐसे खिलाड़ी होते हैं जो उस वर्ग पर "कुछ" होते हैं और उस वर्ग से जुड़े कुछ अन्य डेटा होते हैं। अनिवार्य रूप से, नक्शा दस्तावेज़ स्क्वायर दस्तावेज़ के लिए केवल लुकअप टेबल के रूप में उपयोग किया जाता है। यह मुझे एक साथ दस्तावेज़ को फिर से लिखने के बिना एक ही दस्तावेज़ को बदलने में सक्षम बनाता है, साथ ही साथ पढ़ने और लिखने की समस्या को हल करता है।

मेरी समस्या, हालांकि, मुझे संदर्भ के रूप में उपयोग करने के लिए उपयोगकर्ता के लिए मिनी मानचित्र प्राप्त करने की आवश्यकता है। इस मिनी मानचित्र में आसपास के वर्गों के दस्तावेज होंगे। चूंकि मुझे एक ही समय में यह सब चाहिए, मैंने सोचा कि मैं डेटाबेस से सभी 9 वर्गों को पकड़ लेगा और इसे एक अजाक्स प्रतिक्रिया में वापस कर दूंगा। मेरी समस्या हालांकि आईओ अवरुद्ध करने की मात्रा को कम करने के साथ है। अभी, मेरे पास एक नेस्टेड लूप है जो मुझे डेटाबेस से आवश्यक वर्गों का अनुरोध करता है।

var miniMap = new Array(); 
var keyMap = new Object(); 
var numDone = 0; 
for(i = position.y - 1, y = 0; i < position.y + 1 && i < map.length; i++, y++){ 
    miniMap[i] = new Array(); 
    for(v = position.x - 1, x = 0; v < position.x + 1 && v < map.length; v++, x++){ 
     keyMap[map[i][v].id] = {'x': x, 'y': y}; 
     gameDB.getDoc(map[i][v].id, function(er, doc){ 
      var tPos = keyMap[doc._id]; 
      miniMap[tPos.y][tPos.x] = doc; 
      numDone++; 
     }); 
    } 
} 

मेरे समस्या, हालांकि, कि getDoc गैर अवरुद्ध है है, इसलिए मैं नहीं जानता कि जब यह minimap वर्ग डेटा सेट हो जाएगा: यहाँ (स्थिति और मानचित्र में पारित कर रहे हैं) मेरे कोड पर एक नज़र है । मैं कुछ इस तरह कर रही है के बारे में सोचा:

while(numDone < 9){ 
    sleep(10); 
} 
callback(miniMap); 

यह मैं जब तक CouchDB अपने डेटा के सभी हो रही समाप्त हो गया है, लेकिन जावास्क्रिप्ट एक सोने समारोह नहीं है इंतज़ार करने देगा। मैंने पाया सबसे नज़दीकी सेटटाइमआउट था, लेकिन यह भी गैर-अवरुद्ध है और मैं कभी भी 100% सुनिश्चित नहीं करूँगा कि टाइमआउट के लिए मैंने जो समय चुना है वह सोफेडबी को अपना डेटा प्राप्त करने की अनुमति देने के लिए पर्याप्त होगा।

तो मूल रूप से मैं एक शर्त रखना चाहता हूं, इसका परीक्षण करूँगा, फिर स्थिति को गलत होने पर इसे फिर से स्टैक पर वापस कर दें।

function testCallback(data, condition, callback){ 
    if(data < condition){ 
     setTimeout(function(){ 
      testCallback(data, condition, callback); 
     }, 10); 
    }else{ 
     callback(data); 
    } 
} 

यह सुंदर भयानक लगती है ... वहाँ एक बेहतर तरीका है कि मैं यह कर किया जा सकता है है: एकमात्र समाधान मैं के बारे में सोचा एक पुनरावर्ती setTimeout कॉलबैक कि कुछ इस तरह करना होगा करने के लिए था? क्या मुझे इस दृष्टिकोण को छोड़ देना चाहिए और अद्यतन डेटा प्राप्त करने के लिए कई AJAX कॉल होने के लिए मजबूर होना चाहिए? क्या मुझे अवरुद्ध दृष्टिकोण के लिए जाना चाहिए?

उत्तर

5

बस एक और कॉलबैक का उपयोग करें:

function getMiniMap(....., callback) { // supply the callback that sends the data 
    var miniMap = new Array(); 
    var keyMap = new Object(); 
    var numDone = 0; 
    ... 
       numDone++; 
       if (numDone === 9) { // as soon as everything has been collected... 
        callback(miniMap); // ... call the send callback and supply it the miniMap 
       } 
      }); 
     } 
    } 
} 

ओह, और अपने डेटाबेस मॉडल वास्तव में बुरा है, मैं अपने खेल के बारे में ज्यादा पता नहीं है, लेकिन जब तक यह कई नोड प्रक्रियाओं पर चलने की जरूरत है, यह एक जेएस ऐरे में मानचित्र इत्यादि रखना बेहतर होगा और सर्वर को राज्य को सहेजने की आवश्यकता होने पर केवल डीबी को लिखें।

ओह और आप भी एक गुमनाम समारोह कॉल के साथ अपने keyMap की जगह ले सकता:

(function(x, y) { 
     gameDB.getDoc(map[i][v].id, function(er, doc){ 
      var tPos = keyMap[doc._id]; 
      miniMap[tPos.y][tPos.x] = doc; 
      numDone++; 
     }); 
    })(x, y); // pass in a copy of x and y 
+1

मुझे लगता है कि मैं नक्शा भाग को गलत कर रहा हूं। डेटाबेस की बजाय स्मृति में सबकुछ रखना निश्चित रूप से चीजों को करने का एक आसान तरीका होगा। मुझे लगता है कि मैं आगे बढ़ जाऊंगा और सबकुछ अपने मैप दस्तावेज़ में रखूंगा और केवल तब ही राज्य को बचाऊंगा जब मुझे रीबूट या कुछ करना होगा। सहायता के लिए धन्यवाद!! – tjameson

+1

यह भी देखें [रेडिस] (http://redis.io/)। आप रेडिस-सर्वर शुरू करते हैं और फिर नोड में रेडिस मॉड्यूल का उपयोग करते हैं। आप एक स्ट्रिंग कुंजी और फिर एक जेसन ऑब्जेक्ट देते हैं, और बीएएम सभी बच्चों और डेटा को सहेजा जाता है। इसे लोड करें और फिर ऑब्जेक्ट के रूप में स्मृति में वापस लाने के लिए कुंजी का उपयोग करें। – BigOmega

+0

आप इस प्रकार की राज्य जानकारी के लिए रेडिस या एक रिलेशनल डेटास्टोर के विकल्प के रूप में [फायरबेस] (http://firebase.com) पर भी विचार कर सकते हैं। फायरबेस राज्य को वास्तविक समय में सभी संलग्न ग्राहकों को सिंक करेगा। यह आपके प्रकार के आवेदन के लिए डिज़ाइन किया गया था। – DrFriedParts

1

को देखते हुए हम घटना एड प्रणाली के बारे में बात कर रहे हैं, मुझे लगता है कि यह क्लीनर हो सकता है अगर तुम सिर्फ एक लोड किया घटना फेंकना कर सकते हैं जब numDone == 9 और इसे अपने मुख्य से पकड़ें और वहां से आगे बढ़ें।

आप पूरे मानचित्र को लाल रंग में डाल सकते हैं, यहां तक ​​कि गेम को कई नोड्स में चलाने की आवश्यकता है।

संबंधित मुद्दे

 संबंधित मुद्दे