Tartalomjegyzék:

Scratch 3.0 kiterjesztések: 8 lépés
Scratch 3.0 kiterjesztések: 8 lépés

Videó: Scratch 3.0 kiterjesztések: 8 lépés

Videó: Scratch 3.0 kiterjesztések: 8 lépés
Videó: Installing VSCode with PlaformIO and building MarlinFW 2024, November
Anonim
Scratch 3.0 bővítmények
Scratch 3.0 bővítmények

A Scratch kiterjesztések olyan Javascript kódrészletek, amelyek új blokkokat adnak hozzá a Scratchhez. Bár a Scratch egy csomó hivatalos bővítményt tartalmaz, nincs hivatalos mechanizmus a felhasználó által készített bővítmények hozzáadásához.

Amikor elkészítettem a Minecraft vezérlő bővítményemet a Scratch 3.0 számára, nehezen tudtam elindulni. Ez az Instructable összegyűjti a különböző forrásokból származó információkat (különösen ebből), valamint néhány dolgot, amelyeket magam fedeztem fel.

Tudnia kell, hogyan programozhat Javascript -ben, és hogyan tárolhatja Javascriptjét egy webhelyen. Utóbbihoz a GitHub Pages -t ajánlom.

A fő trükk a SheepTester Scratch modjának használata, amely lehetővé teszi a bővítmények és bővítmények betöltését.

Ez az utasítás két kiterjesztés létrehozásában nyújt segítséget:

  • Lekérés: adatok betöltése URL -ből és JSON -címkék kinyerése, például időjárási adatok betöltéséhez
  • SimpleGamepad: játékvezérlő használata a Scratch alkalmazásban (itt van egy kifinomultabb verzió).

1. lépés: Kétféle kiterjesztés

Kétféle kiterjesztés létezik, amelyeket "homokozónak" és "homokozónak" nevezek. A homokozó dobozos bővítmények webmunkásként futnak, és ennek következtében jelentős korlátaik vannak:

  • A webmunkások nem férhetnek hozzá az ablak objektumban található globális értékekhez (ehelyett globális önobjektumuk van, amely sokkal korlátozottabb), így nem használhatja őket például a gamepad elérésére.
  • A homokozó dobozos bővítmények nem férnek hozzá a Scratch futásidejű objektumhoz.
  • A homokozós bővítmények sokkal lassabbak.
  • A homokozó dobozos bővítmények Javascript konzol hibaüzenetei rejtettebbek a Chrome -ban.

Másrészről:

  • Biztonságosabb mások homokozó dobozos kiterjesztéseinek használata.
  • A homokozó dobozos bővítmények nagyobb valószínűséggel működnek együtt az esetleges hivatalos kiterjesztések betöltési támogatásával.
  • A homokozó dobozos bővítményeket a webszerverre való feltöltés nélkül is tesztelheti, ha data: // URL -be kódolja.

A hivatalos kiterjesztések (például a Zene, a toll stb.) Mind csiszolatlanok. A bővítmény konstruktőre megkapja a futásidejű objektumot a Scratch -től, és az ablak teljesen hozzáférhető.

A Fetch kiterjesztés homokozós, de a Gamepad -nek szüksége van a navigátor objektumra az ablakból.

2. lépés: Homokozó dobozos kiterjesztés írása: I. rész

Bővítmény létrehozásához hozzon létre egy osztályt, amely kódolja a rá vonatkozó információkat, majd adjon hozzá egy kis kódot a bővítmény regisztrálásához.

A kiterjesztési osztályban a legfontosabb egy getInfo () metódus, amely a kötelező mezőket tartalmazó objektumot adja vissza:

  • id: a bővítmény belső neve, egyedinek kell lennie minden egyes bővítményhez
  • név: a bővítmény barátságos neve, amely megjelenik a Scratch blokkok listájában
  • blokkok: az új egyéni blokkot leíró objektumok listája.

És van egy opcionális menümező, amelyet nem használnak a Fetch alkalmazásban, de a Gamepadben fogják használni.

Tehát itt van a lekérés alap sablonja:

osztály ScratchFetch {

konstruktor () {} getInfo () {return {"id": "Fetch", "name": "Fetch", "blokkok": [/* add később * /]}} / * metódusok hozzáadása blokkokhoz * /} Scratch.extensions.register (új ScratchFetch ())

3. lépés: Homokozó dobozos kiterjesztés írása: II

Most létre kell hoznunk a blokkok listáját a getInfo () objektumában. Minden blokknak legalább erre a négy mezőre van szüksége:

  • opcode: ez a metódus neve, amelyet a blokk munkájának elvégzésére hívnak
  • blockType: ez a blokktípus; a leggyakoribbak a kiterjesztéseknél:

    • "parancs": csinál valamit, de nem ad vissza értéket
    • "riporter": karakterláncot vagy számot ad vissza
    • "Boolean": logikai értéket ad vissza (jegyezze meg a nagybetűket)
    • "kalap": eseményfogó blokk; ha a Scratch kódja használja ezt a blokkot, akkor a Scratch futásideje rendszeresen lekérdezi a hozzá tartozó metódust, amely logikai értéket ad vissza annak megállapítására, hogy az esemény megtörtént -e
  • szöveg: ez a blokk barátságos leírása, zárójelben az argumentumokkal, például "adatok lekérése az -ről"
  • argumentumok: ez egy olyan objektum, amely minden argumentumhoz mezőt tartalmaz (pl. "url" a fenti példában); ennek az objektumnak a következő mezői vannak:

    • típus: vagy "karakterlánc" vagy "szám"
    • defaultValue: az előre kitöltendő alapértelmezett érték.

Például itt van a Letöltés kiterjesztés blokkok mezője:

"blokkok": [{"opcode": "fetchURL", "blockType": "riporter", "text": "adatok lekérése az -ről", "argumentumok": {"url": {"type": "string", "defaultValue ":" https://api.weather.gov/stations/KNYC/observations "},}}, {" opcode ":" jsonExtract "," blockType ":" riporter "," text ":" kivonat [név] from [data] "," argument ": {" name ": {" type ":" string "," defaultValue ":" hőmérséklet "}," data ": {" type ":" string "," defaultValue ": '{"hőmérséklet": 12.3}'},}},]

Itt két blokkot definiáltunk: fetchURL és jsonExtract. Mindketten újságírók. Az első adatokat húz egy URL -ből, és visszaadja őket, a második pedig kibont egy mezőt a JSON -adatokból.

Végül meg kell adnia a két blokk módszereit. Minden módszer egy objektumot vesz fel argumentumként, az objektum mezőket tartalmaz az összes argumentumhoz. Ezeket dekódolhatja göndör zárójelek használatával az argumentumokban. Például itt van egy szinkron példa:

jsonExtract ({név, adatok}) {

var parsed = JSON.parse (data) if (name in parsed) {var out = parsed [name] var t = typeof (out) if (t == "string" || t == "number") return out if (t == "boolean") return t? 1: 0 return JSON.stringify (out)} else {return ""}}

A kód lehívja a névmezőt a JSON adatokból. Ha a mező karakterláncot, számot vagy logikai értéket tartalmaz, akkor ezt visszaadjuk. Ellenkező esetben újra JSONify a mezőt. És üres karakterláncot adunk vissza, ha a név hiányzik a JSON -ból.

Néha azonban érdemes blokkot készíteni, amely aszinkron API -t használ. A fetchURL () metódus a fetch API -t használja, amely aszinkron. Ilyen esetben vissza kell adnia egy ígéretet a módszerétől, amely elvégzi a munkát. Például:

fetchURL ({url}) {

return letöltés (url). then (response => response.text ())}

Ez az. A teljes kiterjesztés itt található.

4. lépés: Homokozó dobozos bővítmény használata

Homokozó dobozos bővítmény használata
Homokozó dobozos bővítmény használata
Homokozó dobozos bővítmény használata
Homokozó dobozos bővítmény használata
Homokozó dobozos bővítmény használata
Homokozó dobozos bővítmény használata

A homokozó dobozos kiterjesztésnek két módja van. Először feltöltheti egy webszerverre, majd betöltheti a SheepTester Scratch mod -jába. Másodszor, kódolhatja egy adat URL -be, és betöltheti azt a Scratch modba. Valójában eléggé használom a második módszert tesztelésre, mivel ezzel elkerülhető, hogy a bővítmény régebbi verzióit a szerver tárolja. Ne feledje, hogy bár tárolhat javascriptet a Github -oldalakról, ezt nem teheti meg közvetlenül egy közönséges github -tárból.

A fetch.js webhelyem a https://arpruss.github.io/fetch.js címen található. Vagy átalakíthatja a bővítményt adat URL -re, ha feltölti ide, majd másolja a vágólapra. Az adat URL egy óriási URL, amely egy teljes fájlt tartalmaz.

Nyissa meg a SheepTester Scratch modját. Kattintson a Bővítmény hozzáadása gombra a bal alsó sarokban. Ezután kattintson a "Bővítmény kiválasztása" gombra, és írja be az URL -t (tetszés szerint beillesztheti a teljes óriási adat URL -t).

Ha minden jól ment, akkor a Scratch képernyő bal oldalán lesz egy bejegyzés a bővítményhez. Ha a dolgok nem mentek jól, akkor nyissa meg a Javascript konzolt (shift-ctrl-J a Chrome-ban), és próbálja meg elhárítani a problémát.

Fent talál néhány példakódot, amely lekéri és elemzi a JSON -adatokat az Egyesült Államok Országos Meteorológiai Szolgálatának KNYC (New York) állomásán, és megjeleníti azokat, miközben a sprite -t ugyanolyan irányba fordítja, mint a szél. Az elkészítés módja az volt, hogy lekértem az adatokat egy webböngészőbe, majd kitaláltam a címkéket. Ha másik meteorológiai állomást szeretne kipróbálni, írja be a közeli irányítószámot az weather.gov webhelyen található keresőmezőbe, és a tartózkodási helyének időjárási oldala négybetűs állomáskódot ad, amelyet a KNYC helyett használhat kód.

A "? Url =" argumentum hozzáadásával a homokozó dobozos kiterjesztést közvetlenül a SheepTester mod URL -jébe is beillesztheti. Például:

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

5. lépés: A homokozó nélküli kiterjesztés írása: Bevezetés

A homokozó nélküli bővítmény konstruktorának futásidejű objektum kerül át. Figyelmen kívül hagyhatja vagy használhatja. A Runtime objektum egyik felhasználása az, hogy a currentMSecs tulajdonságát használja az események ("kalapblokkok") szinkronizálására. Amennyire meg tudom mondani, az összes eseményblokk opcode rendszeresen lekérdezésre kerül, és a szavazás minden fordulója egyetlen currentMSecs értékkel rendelkezik. Ha szüksége van a Runtime objektumra, akkor valószínűleg a következővel indítja el a kiterjesztést:

osztály EXTENSIONCLASS {

konstruktor (futásidő) {this.runtime = futási idő…}…}

Az összes szabványos ablakobjektum használható a homokozó nélküli kiterjesztésben. Végül a homokozó nélküli kiterjesztésnek ezzel a varázslatos kóddal kell végződnie:

(function () {

var extensionInstance = új EXTENSIONCLASS (window.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension (extensionInstance) window.vm.extensionManager._loadedExtensions.set (extensionInstance.getInfo ()) id, service (szolgáltatás))

ahol az EXTENSIONCLASS -ot le kell cserélnie a mellék osztályára.

6. lépés: A homokozó nélküli kiterjesztés írása: Egyszerű Gamepad

Készítsünk most egy egyszerű gamepad -bővítményt, amely egyetlen esemény ("kalap") blokkot biztosít a gomb megnyomásakor vagy elengedésekor.

Minden eseményblokk lekérdezési ciklus során mentünk egy időbélyeget a futásidejű objektumból, valamint az előző és az aktuális gamepad állapotot. Az időbélyeget arra használják, hogy felismerjék, ha új lekérdezési ciklusunk van. Tehát kezdjük a következővel:

osztályú ScratchSimpleGamepad {

konstruktor (futásidő) {this.runtime = runtime this.currentMSecs = -1 this.previousButtons = this.currentButtons = }…} Egy eseményblokkunk lesz, két bemenettel-egy gomb számával és egy menüvel, amellyel kiválaszthatjuk, hogy az eseményt megnyomáskor vagy felszabadításkor akarjuk-e kiváltani. Tehát itt a módszerünk

szerezz információt() {

return {"id": "SimpleGamepad", "name": "SimpleGamepad", "blokkok": [{"opcode": "buttonPressedReleased", "blockType": "kalap", "text": "gomb [eventType] "," argument ": {" b ": {" type ":" number "," defaultValue ":" 0 "}," eventType ": {" type ":" number "," defaultValue ":" 1 "," menu ":" pressReleaseMenu "},},},]," menus ": {" pressReleaseMenu ": [{text:" press ", value: 1}, {text:" release ", value: 0}],}}; } Úgy gondolom, hogy a legördülő menü értékei továbbra is karakterláncként kerülnek át az opcode függvénybe, annak ellenére, hogy számként vannak deklarálva. Tehát szükség szerint hasonlítsa össze őket a menüben megadott értékekkel. Most olyan módszert írunk, amely frissíti a gombállapotokat, amikor új esemény lekérdezési ciklus történik

frissítés () {

if (this.runtime.currentMSecs == this.currentMSecs) return // nem új szavazási ciklus this.currentMSecs = this.runtime.currentMSecs var gamepad = navigator.getGamepad () if (gamepad == null || gamepad.length = = 0 || gamepad [0] == null) {this.previousButtons = this.currentButtons = return} var gamepad = gamepad [0] if (gamepad.buttons.length! = This.previousButtons.length) { // különböző számú gomb, ezért új gamepad this.previousButtons = ehhez (var i = 0; i <gamepad.buttons.length; i ++) this.previousButtons.push (false)} else {this.previousButtons = this. currentButtons} this.currentButtons = ehhez (var i = 0; i <gamepad.buttons.length; i ++) this.currentButtons.push (gamepad.buttons .préselve)} Végül megvalósíthatjuk eseményblokkunkat úgy, hogy meghívjuk az update () metódust, majd ellenőrizzük, hogy a szükséges gombot nem nyomtuk -e meg vagy engedtük -e ki, összehasonlítva az aktuális és az előző gombállapotokat

buttonPressedReleased ({b, eventType}) {

this.update () if (b <this.currentButtons.length) {if (eventType == 1) {// megjegyzés: ez egy karakterlánc lesz, ezért jobb összehasonlítani 1 -gyel, mint logikai értékkel kezelni, ha (this.currentButtons &&! this.previousButtons ) {return true}} else {if (! this.currentButtons && this.previousButtons ) {return true}}} return false} És végül hozzáadjuk a mágikus kiterjesztés regisztrációs kódját az osztály meghatározása után

(function () {

var extensionInstance = new ScratchSimpleGamepad (window.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension (extensionInstance) window.vm.extensionManager._loadedExtensions.set (extensionInstance.getInfo ()), id.)

A teljes kódot itt szerezheti be.

7. lépés: Csiszolatlan bővítmény használata

Csiszolatlan bővítmény használata
Csiszolatlan bővítmény használata

Ismét hostold valahol a kiterjesztésedet, és ezúttal töltsd be a load_plugin = argumentummal, nem pedig url = argumentummal a SheepTester Scratch modjába. Például az én egyszerű Gamepad modomhoz látogasson el ide:

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

(Egyébként, ha kifinomultabb játékvezérlőt szeretne, csak távolítsa el az "egyszerű" elemet a fenti URL -ből, és dübörgést és analóg tengely támogatást kap.)

Ismételten, a bővítménynek meg kell jelennie a Scratch szerkesztőjének bal oldalán. A fenti egy nagyon egyszerű Scratch program, amely azt mondja: "hello", amikor megnyomja a 0 gombot, és "viszlát", amikor elengedi.

8. lépés: Kettős kompatibilitás és sebesség

Észrevettem, hogy a kiterjesztési blokkok nagyságrenddel gyorsabban futnak a betöltési módszerrel, amelyet a homokozó nélküli bővítményekhez használtam. Tehát, hacsak nem törődik a Web Worker homokozóban való futtatás biztonsági előnyeivel, akkor a kódnak jót tesz, ha betölti a SheepTester modjának? Load_plugin = URL argumentumát.

A homokozó dobozos bővítményt mindkét betöltési módszerrel kompatibilisé teheti a következő kód használatával a kiterjesztési osztály meghatározása után (módosítsa az OSZTÁLYNÉV -t a kiterjesztési osztály nevére):

(function () {

var extensionClass = CLASSNAME if (windowof type === "undefined" ||! window.vm) {Scratch.extensions.register (new extensionClass ())} else {var extensionInstance = new extensionClass (window.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension (extensionInstance) window.vm.extensionManager._loadedExtensions.set (extensionInstance.getInfo (). azonosító, serviceName)}}) ()

Ajánlott: