विषयसूची:

स्क्रैच 3.0 एक्सटेंशन: 8 कदम
स्क्रैच 3.0 एक्सटेंशन: 8 कदम

वीडियो: स्क्रैच 3.0 एक्सटेंशन: 8 कदम

वीडियो: स्क्रैच 3.0 एक्सटेंशन: 8 कदम
वीडियो: 1. Scratch Tutorial in Hindi - Introduction 2024, जुलाई
Anonim
स्क्रैच 3.0 एक्सटेंशन
स्क्रैच 3.0 एक्सटेंशन

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

जब मैं स्क्रैच 3.0 के लिए अपना Minecraft कंट्रोलिंग एक्सटेंशन बना रहा था, तो मुझे इसे शुरू करना मुश्किल लगा। यह निर्देश विभिन्न स्रोतों (विशेष रूप से यह) से एक साथ जानकारी एकत्र करता है, साथ ही कुछ चीजें जो मैंने खुद खोजी हैं।

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

मुख्य तरकीब भेड़टेस्टर के स्क्रैच के मॉड का उपयोग करना है जो आपको एक्सटेंशन और प्लगइन्स लोड करने देता है।

यह निर्देश आपको दो एक्सटेंशन बनाने में मार्गदर्शन करेगा:

  • प्राप्त करें: URL से डेटा लोड करना और JSON टैग निकालना, उदाहरण के लिए मौसम डेटा लोड करने के लिए
  • SimpleGamepad: स्क्रैच में गेम कंट्रोलर का उपयोग करना (एक अधिक परिष्कृत संस्करण यहां है)।

चरण 1: दो प्रकार के एक्सटेंशन

दो प्रकार के एक्सटेंशन हैं जिन्हें मैं "सैंडबॉक्स्ड" और "सैंडबॉक्स्ड" कहूंगा। सैंडबॉक्स वाले एक्सटेंशन वेब वर्कर्स के रूप में चलते हैं, और इसके परिणामस्वरूप महत्वपूर्ण सीमाएं हैं:

  • वेब वर्कर्स विंडो ऑब्जेक्ट में ग्लोबल्स तक नहीं पहुंच सकते हैं (इसके बजाय, उनके पास एक ग्लोबल सेल्फ ऑब्जेक्ट है, जो बहुत अधिक सीमित है), इसलिए आप गेमपैड एक्सेस जैसी चीजों के लिए उनका उपयोग नहीं कर सकते।
  • सैंडबॉक्स वाले एक्सटेंशन के पास स्क्रैच रनटाइम ऑब्जेक्ट तक पहुंच नहीं है।
  • सैंडबॉक्स वाले एक्सटेंशन बहुत धीमे होते हैं।
  • सैंडबॉक्स वाले एक्सटेंशन के लिए जावास्क्रिप्ट कंसोल त्रुटि संदेश क्रोम में अधिक गुप्त हैं।

दूसरी ओर:

  • अन्य लोगों के सैंडबॉक्स वाले एक्सटेंशन का उपयोग करना सुरक्षित है।
  • सैंडबॉक्स वाले एक्सटेंशन किसी भी आधिकारिक एक्सटेंशन लोडिंग समर्थन के साथ काम करने की अधिक संभावना रखते हैं।
  • सैंडबॉक्स वाले एक्सटेंशन को डेटा: // URL में एन्कोड करके वेब सर्वर पर अपलोड किए बिना परीक्षण किया जा सकता है।

आधिकारिक एक्सटेंशन (जैसे संगीत, पेन, आदि) सभी सैंडबॉक्स नहीं हैं। एक्सटेंशन के लिए कंस्ट्रक्टर स्क्रैच से रनटाइम ऑब्जेक्ट प्राप्त करता है, और विंडो पूरी तरह से सुलभ है।

फ़ेच एक्सटेंशन सैंडबॉक्स किया गया है, लेकिन गेमपैड को विंडो से नेविगेटर ऑब्जेक्ट की आवश्यकता है।

चरण 2: सैंडबॉक्स वाला एक्सटेंशन लिखना: भाग I

एक एक्सटेंशन बनाने के लिए, आप एक वर्ग बनाते हैं जो इसके बारे में जानकारी को एन्कोड करता है, और फिर एक्सटेंशन को पंजीकृत करने के लिए थोड़ा सा कोड जोड़ता है।

एक्सटेंशन क्लास में मुख्य बात एक getInfo () विधि है जो एक ऑब्जेक्ट को आवश्यक फ़ील्ड के साथ लौटाती है:

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

और एक वैकल्पिक मेनू फ़ील्ड है जो फ़ेच में उपयोग नहीं किया जाता है लेकिन गेमपैड में उपयोग किया जाएगा।

तो, यहाँ फ़ेच के लिए मूल टेम्पलेट है:

क्लास स्क्रैचफ़ेच {

कंस्ट्रक्टर () { } getInfo () {रिटर्न {"आईडी": "फ़ेच", "नाम": "फ़ेच", "ब्लॉक": [/* बाद में जोड़ें */]}} / * ब्लॉक के लिए तरीके जोड़ें */} Scratch.extensions.register(नया ScratchFetch ())

चरण 3: सैंडबॉक्स वाला एक्सटेंशन लिखना: भाग II

अब, हमें getInfo () के ऑब्जेक्ट में ब्लॉक की सूची बनाने की आवश्यकता है। प्रत्येक ब्लॉक को कम से कम इन चार क्षेत्रों की आवश्यकता होती है:

  • opcode: यह उस विधि का नाम है जिसे ब्लॉक का कार्य करने के लिए कहा जाता है
  • ब्लॉक टाइप: यह ब्लॉक प्रकार है; एक्सटेंशन के लिए सबसे आम हैं:

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

    • टाइप करें: या तो "स्ट्रिंग" या "नंबर"
    • defaultValue: पहले से भरा जाने वाला डिफ़ॉल्ट मान।

उदाहरण के लिए, यहां मेरे फ़ेच एक्सटेंशन में ब्लॉक फ़ील्ड है:

"ब्लॉक": [{ "ऑपोड": "fetchURL", "ब्लॉक टाइप": "रिपोर्टर", "टेक्स्ट": "[यूआरएल] से डेटा प्राप्त करें", "तर्क": { "यूआरएल": { "टाइप": "स्ट्रिंग", "डिफॉल्टवैल्यू ": "https://api.weather.gov/stations/KNYC/observations" }, }}, { "opcode": "jsonExtract", "blockType": "reporter", "text": "extract [name] [डेटा]", "तर्क" से: { "नाम": { "प्रकार": "स्ट्रिंग", "डिफ़ॉल्ट वैल्यू": "तापमान"}, "डेटा": { "प्रकार": "स्ट्रिंग", "डिफ़ॉल्ट वैल्यू": '{"तापमान": 12.3}' }, } },]

यहां, हमने दो ब्लॉक परिभाषित किए हैं: fetchURL और jsonExtract। दोनों पत्रकार हैं। पहला URL से डेटा खींचता है और उसे वापस करता है, और दूसरा JSON डेटा से एक फ़ील्ड निकालता है।

अंत में, आपको दो ब्लॉकों के लिए विधियों को शामिल करने की आवश्यकता है। प्रत्येक विधि एक वस्तु को एक तर्क के रूप में लेती है, जिसमें वस्तु सभी तर्कों के लिए फ़ील्ड सहित होती है। आप तर्कों में घुंघराले ब्रेसिज़ का उपयोग करके इन्हें डीकोड कर सकते हैं। उदाहरण के लिए, यहाँ एक तुल्यकालिक उदाहरण है:

jsonExtract ({नाम, डेटा}) {

वर पार्स = JSON.parse (डेटा) अगर (पार्स में नाम) { var out = पार्स [नाम] var t = typeof (आउट) अगर (t == "स्ट्रिंग" || t == "नंबर") अगर वापस आ जाए (टी == "बूलियन") टी वापसी? 1: 0 JSON.stringify (बाहर) लौटाएं} और {वापसी ""}}

कोड JSON डेटा से नाम फ़ील्ड खींचता है। यदि फ़ील्ड में एक स्ट्रिंग, संख्या या बूलियन है, तो हम उसे वापस कर देते हैं। अन्यथा, हम फ़ील्ड को फिर से JSONify करते हैं। और अगर JSON से नाम गायब है तो हम एक खाली स्ट्रिंग लौटाते हैं।

कभी-कभी, हालांकि, आप एक ऐसा ब्लॉक बनाना चाह सकते हैं जो एसिंक्रोनस एपीआई का उपयोग करता हो। fetchURL () विधि फ़ेच एपीआई का उपयोग करती है जो एसिंक्रोनस है। ऐसे मामले में, आपको अपने तरीके से एक वादा वापस करना चाहिए जो काम करता है। उदाहरण के लिए:

fetchURL({url}) {

वापसी फ़ेच (यूआरएल)। फिर (प्रतिक्रिया => प्रतिक्रिया। पाठ ())}

बस, इतना ही। पूर्ण विस्तार यहाँ है।

चरण 4: सैंडबॉक्स वाले एक्सटेंशन का उपयोग करना

सैंडबॉक्स वाले एक्सटेंशन का उपयोग करना
सैंडबॉक्स वाले एक्सटेंशन का उपयोग करना
सैंडबॉक्स वाले एक्सटेंशन का उपयोग करना
सैंडबॉक्स वाले एक्सटेंशन का उपयोग करना
सैंडबॉक्स वाले एक्सटेंशन का उपयोग करना
सैंडबॉक्स वाले एक्सटेंशन का उपयोग करना

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

My fetch.js को https://arpruss.github.io/fetch.js पर होस्ट किया गया है। या आप अपने एक्सटेंशन को यहां अपलोड करके डेटा URL में बदल सकते हैं और फिर उसे क्लिपबोर्ड पर कॉपी कर सकते हैं। एक डेटा यूआरएल एक विशाल यूआरएल है जिसमें एक पूरी फाइल होती है।

भेड़ परीक्षक के स्क्रैच मोड पर जाएं। निचले-बाएँ कोने में एक्सटेंशन जोड़ें बटन पर क्लिक करें। फिर "एक एक्सटेंशन चुनें" पर क्लिक करें, और अपना यूआरएल दर्ज करें (यदि आप चाहें तो पूरे विशाल डेटा यूआरएल में पेस्ट कर सकते हैं)।

यदि सब कुछ ठीक रहा, तो आपके पास अपनी स्क्रैच स्क्रीन के बाईं ओर अपने एक्सटेंशन के लिए एक प्रविष्टि होगी। अगर चीजें ठीक नहीं हुईं, तो आपको अपना जावास्क्रिप्ट कंसोल (Chrome में shift-ctrl-J) खोलना चाहिए और समस्या को डीबग करने का प्रयास करना चाहिए।

ऊपर आपको कुछ उदाहरण कोड मिलेंगे जो यूएस नेशनल वेदर सर्विस के केएनवाईसी (न्यूयॉर्क में) स्टेशन से JSON डेटा को प्राप्त और पार्स करते हैं, और इसे प्रदर्शित करते हैं, जबकि स्प्राइट को उसी तरह से मोड़ते हैं जैसे हवा चल रही है। जिस तरह से मैंने इसे बनाया, वह डेटा को वेब ब्राउज़र में लाकर और फिर टैग का पता लगाना था। यदि आप किसी भिन्न मौसम स्टेशन को आज़माना चाहते हैं, तो weather.gov पर खोज बॉक्स में पास का ज़िप कोड दर्ज करें, और आपके स्थान के लिए मौसम पृष्ठ आपको चार अक्षर वाला स्टेशन कोड देगा, जिसका उपयोग आप KNYC के स्थान पर कर सकते हैं। कोड।

आप "?url=" तर्क जोड़कर अपने सैंडबॉक्स वाले एक्सटेंशन को सीधे भेड़टेस्टर के मॉड के URL में शामिल कर सकते हैं। उदाहरण के लिए:

sheeptester.github.io/scratch-gui/?url=https://arpruss.github.io/fetch.js

चरण 5: सैंडबॉक्स न किया गया एक्सटेंशन लिखना: परिचय

सैंडबॉक्स न किए गए एक्सटेंशन के कंस्ट्रक्टर को एक रनटाइम ऑब्जेक्ट पास किया जाता है। आप इसे अनदेखा कर सकते हैं या इसका इस्तेमाल कर सकते हैं। रनटाइम ऑब्जेक्ट का एक उपयोग घटनाओं ("टोपी ब्लॉक") को सिंक्रनाइज़ करने के लिए अपनी currentMSecs संपत्ति का उपयोग करना है। जहां तक मैं कह सकता हूं, सभी इवेंट ब्लॉक ऑपकोड नियमित रूप से मतदान किए जाते हैं, और मतदान के प्रत्येक दौर में एक ही currentMSecs मान होता है। यदि आपको रनटाइम ऑब्जेक्ट की आवश्यकता है, तो आप संभवतः अपना एक्सटेंशन इसके साथ शुरू करेंगे:

