Turinys:

„Scratch 3.0“plėtiniai: 8 žingsniai
„Scratch 3.0“plėtiniai: 8 žingsniai

Video: „Scratch 3.0“plėtiniai: 8 žingsniai

Video: „Scratch 3.0“plėtiniai: 8 žingsniai
Video: CS50 2015 - Week 3, continued 2024, Liepa
Anonim
„Scratch 3.0“plėtiniai
„Scratch 3.0“plėtiniai

„Scratch“plėtiniai yra „Javascript“kodo dalys, kurios prideda naujų blokų prie „Scratch“. Nors „Scratch“komplektuojama su daugybe oficialių plėtinių, nėra oficialaus vartotojo sukurtų plėtinių pridėjimo mechanizmo.

Kai kuriau „Minecraft“valdantį „Scratch 3.0“plėtinį, man buvo sunku pradėti. Šis „Instructable“renka informaciją iš įvairių šaltinių (ypač šio) ir keletą dalykų, kuriuos atradau pats.

Turite žinoti, kaip programuoti „Javascript“ir kaip priglobti „Javascript“svetainėje. Pastarajam rekomenduoju „GitHub Pages“.

Pagrindinis triukas yra naudoti „SheepTester“„Scratch“modifikaciją, leidžiančią įkelti plėtinius ir papildinius.

Ši instrukcija padės jums sukurti du plėtinius:

  • Iškviesti: įkeliami duomenys iš URL ir išgaunamos JSON žymos, pavyzdžiui, norint įkelti orų duomenis
  • „SimpleGamepad“: naudojant „Scratch“žaidimų valdiklį (čia yra sudėtingesnė versija).

1 veiksmas: dviejų tipų plėtiniai

Yra dviejų tipų plėtiniai, kuriuos vadinsiu „nesmulkintais“ir „smėlio dėžėmis“. „Smėlio dėžės“plėtiniai veikia kaip žiniatinklio darbuotojai, todėl turi didelių apribojimų:

  • Žiniatinklio darbuotojai negali pasiekti lango objekto visumos (vietoj to jie turi visuotinį savęs objektą, kuris yra daug ribotesnis), todėl jūs negalite jų naudoti tokiems dalykams kaip žaidimų prieiga.
  • Smėlio dėžės plėtiniai neturi prieigos prie „Scratch“vykdymo laiko objekto.
  • Smėlio dėžės plėtiniai yra daug lėtesni.
  • „Javascript“konsolės klaidų pranešimai, esantys smėlio dėžės plėtiniuose, yra labiau paslaptingi „Chrome“.

Iš kitos pusės:

  • Saugiau naudoti kitų žmonių smėlio dėžės plėtinius.
  • „Smėlio dėžės“plėtiniai greičiausiai veiks su bet kokiu galimu oficialiu plėtinių įkėlimo palaikymu.
  • Smėlio dėžės plėtinius galima išbandyti neįkėlus į žiniatinklio serverį, užkoduodami į data: // URL.

Visi oficialūs plėtiniai (pvz., „Music“, „Pen“ir kt.) Yra be dėžutės. Plėtinio konstruktorius gauna vykdymo laiko objektą iš „Scratch“, o langas yra visiškai prieinamas.

„Fetch“plėtinys yra smėlio dėžėje, tačiau „Gamepad“reikia naršyklės objekto iš lango.

2 žingsnis: „Smėlio dėžės“plėtinio rašymas: I dalis

Norėdami sukurti plėtinį, sukurkite klasę, kurioje užkoduota informacija apie jį, ir pridėkite šiek tiek kodo, kad užregistruotumėte plėtinį.

Pagrindinis plėtinio klasės dalykas yra „getInfo ()“metodas, kuris grąžina objektą su privalomais laukais:

  • id: vidinis plėtinio pavadinimas, turi būti unikalus kiekvienam plėtiniui
  • vardas: draugiškas plėtinio pavadinimas, rodomas „Scratch“blokų sąraše
  • blokai: objektų, apibūdinančių naują pasirinktinį bloką, sąrašas.

Taip pat yra pasirenkamas meniu laukas, kuris nėra naudojamas „Fetch“, bet bus naudojamas „Gamepad“.

Taigi, čia yra pagrindinis „Fetch“šablonas:

klasė „ScratchFetch“{

konstruktorius () {} getInfo () {return {"id": "Fetch", "name": "Fetch", "blokai": [/* pridėti vėliau * /]}} / * pridėti blokų metodus * /} Scratch.extensions.register (naujas „ScratchFetch“)

3 žingsnis: „Smėlio dėžės“plėtinio rašymas: II dalis

Dabar turime sukurti blokų sąrašą „getInfo“() objekte. Kiekvienam blokui reikia bent šių keturių laukų:

  • opcode: tai metodo, kuris vadinamas blokui atlikti, pavadinimas
  • blockType: tai bloko tipas; dažniausiai naudojami plėtiniai:

    • "komanda": daro kažką, bet negrąžina vertės
    • „reporteris“: grąžina eilutę arba skaičių
    • „Būlis“: grąžina loginę reikšmę (atkreipkite dėmesį į didžiąsias raides)
    • "skrybėlė": įvykių gaudymo blokas; jei jūsų „Scratch“kodas naudoja šį bloką, „Scratch“vykdymo laikas reguliariai apklausia susijusį metodą, kuris grąžina loginę reikšmę, kad pasakytų, ar įvykis įvyko
  • tekstas: tai draugiškas bloko aprašymas su argumentais skliausteliuose, pvz., „gauti duomenis iš “
  • argumentai: tai objektas, kuriame yra kiekvieno argumento laukas (pvz., „url“aukščiau pateiktame pavyzdyje); šis objektas savo ruožtu turi šiuos laukus:

    • tipas: „eilutė“arba „skaičius“
    • defaultValue: numatytoji vertė, kurią reikia užpildyti iš anksto.

Pavyzdžiui, čia yra blokų laukas mano „Fetch“plėtinyje:

"blokai": [{"opcode": "fetchURL", "blockType": "reporteris", "text": "gauti duomenis iš ", "argumentai": {"url": {"type": "string", "defaultValue ":" https://api.weather.gov/stations/KNYC/observations "},}}, {" opcode ":" jsonExtract "," blockType ":" reporteris "," text ":" ekstraktas [vardas] from [data] "," argument ": {" name ": {" type ":" string "," defaultValue ":" temperatūra "}," data ": {" type ":" string "," defaultValue ": '{"temperatūra": 12.3}'},}},]

Čia mes apibrėžėme du blokus: fetchURL ir jsonExtract. Abu yra žurnalistai. Pirmasis ištraukia duomenis iš URL ir grąžina juos, o antrasis išskiria lauką iš JSON duomenų.

Galiausiai turite įtraukti dviejų blokų metodus. Kiekvienas metodas objektą laiko argumentu, o objektas apima visų argumentų laukus. Galite juos iššifruoti naudodami argumentų garbanotas skliaustus. Pavyzdžiui, čia yra vienas sinchroninis pavyzdys:

jsonExtract ({vardas, duomenys}) {

var parsed = JSON.parse (duomenys) if (vardas išanalizuotas) {var out = parsinta [name] var t = typeof (out) if (t == "string" || t == "number") return if (t == "loginis") return t? 1: 0 grąžinti JSON.stringify (out)} else {return ""}}

Kodas ištraukia vardo lauką iš JSON duomenų. Jei lauke yra eilutė, skaičius arba loginė reikšmė, mes ją grąžiname. Priešingu atveju mes iš naujo JSONify lauką. Ir grąžiname tuščią eilutę, jei JSON pavadinimo nėra.

Tačiau kartais galbūt norėsite sukurti bloką, kuriame naudojama asinchroninė API. Metodas fetchURL () naudoja asinchroninę fetch API. Tokiu atveju turėtumėte grąžinti pažadą iš savo metodo, kuris atlieka darbą. Pavyzdžiui:

fetchURL ({url}) {

return get (url). then (response => response.text ())}

Viskas. Visas pratęsimas yra čia.

4 žingsnis: „Smėlio dėžės“plėtinio naudojimas

„Smėlio dėžės“plėtinio naudojimas
„Smėlio dėžės“plėtinio naudojimas
„Smėlio dėžės“plėtinio naudojimas
„Smėlio dėžės“plėtinio naudojimas
„Smėlio dėžės“plėtinio naudojimas
„Smėlio dėžės“plėtinio naudojimas

Yra du smėlio dėžės plėtinio naudojimo būdai. Pirmiausia galite įkelti jį į žiniatinklio serverį ir įkelti į „SheepTester“„Scratch“mod. Antra, galite jį užkoduoti į duomenų URL ir įkelti jį į „Scratch“mod. Aš iš tikrųjų bandymams naudoju antrąjį metodą, nes taip išvengiama rūpesčių dėl senesnių plėtinio versijų, kurias serveris išsaugo talpykloje. Atminkite, kad nors galite priglobti „JavaScript“iš „Github“puslapių, negalite to padaryti tiesiogiai iš įprastos „github“saugyklos.

Mano „fetch.js“priglobta adresu https://arpruss.github.io/fetch.js. Arba galite konvertuoti plėtinį į duomenų URL įkeldami jį čia ir nukopijuodami į iškarpinę. Duomenų URL yra milžiniškas URL, kuriame yra visas failas.

Eikite į „SheepTester“„Scratch“mod. Apatiniame kairiajame kampe spustelėkite mygtuką Pridėti plėtinį. Tada spustelėkite „Pasirinkite plėtinį“ir įveskite savo URL adresą (jei norite, galite įklijuoti visą milžinišką duomenų URL).

Jei viskas klostėsi gerai, „Scratch“ekrano kairėje pusėje turėsite įrašą apie savo plėtinį. Jei ne viskas gerai, turėtumėte atidaryti „Javascript“konsolę („Chrome“-„Shift-ctrl-J“) ir pabandyti derinti problemą.

Viršuje rasite kodo pavyzdį, kuris paima ir analizuoja JSON duomenis iš JAV Nacionalinės meteorologijos tarnybos KNYC (Niujorke) stoties ir parodo juos, pasukdamas sprite į veidą taip, kaip pučia vėjas. Aš tai padariau nusinešęs duomenis į žiniatinklio naršyklę ir išsiaiškinęs žymas. Jei norite išbandyti kitą oro stotį, paieškos laukelyje weather.gov įveskite netoliese esantį pašto kodą, o jūsų vietovės orų puslapyje turėtų būti pateiktas keturių raidžių stoties kodas, kurį galite naudoti vietoje KNYC kodą.

Taip pat galite įtraukti savo smėlio dėžės plėtinį tiesiai į „SheepTester“modulio URL, pridėdami argumentą „? Url =“. Pavyzdžiui:

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

5 veiksmas: neparašyto plėtinio rašymas: įvadas

Plėtinio be smėlio dėžės konstruktorius gauna „Runtime“objektą. Galite jį ignoruoti arba naudoti. Vienas iš „Runtime“objekto naudojimo būdų yra naudoti jo ypatybę „currentMSecs“įvykiams („skrybėlių blokams“) sinchronizuoti. Kiek galiu pasakyti, visi įvykių bloko opcodai yra apklausiami reguliariai, o kiekvienas apklausos etapas turi vieną dabartinęMSecs reikšmę. Jei jums reikia „Runtime“objekto, greičiausiai pradėsite plėtinį naudodami:

EXTENSIONCLASS {klasė

konstruktorius (vykdymo laikas) {this.runtime = runtime…}…}

Visi standartiniai lango objekto dalykai gali būti naudojami plėtinyje, kuriame nėra smėlio dėžės. Galiausiai jūsų smėlio dėžės plėtinys turėtų baigtis tokiu magišku kodu:

(funkcija() {

var extensionInstance = naujas EXTENSIONCLASS (window.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension (extensionInstance) window.vm.extensionManager._loadedExtensions.set (extensionInstance.getInfo ()) id, service ())

kur EXTENSIONCLASS turėtumėte pakeisti savo plėtinio klase.

6 veiksmas: neparašyto plėtinio rašymas: paprasta žaidimų planšetė

Dabar padarykime paprastą žaidimų planšetės plėtinį, kuris suteikia vieno įvykio („skrybėlės“) bloką, kai paspaudžiamas ar atleidžiamas mygtukas.

Kiekvieno įvykių bloko apklausos ciklo metu išsaugosime laiko žymę iš vykdymo laiko objekto ir ankstesnės bei dabartinės žaidimų planšetės būsenos. Laiko žyma naudojama atpažinti, ar turime naują apklausos ciklą. Taigi, mes pradedame nuo:

klasės „ScratchSimpleGamepad“{

konstruktorius (vykdymo laikas) {this.runtime = runtime this.currentMSecs = -1 this.previousButtons = this.currentButtons = }…} Turėsime vieną įvykių bloką su dviem įėjimais-mygtuko numeriu ir meniu, kad pasirinktume, ar norime, kad įvykis įsijungtų spaudžiant ar atleidžiant. Taigi, čia yra mūsų metodas

gauti informaciją() {

return {"id": "SimpleGamepad", "name": "SimpleGamepad", "blokai": [{"opcode": "buttonPressedReleased", "blockType": "skrybėlė", "text": "mygtukas [eventType] "," arguments ": {" b ": {" type ":" number "," defaultValue ":" 0 "}," eventType ": {" type ":" number "," defaultValue ":" 1 "," menu ":" pressReleaseMenu "},},},]," menus ": {" pressReleaseMenu ": [{text:" press ", value: 1}, {text:" release ", value: 0}],}}; } Manau, kad išskleidžiamojo meniu reikšmės vis tiek perduodamos opcode funkcijai kaip eilutės, nepaisant to, kad jos deklaruojamos kaip skaičiai. Taigi, jei reikia, aiškiai palyginkite juos su meniu nurodytomis vertėmis. Dabar rašome metodą, kuris atnaujina mygtuko būsenas, kai įvyksta naujas įvykių apklausos ciklas

atnaujinti () {

if (this.runtime.currentMSecs == this.currentMSecs) return // ne naujas apklausos ciklas this.currentMSecs = this.runtime.currentMSecs var gamepads = navigator.getGamepad () if (gamepads == null || gamepads.length = = 0 || žaidimo valdikliai [0] == null) {this.previousButtons = this.currentButtons = return} var gamepad = gamepad [0] if (gamepad.buttons.length! = This.previousButtons.length) { // skirtingas mygtukų skaičius, todėl naujas žaidimų pultas this.previousButtons = skirtas (var i = 0; i <gamepad.buttons.length; i ++) this.previousButtons.push (false)} else {this.previousButtons = this. currentButtons} this.currentButtons = skirtas (var i = 0; i <gamepad.buttons.length; i ++) this.currentButtons.push (gamepad.buttons .paspaustas)} Galiausiai, mes galime įgyvendinti savo įvykių bloką, paskambinę atnaujinimo () metodui ir tada patikrinę, ar reikiamas mygtukas ką tik buvo paspaustas ar atleistas, lyginant esamas ir ankstesnes mygtukų būsenas

buttonPressedReleased ({b, eventType}) {

this.update () if (b <this.currentButtons.length) {if (eventType == 1) {// pastaba: tai bus eilutė, todėl geriau ją palyginti su 1, nei laikyti logine, jei (this.currentButtons &&! this.previousButtons ) {return true}} else {if (! this.currentButtons && this.previousButtons ) {return true}}} return false} Galiausiai, apibrėžę klasę, pridedame savo stebuklingo plėtinio registracijos kodą

(funkcija() {

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

Visą kodą galite gauti čia.

7 veiksmas: „Unsandboxed“plėtinio naudojimas

Naudojant plėtinį be smėlio dėžės
Naudojant plėtinį be smėlio dėžės

Dar kartą priglobkite savo plėtinį kažkur ir šį kartą įkelkite jį naudodami argumentą load_plugin =, o ne url = į „SheepTester“„Scratch“mod. Pavyzdžiui, mano paprastam „Gamepad“modui eikite į:

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

(Beje, jei norite sudėtingesnio žaidimų planšetinio kompiuterio, tiesiog pašalinkite „paprastą“iš aukščiau nurodyto URL ir turėsite dundėjimą bei analoginės ašies palaikymą.)

Vėlgi, plėtinys turėtų būti rodomas kairėje „Scratch“redaktoriaus pusėje. Aukščiau yra labai paprasta „Scratch“programa, kuri sako „labas“, kai paspaudžiate mygtuką 0, ir „sudie“, kai jį atleidžiate.

8 veiksmas: dvigubas suderinamumas ir greitis

Pastebėjau, kad plėtinių blokai veikia eilės greičiu greičiau, naudojant įkėlimo metodą, kurį naudojau ne smėlio dėžės plėtiniams. Taigi, jei jums nerūpi saugumo, susijusio su veikimu „Web Worker“smėlio dėžėje, jūsų kodui bus naudinga įkelti „SheepTester“modulio argumentą? Load_plugin = URL.

Galite nustatyti, kad smėlio dėžės plėtinys būtų suderinamas su abiem įkėlimo metodais, naudodami šį kodą, apibrėžę plėtinio klasę (pakeiskite KLASĖS VARDĄ į plėtinio klasės pavadinimą):

(funkcija() {

var extensionClass = CLASSNAME if (typeof window === "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 (). id, serviceName)}}) ()

Rekomenduojamas: