Kazalo:

Razširitve Scratch 3.0: 8 korakov
Razširitve Scratch 3.0: 8 korakov

Video: Razširitve Scratch 3.0: 8 korakov

Video: Razširitve Scratch 3.0: 8 korakov
Video: ошибка [レッドゾーン] 2024, Julij
Anonim
Razširitve Scratch 3.0
Razširitve Scratch 3.0

Razširitve Scratch so kodi Javascript, ki v Scratch dodajo nove bloke. Čeprav je Scratch v kompletu s kopico uradnih razširitev, ni uradnega mehanizma za dodajanje uporabniško izdelanih razširitev.

Ko sem ustvarjal razširitev za nadzor Minecraft za Scratch 3.0, sem težko začel. Ta Instructable skupaj zbira informacije iz različnih virov (zlasti tega) in nekaj stvari, ki sem jih odkril sam.

Morate vedeti, kako programirati v Javascript in kako gostiti svoj Javascript na spletnem mestu. Za slednje priporočam strani GitHub.

Glavni trik je uporaba SheepTesterjevega načina Scratch, ki vam omogoča nalaganje razširitev in vtičnikov.

Ta navodila vas bodo vodila skozi dve razširitvi:

  • Pridobivanje: nalaganje podatkov z URL -ja in pridobivanje oznak JSON, na primer za nalaganje vremenskih podatkov
  • SimpleGamepad: uporaba krmilnika iger v Scratchu (tukaj je bolj izpopolnjena različica).

1. korak: Dve vrsti razširitev

Obstajata dve vrsti razširitev, ki jih bom poimenoval "nesandboxed" in "sandboxed". Razširitve v peskovniku se izvajajo kot spletni delavci, zato imajo pomembne omejitve:

  • Spletni delavci ne morejo dostopati do globalnih elementov v okenskem objektu (namesto tega imajo globalni self objekt, ki je veliko bolj omejen), zato jih ne morete uporabljati za stvari, kot je dostop do igralne plošče.
  • Razširitve v peskovniku nimajo dostopa do predmeta izvajanja Scratch.
  • Razširitve v peskovniku so veliko počasnejše.
  • Sporočila o napakah konzole Javascript za razširitve v peskovniku so v Chromu bolj skrivnostna.

Po drugi strani:

  • Uporaba razširitev v peskovniku drugih ljudi je varnejša.
  • Razširitve v peskovniku bodo bolj verjetno delovale z morebitno uradno podporo za nalaganje razširitev.
  • Razširitve v peskovniku lahko preizkusite brez nalaganja na spletni strežnik s kodiranjem v URL: data: //.

Uradne razširitve (na primer Glasba, Pero itd.) Vse niso shranjene. Konstruktor za razširitev dobi predmet izvajanja iz programa Scratch in okno je v celoti dostopno.

Razširitev Fetch je v peskovniku, vendar Gamepad potrebuje navigacijski objekt iz okna.

2. korak: Pisanje razširitve v peskovniku: I. del

Če želite narediti razširitev, ustvarite razred, ki kodira podatke o njem, in nato dodate malo kode za registracijo razširitve.

Glavna stvar v razširitvenem razredu je metoda getInfo (), ki vrne predmet z zahtevanimi polji:

  • id: notranje ime razširitve mora biti edinstveno za vsako razširitev
  • name: prijazno ime razširitve, prikazano na Scratchovem seznamu blokov
  • bloki: seznam predmetov, ki opisujejo nov blok po meri.

Obstaja tudi izbirno polje menijev, ki se ne uporablja v Fetchu, ampak bo uporabljeno v Gamepadu.

Torej, tukaj je osnovna predloga za Fetch:

razred ScratchFetch {

constructor () {} getInfo () {return {"id": "Pridobi", "name": "Pridobi", "bloki": [/* dodaj pozneje * /]}} / * dodaj metode za bloke * /} Scratch.extensions.register (nov ScratchFetch ())

3. korak: Pisanje razširitve v peskovniku: II. Del

Zdaj moramo ustvariti seznam blokov v objektu getInfo (). Vsak blok potrebuje vsaj ta štiri polja:

  • opcode: to je ime metode, ki je poklicana za opravljanje dela bloka
  • blockType: to je vrsta bloka; najpogostejše razširitve so:

    • "ukaz": naredi nekaj, vendar ne vrne vrednosti
    • "reporter": vrne niz ali številko
    • "Boolean": vrne logično vrednost (upoštevajte veliko začetnico)
    • "klobuk": blok za ugotavljanje dogodkov; če vaša koda Scratch uporablja ta blok, čas izvajanja Scratch redno anketira povezano metodo, ki vrne logično vrednost, da pove, ali se je dogodek zgodil
  • text: to je prijazen opis bloka z argumenti v oklepajih, na primer "pridobivanje podatkov iz "
  • argumenti: to je predmet, ki ima polje za vsak argument (npr. "url" v zgornjem primeru); ta objekt ima ta polja:

    • vrsta: "niz" ali "številka"
    • defaultValue: privzeta vrednost, ki jo je treba vnaprej napolniti.

Tu je na primer polje blokov v moji razširitvi Fetch:

"bloki": [{"opcode": "fetchURL", "blockType": "reporter", "text": "pridobivanje podatkov iz ", "argumenti": {"url": {"type": "string", "defaultValue ":" https://api.weather.gov/stations/KNYC/observations "},}}, {" opcode ":" jsonExtract "," blockType ":" reporter "," text ":" ekstrakt [ime] from [data] "," arguments ": {" name ": {" type ":" string "," defaultValue ":" temperature "}," data ": {" type ":" string "," defaultValue ": '{"temperatura": 12.3}'},}},]

Tu smo definirali dva bloka: fetchURL in jsonExtract. Oba sta poročevalca. Prva potegne podatke iz URL -ja in jih vrne, druga pa izvleče polje iz podatkov JSON.

Nazadnje morate vključiti metode za dva bloka. Vsaka metoda vzame predmet kot argument, pri čemer objekt vključuje polja za vse argumente. Lahko jih dekodirate s kodranimi oklepaji v argumentih. Na primer, tukaj je en sinhroni primer:

jsonExtract ({ime, podatki}) {

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

Koda potegne polje imena iz podatkov JSON. Če polje vsebuje niz, številko ali logično vrednost, to vrnemo. V nasprotnem primeru polje ponovno JSONify. Če v imenu JSON manjka ime, vrnemo prazen niz.

Včasih pa boste morda želeli narediti blok, ki uporablja asinhroni API. Metoda fetchURL () uporablja asinkroni API za pridobivanje. V takem primeru bi morali vrniti obljubo iz svoje metode, ki bo delovala. Na primer:

fetchURL ({url}) {

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

To je to. Celotna razširitev je tukaj.

4. korak: Uporaba razširitve v peskovniku

Uporaba razširitve v peskovniku
Uporaba razširitve v peskovniku
Uporaba razširitve v peskovniku
Uporaba razširitve v peskovniku
Uporaba razširitve v peskovniku
Uporaba razširitve v peskovniku

Obstajata dva načina uporabe razširitve v peskovniku. Najprej ga lahko naložite na spletni strežnik in ga nato naložite v SheepTester's Scratch mod. Drugič, lahko ga kodirate v podatkovni URL in ga naložite v mod Scratch. Drugo metodo pravzaprav precej uporabljam za testiranje, saj se s tem izognemo skrbi, da bi starejše različice razširitve strežnik predpomnil. Upoštevajte, da čeprav lahko gostite javascript na straneh Github, tega ne morete storiti neposredno iz navadnega skladišča github.

Moj fetch.js gostuje na https://arpruss.github.io/fetch.js. Lahko pa svojo razširitev pretvorite v podatkovni URL, tako da jo naložite sem in nato kopirate v odložišče. Podatkovni URL je velikanski URL, ki vsebuje celo datoteko.

Pojdite na SheepTester's Scratch mod. V spodnjem levem kotu kliknite gumb Dodaj razširitev. Nato kliknite »Izberi razširitev« in vnesite svoj URL (če želite, lahko prilepite celoten velikanski podatkovni URL).

Če je vse v redu, boste imeli vnos za razširitev na levi strani zaslona Scratch. Če stvari niso šle dobro, odprite konzolo Javascript (shift-ctrl-J v Chromu) in poskusite odpraviti težavo.

Zgoraj boste našli nekaj primerov kode, ki pridobiva in razčlenjuje podatke JSON s postaje KNYC (v New Yorku) ameriške nacionalne vremenske službe in jih prikaže, medtem ko obrne sprite v obraz tako, kot piha veter. To sem naredil tako, da sem podatke prebral v spletni brskalnik in nato ugotovil oznake. Če želite poskusiti z drugo vremensko postajo, v iskalno polje na weather.gov vnesite bližnjo poštno številko in vremenska stran za vašo lokacijo vam mora dati štirimestno kodo postaje, ki jo lahko uporabite namesto KNYC v Koda.

Svojo razširitev v peskovniku lahko vključite tudi neposredno v URL za mod SheepTester tako, da dodate argument "? Url =". Na primer:

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

5. korak: Pisanje razširitve brez embalaže: Uvod

Konstruktor razširitve, ki ni shranjena v škatli, se prenese v objekt Runtime. Lahko ga prezrete ali uporabite. Eden od načinov uporabe predmeta Runtime je uporaba njegove lastnosti currentMSecs za sinhronizacijo dogodkov ("bloki klobukov"). Kolikor lahko vidim, so vse op kode blokov dogodkov redno anketirane in vsak krog glasovanja ima eno samo trenutno vrednost MSecs. Če potrebujete predmet Runtime, boste razširitev verjetno zagnali z:

razred EXTENSIONCLASS {

constructor (runtime) {this.runtime = runtime…}…}

Vse standardne stvari okenskih predmetov je mogoče uporabiti v razširitvi brez peskovnika. Nazadnje bi se morala vaša razširitev, ki ni shranjena v škatli, končati s tem kosom čarobne kode:

(funkcija () {

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

kjer morate zamenjati EXTENSIONCLASS z razredom razširitve.

Korak 6: Pisanje razširitve brez embalaže: Enostavna igralna plošča

Zdaj pa naredimo preprosto razširitev igralne plošče, ki zagotavlja en sam dogodek ("klobuk"), ko pritisnete ali spustite gumb.

Med vsakim ciklom anketiranja blokov dogodkov bomo shranili časovni žig iz predmeta izvajanja ter prejšnje in trenutno stanje igralne plošče. Časovni žig se uporablja za ugotavljanje, ali imamo nov cikel glasovanja. Torej, začnemo z:

razred ScratchSimpleGamepad {

constructor (runtime) {this.runtime = runtime this.currentMSecs = -1 this.previousButtons = this.currentButtons = }…} Imeli bomo en blok dogodkov z dvema vhodoma-številko gumba in menijem za izbiro, ali želimo, da se dogodek sproži ob pritisku ali sprostitvi. Torej, tukaj je naša metoda

getInfo () {

return {"id": "SimpleGamepad", "name": "SimpleGamepad", "bloki": [{"opcode": "buttonPressedReleased", "blockType": "klobuk", "besedilo": "gumb [eventType] "," argumenti ": {" b ": {" type ":" number "," defaultValue ":" 0 "}," eventType ": {" type ":" number "," defaultValue ":" 1 "," menu ":" pressReleaseMenu "},},},]," meniji ": {" pressReleaseMenu ": [{text:" press ", vrednost: 1}, {text:" release ", vrednost: 0}],}}; } Mislim, da se vrednosti v spustnem meniju kljub temu, da so deklarirane kot številke, še vedno prenesejo v funkcijo opcode. Zato jih po potrebi izrecno primerjajte z vrednostmi, navedenimi v meniju. Zdaj pišemo metodo, ki posodobi stanje gumbov vsakič, ko se zgodi nov cikel raziskovanja dogodkov

nadgradnja() {

if (this.runtime.currentMSecs == this.currentMSecs) return // ni nov cikel anketiranja this.currentMSecs = this.runtime.currentMSecs var gamepads = navigator.getGamepads () if (gamepads == null || gamepads.length = = 0 || igralne plošče [0] == null) {this.previousButtons = this.currentButtons = return} var gamepad = igralne plošče [0] if (gamepad.buttons.length! = This.previousButtons.length) { // različno število gumbov, zato je nova igralna plošča this.previousButtons = za (var i = 0; i <gamepad.buttons.length; i ++) this.previousButtons.push (false)} else {this.previousButtons = this. currentButtons} this.currentButtons = za (var i = 0; i <gamepad.buttons.length; i ++) this.currentButtons.push (gamepad.buttons .pressed)} Končno lahko svoj blok dogodkov izvedemo tako, da pokličemo metodo update () in nato preverimo, ali je bil potreben gumb pravkar pritisnjen ali sproščen, s primerjavo trenutnega in prejšnjega stanja gumbov.

buttonPressedReleased ({b, eventType}) {

this.update () if (b <this.currentButtons.length) {if (eventType == 1) {// opomba: to bo niz, zato je bolje, da ga primerjate z 1, kot pa da ga obravnavate kot logično vrednost, če (this.currentButtons &&! this.previousButtons ) {return true}} else {if (! this.currentButtons && this.previousButtons ) {return true}}} return false} In končno dodamo našo čarobno registracijsko kodo razširitve, potem ko definiramo razred

(funkcija () {

var extensionInstance = nov ScratchSimpleGamepad (window.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension (extensionInstance) window.vm.extensionManager._loadedExtensions.set (extensionInstance.getInmea)))

Celotno kodo lahko dobite tukaj.

7. korak: Uporaba razširitve brez omarice

Uporaba razširitve brez embalaže
Uporaba razširitve brez embalaže

Še enkrat nekam gostite svojo razširitev in tokrat jo naložite z argumentom load_plugin = namesto url = v SheepTesterjev mod Scratch. Na primer, za moj preprost način Gamepad pojdite na:

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

(Mimogrede, če želite bolj prefinjeno igralno ploščo, preprosto odstranite "preprosto" z zgornjega URL -ja in imeli boste podporo ropotanja in analogne osi.)

Ponovno bi se morala razširitev prikazati na levi strani urejevalnika Scratch. Zgoraj je zelo preprost program Scratch, ki ob pritisku na tipko 0 izgovori "zdravo" in ko ga spustite "zbogom".

8. korak: Dvojna združljivost in hitrost

Opazil sem, da razširitveni bloki tečejo za red velikosti hitreje z uporabo metode nalaganja, ki sem jo uporabil za razširitve brez peskovnika. Če vas torej ne skrbijo varnostne prednosti izvajanja v peskovniku spletnega delavca, bo vaša koda imela koristi od nalaganja argumenta? Load_plugin = URL v mod SheepTester.

Razširitev v peskovniku lahko združite z obema načinoma nalaganja z uporabo naslednje kode, potem ko definirate razred razširitve (spremenite CLASSNAME v ime razreda razširitve):

(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)}}) ()

Priporočena: