मैं जावास्क्रिप्ट में ब्रांचिंग संवाद कैसे लागू कर सकता हूं?


11

मैं जावास्क्रिप्ट में खेल का एक बहुत ही मूल दृश्य उपन्यास प्रकार बना रहा हूं । मैं एक शुरुआत कर रहा हूं, इसलिए मैं सिर्फ मनोरंजन और सीखने के लिए ऐसा कर रहा हूं, और खराब योजना के कारण जब आप संवाद में एक शाखा में आते हैं तो मैं थोड़ी परेशानी में पड़ जाता हूं।

वर्तमान में मैं एक स्ट्रिंग चर में खेल के लिए स्क्रिप्ट रखता हूं और मैं प्रत्येक दृश्य को टैग के साथ तोड़ता हूं जैसे "# ~" छोटे सरणियों में ताकि खेल स्क्रिप्ट इस तरह दिखे:

var script = "Hello World!#~How are you today?"
var gameText = script.split("#~");
//gameText[0]= Hello World!

यह रैखिक सामान के लिए बहुत अच्छा काम करता है, लेकिन मुझे संवाद पेड़ की एक शाखा को कैसे संभालना चाहिए? यह विधि बहुत जटिल लगती है, क्योंकि मुझे यह जानना होगा कि प्रत्येक मार्ग कितना लंबा है और फिर अगर मुझे कभी भी कुछ भी बदलने की आवश्यकता है तो यह सिरदर्द होगा।

मैं इसे सरल तरीके से कैसे कर सकता हूं? मैं वैनिला जावास्क्रिप्ट से चिपके रहने की कोशिश कर रहा हूं क्योंकि मैं वेब रन टाइम के साथ काम करना चाहता हूं।


यह वीडियो आपको कुछ विचार दे सकता है: youtube.com/watch?v=XM2t5H7kY6Y
JCM

मुझे हाल ही में नोड का उपयोग करके इसके लिए कुछ विकसित करना पड़ा, और एक बहुत ही मूल पाठ फ़ाइल संरचना का विकल्प चुना। आप परिणामस्वरूप कोड और पाठ प्रारूप देख सकते हैं: github.com/scottbw/dialoguejs कोड GPL है, इसका उपयोग करने के लिए स्वतंत्र महसूस करें। मुझे यकीन है कि एक गैर-नोड जेएस गेम के लिए अनुकूलित करना मुश्किल नहीं होगा - अजाक्स के साथ "fs.load ()" भाग को बदलें।
स्कॉट विल्सन

इंकले स्टूडियो द्वारा विकसित इंक , एक शाखायुक्त कहानी पटकथा भाषा की जाँच करें । विभिन्न प्रोग्रामेटिक इंक इंटीग्रेशन (जावा, जावास्क्रिप्ट, सी #) और कई तृतीय पक्ष संसाधन हैं । कई व्यावसायिक खेलों में भी स्याही का उपयोग किया गया है। अंत में, एक डेस्कटॉप एडिटर है, इंकी जो आपके ब्रांचिंग संवादों को जांच और editor प्ले ’कर सकता है।
बिग रिच

जवाबों:


8

फिलिप का जवाब पहले से ही सही दिशा दिखाता है। मुझे लगता है कि डेटा संरचना अनावश्यक रूप से क्रिया है। छोटे ग्रंथों को लिखना और पढ़ना आसान होगा।

भले ही छोटे पाठ एल्गोरिथ्म को थोड़ा अधिक जटिल बना देंगे, लेकिन यह करने योग्य है, क्योंकि आप केवल एक बार एल्गोरिथ्म लिखते हैं, लेकिन आपका अधिकांश समय कहानी लिखने और बनाए रखने में व्यतीत होगा। इसलिए आसान बनाने के लिए ऑप्टिमाइज़ करें वह हिस्सा जिसे आप सबसे अधिक समय बिताएंगे।

var story = [
  { m: "Hi!" },
  { m: "This is my new game." },
  { question: "Do you like it?", answers: [
    { m: "yes", next: "like_yes" },
    { m: "no", next: "like_no" },
  ] },
  { label: "like_yes", m: "I am happy you like my game!", next: "like_end" },
  { label: "like_no", m: "You made me sad!", next: "like_end" },
  { label: "like_end" },
  { m: "OK, let's change the topic" }
];

इस डिजाइन के लिए कुछ स्पष्टीकरण:

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

ज्यादातर मामलों में, निम्न चरण की संख्या लिखना आवश्यक नहीं है। मैं मानता हूं कि पाठ की अधिकांश लाइनें शाखाएं नहीं हैं। चलो "अगला चरण निम्नलिखित आइटम है" एक डिफ़ॉल्ट धारणा है, और केवल तभी नोट करें जब यह अन्यथा हो।

छलांग के लिए, लेबल का उपयोग करें , संख्याओं का नहीं। फिर, यदि आप बाद में कुछ पंक्तियों को जोड़ते या हटाते हैं, तो कहानी के तर्क को संरक्षित किया जाएगा, और आपको संख्याओं को समायोजित करने की आवश्यकता नहीं है।

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

खेल के लिए एल्गोरिथ्म कुछ इस तरह होना चाहिए:

function execute_game() {
  var current_line = 0;
  while (current_line < story.length) {
    var current_step = story[current_line];
    if (undefined !== current_step.m) {

      display_message(current_step.m);
      if (undefined !== current_step.next) {
        current_line = find_label(current_step.next);
      } else {
        current_line = current_line + 1;
      }

    } else if (undefined !== current_step.question) {

      // display the question: current_step.question
      // display the answers: current_step.answers
      // choose an answer
      // and change current_line accordingly

    }
  }
}

वैसे, ये विचार Ren'Py से प्रेरित थे , जो कि वास्तव में आप क्या चाहते हैं (जावास्क्रिप्ट नहीं, वेब नहीं), लेकिन आप वैसे भी कुछ शांत विचार दे सकते हैं।


गहराई से समझाने के लिए धन्यवाद, मुझे इस बात की जानकारी नहीं थी कि सरणियां आपके और फिलिपींस के काम करने के तरीके को दिखा सकती हैं, मुझे लगा कि वे केवल स्ट्रिंग्स या संख्याओं को पकड़ सकते हैं।
साइलेंट कार्टोग्राफर

1
मैं आपके समाधान को लागू करने की कोशिश कर रहा हूं और यह काफी अच्छी तरह से काम करता है, हालांकि मुझे लगता है कि कुछ जगहों ({ label: "like_yes"; m: "I am happy you like my game!"; next: "like_end" },)पर ',' नहीं 'होना चाहिए।' इसके अलावा, वास्तव में घुंघराले ब्रेसिज़ में क्या चीज है? क्या यह सरणी के भीतर एक वस्तु है? अगर मुझे इस बारे में अधिक जानकारी चाहिए कि मैं इसका उपयोग कैसे करूंगा?
साइलेंट कार्टोग्राफर

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

1
btw ध्यान दें कि वह जिस डेटा संरचना की अनुशंसा करता है वह मूल रूप से JSON है। व्यक्तिगत रूप से मैं JSON के लिए सभी तरह से जाने की सलाह दूंगा (ज्यादातर घुंघराले कोष्ठक और एक "पेड़" जोड़ें: पूरी चीज़ के आसपास; जैसे {"पेड़": [आदि]}) और फिर आप बाहरी फ़ाइलों में अपने संवाद पेड़ों को संग्रहीत कर सकते हैं। अपने डेटा को बाहरी फ़ाइलों में डालते हुए कि आपका गेम लोड अधिक लचीला और मॉड्यूलर है (इसीलिए यह दृष्टिकोण एक सर्वोत्तम अभ्यास है)।
झॉकिंग

5

मैं आपको एक डायलॉग ईवेंट बनाने की सलाह दूंगा। प्रत्येक घटना एनपीसी कहती है और संभव खिलाड़ी प्रतिक्रियाओं की एक सरणी, पाठ के साथ एक वस्तु है, जो बदले में एक प्रतिक्रिया पाठ और इस प्रतिक्रिया पर होने वाली घटना के सूचकांक के साथ ऑब्जेक्ट हैं।

var event = []; // create empty array

// create event objects and store them in the array
event[0] = { text: "Hello, how are you?",
             options: [    { response: "Bad", next: 1 },
                           { response: "Good", next: 2 }
                      ]
           };
event[1] = { text: "Why, what's wrong?",
             options: [    { response: "My dog ran away", next: 3},
                           { response: "I broke up with my girlfriend", next: 4}
                      ]
           };
event[2] = { text: "That's nice",

...

2

आपको एक अलग दृष्टिकोण का उपयोग करना चाहिए। जावास्क्रिप्ट सरणियों और वस्तुओं का समर्थन करता है, इसलिए प्रति प्रविष्टि एक का उपयोग क्यों नहीं किया जाता है, जिससे आप सभी बंटवारे को बचा सकते हैं और वास्तविक पाठ को संपादित / पढ़ने में आसान बना सकते हैं?

यदि आप चाहें, तो आप कुछ प्रोटोटाइप पर नज़र डाल सकते हैं जो मैंने # 1 ग्राम के लिए कुछ घंटों के दौरान बनाया है । स्रोत GPLv3 के तहत उपयोग किए जाने के लिए स्वतंत्र है (यदि आप जीपीएल से चिपके नहीं हैं, तो आप पूरी तरह से ठीक हैं, यदि आप प्रेरणा के लिए इसे ले रहे हैं। लेकिन आपका गेम समाप्त होने के बाद मुझे बताएं।) बस कमाल लेखन या ऐसा कुछ भी उम्मीद नहीं है। ;)

कोड कैसे काम करता है, इस पर एक संक्षिप्त विवरण देने के लिए, सीएसएस एनीमेशन चीजों और सामानों की अनदेखी करना:

  • var data अनिवार्य रूप से सभी संभावित विकल्पों के साथ पूरी कहानी शामिल है, आदि।
  • प्रत्येक "स्थान" (या पृष्ठ / प्रविष्टि) की पहचान एक आईडी द्वारा की जाती है। सूची में पहली आईडी है start, दूसरी cwait, आदि।
  • प्रत्येक स्थान में दो अनिवार्य तत्व होते हैं: एक कैप्शन और साथ ही वास्तविक पाठ। निर्णय के लिए लिंक कुछ सरल मार्कअप में लिखे गए हैं जो फार्म ले रहे हैं [target location:display text]
  • पूरा "जादू" अंदर हो रहा है navigate(): यह फ़ंक्शन मार्कअप लिंक को क्लिक करता है। यह थोड़ा लंबा है, क्योंकि मैं मृत अंत के लिए कुछ स्थिर पाठ भी संभाल रहा हूं। महत्वपूर्ण हिस्सा पहले दो कॉल हैं replace()
  • वैकल्पिक अंतिम प्रविष्टियाँ मिश्रण करने के लिए नए पृष्ठभूमि के रंगों को परिभाषित करती हैं, खेल के समग्र मूड का समर्थन करती हैं।
  • इन रंगों को परिभाषित करने के बजाय आप अन्य स्थानों की ओर इशारा करते हुए लिंक जोड़ सकते हैं (ध्यान दें कि यह मेरे विज्ञापनों द्वारा संभाला नहीं गया है; यह प्रदर्शित करने के लिए बस कुछ विचार है):

    'start': ['Waking up', 'You wake...', 'cwait:yell for help', 'cwait: wait a bit', 'clook: look around']

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.