कक्षा विस्तारकक्षा {

कंस्ट्रक्टर (रनटाइम) {this.runtime = रनटाइम …} …}

सैंडबॉक्स न किए गए एक्सटेंशन में सभी मानक विंडो ऑब्जेक्ट चीज़ों का उपयोग किया जा सकता है। अंत में, आपका सैंडबॉक्स न किया गया एक्सटेंशन इस बिट मैजिक कोड के साथ समाप्त होना चाहिए:

(समारोह() {

var एक्सटेंशनइंस्टेंस = नया एक्सटेंशन क्लास (विंडो.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension(extensionInstance) window.vm.extensionManager._loadedExtensions.set(extensionInstance.getInfo().id, serviceName)})()

जहां आपको EXTENSIONCLASS को अपने एक्सटेंशन की कक्षा से बदलना चाहिए।

चरण 6: सैंडबॉक्स न किया गया एक्सटेंशन लिखना: साधारण गेमपैड

आइए अब एक साधारण गेमपैड एक्सटेंशन बनाते हैं जो एक बटन दबाए जाने या रिलीज़ होने पर एकल ईवेंट ("टोपी") ब्लॉक प्रदान करता है।

प्रत्येक घटना ब्लॉक मतदान चक्र के दौरान, हम रनटाइम ऑब्जेक्ट से टाइमस्टैम्प को सहेजेंगे, और पिछले और वर्तमान गेमपैड स्थिति। टाइमस्टैम्प का उपयोग यह पहचानने के लिए किया जाता है कि हमारे पास एक नया मतदान चक्र है या नहीं। तो, हम इसके साथ शुरू करते हैं:

क्लास स्क्रैच सिंपलगेमपैड {

कंस्ट्रक्टर (रनटाइम) { यह। रनटाइम = रनटाइम यह। करंटएमएसईसी = -1 यह। पिछला बटन = यह। करंटबटन = } …} हमारे पास एक ईवेंट ब्लॉक होगा, जिसमें दो इनपुट होंगे - एक बटन नंबर और एक मेनू यह चुनने के लिए कि क्या हम चाहते हैं कि ईवेंट प्रेस या रिलीज़ पर ट्रिगर हो। तो, ये है हमारी विधि

जानकारी मिलना() {

वापसी {"आईडी": "सिंपलगेमपैड", "नाम": "सिंपलगेमपैड", "ब्लॉक": [{"ऑपोड": "बटनप्रेसेड रिलीज", "ब्लॉक टाइप": "हैट", "टेक्स्ट": "बटन [बी] [इवेंट टाइप]", "तर्क": {"बी": {"टाइप": "नंबर", "डिफॉल्टवैल्यू": "0"}, "इवेंट टाइप": { "टाइप": "नंबर", "डिफॉल्टवैल्यू": "1 ", "मेनू": "pressReleaseMenu" }, }, },], "मेनू": { "pressReleaseMenu": [{text:"press", value:1}, {text:"release", value:0}], } }; } मुझे लगता है कि ड्रॉप-डाउन मेनू में मान अभी भी संख्याओं के रूप में घोषित होने के बावजूद, ओपोड फ़ंक्शन को स्ट्रिंग्स के रूप में पास कर दिए जाते हैं। इसलिए आवश्यकतानुसार मेनू में निर्दिष्ट मानों के विरुद्ध उनकी स्पष्ट रूप से तुलना करें। अब हम एक ऐसी विधि लिखते हैं जो बटन को अपडेट करती है जब भी कोई नई घटना मतदान चक्र होता है

अपडेट करें() {

अगर (this.runtime.currentMSecs == this.currentMSecs) वापसी // कोई नया मतदान चक्र नहीं this.currentMSecs = this.runtime.currentMSecs var gamepads = navigator.getGamepads() if (gamepads == null || gamepads.length = = 0 || गेमपैड्स [0] == नल) { यह। पिछला बटन = यह। करंटबटन = रिटर्न} वर गेमपैड = गेमपैड्स [0] अगर (गेमपैड। बटन। लंबाई! = यह। पिछला बटन। लंबाई) { // अलग-अलग संख्या में बटन, इसलिए नया गेमपैड this.previousButtons = for (var i = 0; i <gamepad.buttons.length; i++) this.previousButtons.push(false)} else { this.previousButtons = this. currentButtons } this.currentButtons = for (var i = 0; i <gamepad.buttons.length; i++) this.currentButtons.push(gamepad.buttons.pressed) } अंत में, हम अपने ईवेंट ब्लॉक को अपडेट () विधि को कॉल करके और फिर वर्तमान और पिछले बटन राज्यों की तुलना करके जांच कर सकते हैं कि अपेक्षित बटन अभी दबाया या जारी किया गया है या नहीं

बटन दबाया रिलीज ({बी, इवेंट टाइप}) {

this.update() if (b < this.currentButtons.length) {if (eventType == 1) {// नोट: यह एक स्ट्रिंग होगी, इसलिए इसे बूलियन के रूप में मानने की तुलना में 1 से तुलना करना बेहतर है यदि (this.currentButtons && ! this.previousButtons) {रिटर्न ट्रू}} और {if (!this.currentButtons && this.previousButtons) {रिटर्न ट्रू}}} रिटर्न फॉल्स} और अंत में हम क्लास को परिभाषित करने के बाद अपना मैजिक एक्सटेंशन रजिस्ट्रेशन कोड जोड़ते हैं

(समारोह() {

वर एक्सटेंशनइंस्टेंस = नया स्क्रैचसिंपलगेमपैड (विंडो.vm.extensionManager.runtime) वर सर्विसनाम = window.vm.extensionManager._registerInternalExtension(extensionInstance) window.vm.extensionManager._loadedExtensions.set(extensionInstance.getInfo().id, serviceName)})()

आप यहां पूरा कोड प्राप्त कर सकते हैं।

चरण 7: सैंडबॉक्स न किए गए एक्सटेंशन का उपयोग करना

सैंडबॉक्स न किए गए एक्सटेंशन का उपयोग करना
सैंडबॉक्स न किए गए एक्सटेंशन का उपयोग करना

एक बार फिर, अपने एक्सटेंशन को कहीं पर होस्ट करें, और इस बार इसे भेड़टेस्टर के स्क्रैच मोड में url= तर्क के बजाय load_plugin= के साथ लोड करें। उदाहरण के लिए, मेरे सरल गेमपैड मॉड के लिए, यहां जाएं:

sheeptester.github.io/scratch-gui/?load_plugin=https://arpruss.github.io/simplegamepad.js

(वैसे, यदि आप अधिक परिष्कृत गेमपैड चाहते हैं, तो उपरोक्त URL से "सरल" को हटा दें, और आपके पास गड़गड़ाहट और एनालॉग अक्ष समर्थन होगा।)

फिर से, एक्सटेंशन आपके स्क्रैच संपादक के बाईं ओर दिखाई देना चाहिए। ऊपर एक बहुत ही सरल स्क्रैच प्रोग्राम है जो जब आप बटन 0 दबाते हैं तो "हैलो" और जब आप इसे छोड़ते हैं तो "अलविदा" कहते हैं।

चरण 8: दोहरी संगतता और गति

मैंने देखा है कि सैंडबॉक्स न किए गए एक्सटेंशन के लिए उपयोग की जाने वाली लोडिंग विधि का उपयोग करके एक्सटेंशन ब्लॉक तेजी से परिमाण का क्रम चलाते हैं। इसलिए जब तक आप वेब वर्कर सैंडबॉक्स में चलने के सुरक्षा लाभों की परवाह नहीं करते हैं, तब तक आपके कोड को ?load_plugin=URL तर्क के साथ भेड़ परीक्षक के मॉड में लोड होने से लाभ होगा।

आप एक्सटेंशन क्लास को परिभाषित करने के बाद निम्न कोड का उपयोग करके दोनों लोडिंग विधियों के साथ सैंडबॉक्स वाले एक्सटेंशन को संगत बना सकते हैं (CLASSNAME को अपने एक्सटेंशन क्लास के नाम से बदलें):

(समारोह() {

वर एक्सटेंशन क्लास = क्लासनाम अगर (टाइपऑफ विंडो === "अपरिभाषित" || !window.vm) {स्क्रैच.एक्सटेंशन्स.रजिस्टर (नया एक्सटेंशनक्लास ())} और {var एक्सटेंशनइंस्टेंस = नया एक्सटेंशनक्लास (विंडो.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension(extensionInstance) window.vm.extensionManager._loadedExtensions.set(extensionInstance.getInfo().id, serviceName) } })()

सिफारिश की: