Isi kandungan:

Sambungan Scratch 3.0: 8 Langkah
Sambungan Scratch 3.0: 8 Langkah

Video: Sambungan Scratch 3.0: 8 Langkah

Video: Sambungan Scratch 3.0: 8 Langkah
Video: Scratch! 2024, November
Anonim
Sambungan Scratch 3.0
Sambungan Scratch 3.0

Sambungan calar adalah potongan kod Javascript yang menambah blok baru pada Scratch. Walaupun Scratch digabungkan dengan banyak ekstensi rasmi, tidak ada mekanisme rasmi untuk menambahkan pelanjutan buatan pengguna.

Semasa saya membuat pelanjutan kawalan Minecraft saya untuk Scratch 3.0, saya sukar memulakannya. Instructable ini mengumpulkan maklumat dari pelbagai sumber (terutamanya ini), dan beberapa perkara yang saya dapati sendiri.

Anda perlu tahu bagaimana memprogram dalam Javascript dan bagaimana menjadi host Javascript anda di laman web. Untuk yang terakhir, saya cadangkan GitHub Pages.

Silap mata utama adalah menggunakan mod Scratch SheepTester yang membolehkan anda memuatkan sambungan dan pemalam.

Instructable ini akan membimbing anda membuat dua sambungan:

  • Ambil: memuatkan data dari URL dan mengekstrak tag JSON, misalnya untuk memuatkan data cuaca
  • SimpleGamepad: menggunakan pengawal permainan di Scratch (versi yang lebih canggih ada di sini).

Langkah 1: Dua Jenis Sambungan

Terdapat dua jenis sambungan yang akan saya panggil "kotak pasir" dan "kotak pasir". Sambungan kotak pasir dijalankan sebagai Pekerja Web, dan hasilnya mempunyai batasan yang ketara:

  • Pekerja Web tidak dapat mengakses global di objek tetingkap (sebaliknya, mereka mempunyai objek diri global, yang jauh lebih terhad), jadi anda tidak dapat menggunakannya untuk perkara seperti akses gamepad.
  • Sambungan kotak pasir tidak mempunyai akses ke objek runtime Scratch.
  • Sambungan kotak pasir jauh lebih perlahan.
  • Mesej ralat konsol Javascript untuk sambungan kotak pasir lebih samar di Chrome.

Selain itu:

  • Menggunakan sambungan kotak pasir orang lain lebih selamat.
  • Sambungan kotak pasir lebih cenderung berfungsi dengan sokongan pemuatan pelanjutan rasmi akhirnya.
  • Sambungan kotak pasir dapat diuji tanpa memuat naik ke pelayan web dengan mengekod ke data: // URL.

Sambungan rasmi (seperti Muzik, Pena, dan lain-lain) semuanya tanpa kotak. Pembina untuk peluasan mendapat objek runtime dari Scratch, dan tetingkap dapat diakses sepenuhnya.

Sambungan Fetch adalah kotak pasir, tetapi Gamepad yang memerlukan objek navigator dari tingkap.

Langkah 2: Menulis Sambungan Kotak Pasir: Bahagian I

Untuk membuat pelanjutan, anda membuat kelas yang menyandikan maklumat mengenainya, dan kemudian menambahkan sedikit kod untuk mendaftarkan pelanjutan tersebut.

Perkara utama dalam kelas peluasan adalah kaedah getInfo () yang mengembalikan objek dengan bidang yang diperlukan:

  • id: nama dalaman pelanjutan, mestilah unik untuk setiap peluasan
  • name: nama sambungan yang mesra, muncul dalam senarai blok Scratch
  • blok: senarai objek yang menerangkan blok khusus baru.

Dan ada bidang menu pilihan yang tidak digunakan dalam Ambil tetapi akan digunakan di Gamepad.

Jadi, berikut adalah templat asas untuk Ambil:

ScratchFetch kelas {

pembina () {} getInfo () {return {"id": "Fetch", "name": "Fetch", "blocks": [/* add later * /]}} / * tambahkan kaedah untuk blok * /} Scratch.extensions.register (ScratchFetch baru ())

Langkah 3: Menulis Sambungan Kotak Pasir: Bahagian II

Sekarang, kita perlu membuat senarai blok di objek getInfo (). Setiap blok memerlukan sekurang-kurangnya empat bidang ini:

  • opcode: ini adalah nama kaedah yang dipanggil untuk melakukan kerja blok
  • blockType: ini adalah jenis blok; yang paling biasa untuk sambungan adalah:

    • "command": melakukan sesuatu tetapi tidak mengembalikan nilai
    • "wartawan": mengembalikan rentetan atau nombor
    • "Boolean": mengembalikan boolean (perhatikan huruf besarnya)
    • "topi": blok penangkapan acara; jika kod Scratch anda menggunakan blok ini, waktu larian Scratch secara berkala memilih kaedah yang berkaitan yang mengembalikan boolean untuk mengatakan sama ada peristiwa itu telah berlaku
  • teks: ini adalah deskripsi blok yang mesra, dengan argumen dalam tanda kurung, mis., "ambil data dari "
  • argumen: ini adalah objek yang mempunyai medan untuk setiap argumen (mis., "url" dalam contoh di atas); objek ini seterusnya mempunyai bidang ini:

    • taipkan: "string" atau "number"
    • defaultValue: nilai lalai yang akan diisi sebelumnya.

Sebagai contoh, berikut adalah bidang blok dalam pelanjutan Pengambilan saya:

"blok": [{"opcode": "fetchURL", "blockType": "reporter", "text": "ambil data dari ", "argumen": {"url": {"type": "string", "defaultValue ":" https://api.weather.gov/stations/KNYC/observations "},}}, {" opcode ":" jsonExtract "," blockType ":" reporter "," text ":" ekstrak [nama] dari [data] "," argumen ": {" name ": {" type ":" string "," defaultValue ":" temperature "}," data ": {" type ":" string "," defaultValue ": '{"suhu": 12.3}'},}},]

Di sini, kami menentukan dua blok: fetchURL dan jsonExtract. Kedua-duanya adalah wartawan. Yang pertama menarik data dari URL dan mengembalikannya, dan yang kedua mengekstrak medan dari data JSON.

Akhirnya, anda perlu memasukkan kaedah untuk dua blok. Setiap kaedah mengambil objek sebagai argumen, dengan objek termasuk bidang untuk semua argumen. Anda boleh menyahkodnya menggunakan pendakap keriting dalam argumen. Sebagai contoh, berikut adalah satu contoh serentak:

jsonExtract ({nama, data}) {

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

Kod tersebut menarik bidang nama dari data JSON. Sekiranya medan mengandungi rentetan, nombor atau boolean, kami mengembalikannya. Jika tidak, kami kembali JSONify lapangan. Dan kami mengembalikan rentetan kosong jika namanya hilang dari JSON.

Namun, kadangkala, anda mungkin mahu membuat blok yang menggunakan API tak segerak. Kaedah fetchURL () menggunakan API pengambilan yang tidak segerak. Dalam kes sedemikian, anda harus mengembalikan janji dari kaedah anda yang berjaya. Contohnya:

fetchURL ({url}) {

kembali ambil (url). kemudian (respons => respons.text ())}

Itu sahaja. Sambungan penuh ada di sini.

Langkah 4: Menggunakan Sambungan Kotak Pasir

Menggunakan Sambungan Kotak Pasir
Menggunakan Sambungan Kotak Pasir
Menggunakan Sambungan Kotak Pasir
Menggunakan Sambungan Kotak Pasir
Menggunakan Sambungan Kotak Pasir
Menggunakan Sambungan Kotak Pasir

Terdapat dua cara menggunakan peluasan kotak pasir. Pertama, anda boleh memuat naiknya ke pelayan web, dan kemudian memuatkannya ke mod Scratch SheepTester. Kedua, anda boleh menyandikannya ke dalam URL data, dan memasukkannya ke mod Scratch. Saya sebenarnya menggunakan kaedah kedua sedikit untuk ujian, kerana mengelakkan kebimbangan mengenai versi lama dari pelanjutan yang dicache oleh pelayan. Perhatikan bahawa walaupun anda dapat menghoskan javascript dari Github Pages, anda tidak boleh melakukannya secara langsung dari repositori github biasa.

Fetch.js saya dihoskan di https://arpruss.github.io/fetch.js. Atau anda boleh menukar peluasan anda ke URL data dengan memuat naiknya di sini dan kemudian menyalinnya ke papan keratan. URL data adalah URL raksasa yang menyimpan keseluruhan fail di dalamnya.

Pergi ke mod Scratch SheepTester. Klik pada butang Tambah Sambungan di sudut kiri bawah. Kemudian klik "Pilih pelanjutan", dan masukkan URL anda (anda boleh menempelkan keseluruhan URL data gergasi jika anda mahu).

Sekiranya semuanya berjalan lancar, anda akan mempunyai entri untuk sambungan anda di sebelah kiri skrin Gores anda. Sekiranya keadaan tidak berjalan lancar, anda harus membuka konsol Javascript anda (shift-ctrl-J di Chrome) dan cuba menyelesaikan masalah ini.

Di atas anda akan menemui beberapa contoh kod yang mengambil dan menguraikan data JSON dari stesen KNYC (di New York) Perkhidmatan Cuaca Nasional AS, dan memaparkannya, sambil memutar sprite untuk menghadap ke arah yang sama seperti angin yang bertiup. Cara saya membuatnya adalah dengan mengambil data ke dalam penyemak imbas web, dan kemudian mencari tag. Sekiranya anda ingin mencuba stesen cuaca yang berbeza, masukkan poskod berdekatan ke dalam kotak carian di weather.gov, dan halaman cuaca untuk lokasi anda harus memberi anda kod stesen empat huruf, yang boleh anda gunakan sebagai pengganti KNYC di kod.

Anda juga boleh memasukkan pelanjutan kotak pasir anda tepat di URL untuk mod SheepTester dengan menambahkan argumen "? Url =". Contohnya:

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

Langkah 5: Menulis Sambungan Tanpa Kotak: Pengenalan

Pembina sambungan tanpa kotak dilewati objek Runtime. Anda boleh mengabaikannya atau menggunakannya. Salah satu penggunaan objek Runtime adalah dengan menggunakan propertiMSMS saat ini untuk menyegerakkan peristiwa ("hat block"). Sejauh yang saya tahu, semua kod blok acara disurvei secara berkala, dan setiap pusingan pengundian mempunyai nilai MS saat ini. Sekiranya anda memerlukan objek Runtime, anda mungkin akan memulakan peluasan anda dengan:

PEMBELAJARAN kelas {

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

Semua benda tetingkap standard boleh digunakan dalam sambungan tanpa kotak. Akhirnya, peluasan tanpa kotak anda harus diakhiri dengan sedikit kod sihir ini:

(fungsi () {

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

di mana anda harus mengganti EXTENSIONCLASS dengan kelas pelanjutan anda.

Langkah 6: Menulis Sambungan Tanpa Kotak: Gamepad Mudah

Sekarang mari buat peluasan gamepad sederhana yang menyediakan blok acara ("hat") tunggal apabila butang ditekan atau dilepaskan.

Semasa setiap kitaran pengundian blok acara, kami akan menyimpan cap waktu dari objek runtime, dan keadaan gamepad sebelumnya dan semasa. Cap waktu digunakan untuk mengenali jika kita mempunyai kitaran pengundian baru. Oleh itu, kita mulakan dengan:

kelas ScratchSimpleGamepad {

pembina (runtime) {this.runtime = runtime this.currentMSecs = -1 this.pre sebelumnyaButtons = this.currentButtons = }…} Kami akan mempunyai satu blok acara, dengan dua input - nombor butang dan menu untuk memilih sama ada kami mahu acara itu dicetuskan pada tekan atau siaran. Jadi, inilah kaedah kami

dapatkan maklumat() {

kembali {"id": "SimpleGamepad", "name": "SimpleGamepad", "blocks": [{"opcode": "buttonPressedReleased", "blockType": "hat", "text": "butang [eventType] "," argumen ": {" b ": {" type ":" number "," defaultValue ":" 0 "}," eventType ": {" type ":" number "," defaultValue ":" 1 "," menu ":" pressReleaseMenu "},},},]," menu ": {" pressReleaseMenu ": [{text:" tekan ", nilai: 1}, {teks:" lepaskan ", nilai: 0}],}}; } Saya rasa nilai dalam menu lungsur masih diteruskan ke fungsi opcode sebagai rentetan, walaupun dinyatakan sebagai nombor. Oleh itu, bandingkan secara eksplisit dengan nilai yang ditentukan dalam menu yang diperlukan. Kami sekarang menulis kaedah yang mengemas kini butang menyatakan setiap kali kitaran pengundian acara baru berlaku

kemas kini () {

jika (this.runtime.currentMSecs == this.currentMSecs) kembali // bukan kitaran pengundian baru ini.currentMSecs = this.runtime.currentMSecs var gamepads = navigator.getGamepads () if (gamepads == null || gamepads.length = = 0 || gamepads [0] == null) {this.previousButtons = this.currentButtons = return} var gamepad = gamepads [0] if (gamepad.buttons.length! = This.previousButtons.length) { // bilangan butang yang berbeza, jadi gamepad baru ini.previousButtons = untuk (var i = 0; i <gamepad.buttons.length; i ++) this.previousButtons.push (false)} lain {this.previousButtons = ini. currentButtons} this.currentButtons = untuk (var i = 0; i <gamepad.buttons.length; i ++) this.currentButtons.push (gamepad.buttons .pressed)} Akhirnya, kita dapat melaksanakan blok acara kita, dengan memanggil kaedah pembaruan () dan kemudian memeriksa apakah butang yang diperlukan baru saja ditekan atau dilepaskan, dengan membandingkan keadaan butang semasa dan sebelumnya

buttonPressedReleased ({b, eventType}) {

this.update () if (b <this.currentButtons.length) {if (eventType == 1) {// note: ini akan menjadi rentetan, jadi lebih baik membandingkannya dengan 1 daripada menganggapnya sebagai Boolean jika (this.currentButtons &&! this.pre sebelumnyaButtons ) {return true}} other {if (! this.currentButtons && this.previousButtons ) {return true}}} kembali palsu} Dan akhirnya kami menambahkan kod pendaftaran peluasan sihir kami setelah menentukan kelas

(fungsi () {

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

Anda boleh mendapatkan kod penuh di sini.

Langkah 7: Menggunakan Sambungan Tanpa Kotak

Menggunakan Sambungan Tanpa Kotak
Menggunakan Sambungan Tanpa Kotak

Sekali lagi, hoskan pelanjutan anda di suatu tempat, dan kali ini muatkan dengan load_plugin = bukannya url = argumen ke mod Scratch SheepTester. Sebagai contoh, untuk mod Gamepad sederhana saya, pergi ke:

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

(Ngomong-ngomong, jika anda mahukan gamepad yang lebih canggih, hapus "sederhana" dari URL di atas, dan anda akan mendapat sokongan sumbu dan analog.)

Sekali lagi, pelanjutan itu akan muncul di sebelah kiri editor Scratch anda. Di atas adalah program Scratch yang sangat sederhana yang mengatakan "hello" semasa anda menekan butang 0 dan "selamat tinggal" semasa anda melepaskannya.

Langkah 8: Keserasian dan Kelajuan Dwi

Saya perhatikan bahawa blok lanjutan menjalankan urutan magnitud lebih cepat menggunakan kaedah pemuatan yang saya gunakan untuk sambungan tanpa kotak. Oleh itu, melainkan jika anda mengambil berat tentang keselamatan dari menjalankan di kotak pasir Worker Web, kod anda akan mendapat manfaat daripada dimuat dengan argumen? Load_plugin = URL ke mod SheepTester.

Anda boleh menjadikan peluasan kotak pasir sesuai dengan kedua kaedah pemuatan dengan menggunakan kod berikut setelah menentukan kelas peluasan (ubah nama CLASSNAME menjadi nama kelas pelanjutan anda):

(fungsi () {

var extensionClass = CLASSNAME if (typeof window === "undefined" ||! window.vm) {Scratch.extensions.register (new extensionClass ())} lain-lain {var extensionInstance = new extensionClass (window.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension (extensionInstance) window.vm.extensionManager._loadedExtensions.set (extensionInstance.getInfo (). id, serviceName)}}) ()

Disyorkan: