İçindekiler:
- Adım 1: İki Uzantı Türü
- 2. Adım: Korumalı Alana Alınmış Uzantı Yazma: Bölüm I
- 3. Adım: Korumalı Alana Alınmış Uzantı Yazma: Bölüm II
- 4. Adım: Korumalı Alanda Uzantı Kullanma
- 5. Adım: Korumalı Alana Alınmamış Uzantı Yazma: Giriş
- 6. Adım: Korumalı Alana Alınmamış Uzantı Yazma: Basit Oyun Kumandası
- 7. Adım: Korumalı Alana Sahip Olmayan Uzantıyı Kullanma
- Adım 8: Çift Uyumluluk ve Hız
Video: Scratch 3.0 Uzantıları: 8 Adım
2024 Yazar: John Day | [email protected]. Son düzenleme: 2024-01-30 13:16
Scratch uzantıları, Scratch'e yeni bloklar ekleyen Javascript kodu parçalarıdır. Scratch bir dizi resmi uzantıyla birlikte gelirken, kullanıcı yapımı uzantıları eklemek için resmi bir mekanizma yoktur.
Scratch 3.0 için Minecraft kontrol uzantımı yaparken, başlamayı zor buldum. Bu Eğitilebilir Kitap, çeşitli kaynaklardan (özellikle bu) bilgileri ve ayrıca kendim keşfettiğim birkaç şeyi bir araya toplar.
Javascript'te nasıl programlanacağını ve Javascript'inizi bir web sitesinde nasıl barındıracağınızı bilmeniz gerekir. İkincisi için GitHub Pages'i öneririm.
İşin püf noktası, SheepTester'ın uzantıları ve eklentileri yüklemenize izin veren Scratch modunu kullanmaktır.
Bu Eğitilebilir Tablo, iki uzantı oluşturma konusunda size rehberlik edecektir:
- Getirme: bir URL'den veri yükleme ve örneğin hava durumu verilerini yüklemek için JSON etiketlerini çıkarma
- SimpleGamepad: Scratch'te bir oyun kumandası kullanma (daha gelişmiş bir sürüm burada).
Adım 1: İki Uzantı Türü
"Korumalı olmayan" ve "korumalı alan" olarak adlandıracağım iki tür uzantı vardır. Korumalı alan uzantıları Web Çalışanları olarak çalışır ve sonuç olarak önemli sınırlamalara sahiptir:
- Web Çalışanları, pencere nesnesindeki küresellere erişemezler (bunun yerine, çok daha sınırlı bir küresel öz nesneye sahiptirler), bu nedenle bunları oyun kumandası erişimi gibi şeyler için kullanamazsınız.
- Korumalı alan uzantılarının, Scratch çalışma zamanı nesnesine erişimi yoktur.
- Korumalı alan uzantıları çok daha yavaştır.
- Korumalı alan uzantıları için Javascript konsolu hata mesajları, Chrome'da daha şifrelidir.
Diğer yandan:
- Diğer kişilerin korumalı alan uzantılarını kullanmak daha güvenlidir.
- Korumalı alan uzantılarının, herhangi bir nihai resmi uzantı yükleme desteğiyle çalışması daha olasıdır.
- Korumalı alan uzantıları, bir data:// URL'sine kodlanarak bir web sunucusuna yüklenmeden test edilebilir.
Resmi uzantıların (Müzik, Kalem vb.) tümü korumalı alanda değildir. Uzantının yapıcısı, çalışma zamanı nesnesini Scratch'ten alır ve pencereye tamamen erişilebilir.
Getirme uzantısı korumalı alana sahiptir, ancak Gamepad'in pencereden gezgin nesnesine ihtiyacı vardır.
2. Adım: Korumalı Alana Alınmış Uzantı Yazma: Bölüm I
Bir uzantı oluşturmak için, onunla ilgili bilgileri kodlayan bir sınıf oluşturursunuz ve ardından uzantıyı kaydetmek için biraz kod eklersiniz.
Uzantı sınıfındaki ana şey, gerekli alanları içeren bir nesneyi döndüren bir getInfo() yöntemidir:
- id: uzantının dahili adı, her uzantı için benzersiz olmalıdır
- name: Scratch'in blok listesinde görünen uzantının kolay adı
- bloklar: yeni özel bloğu açıklayan nesnelerin listesi.
Ayrıca, Getir'de kullanılmayan ancak Gamepad'de kullanılacak isteğe bağlı bir menü alanı var.
İşte Fetch için temel şablon:
sınıf ScratchFetch {
yapıcı() { } getInfo() { return { "id": "Getir", "ad": "Getir", "bloklar": [/* daha sonra ekle */] } } /* bloklar için yöntemler ekle */ } Scratch.extensions.register(yeni ScratchFetch())
3. Adım: Korumalı Alana Alınmış Uzantı Yazma: Bölüm II
Şimdi getInfo()'nun nesnesindeki blokların listesini oluşturmamız gerekiyor. Her bloğun en az şu dört alana ihtiyacı vardır:
- opcode: Bu, bloğun işini yapmak için çağrılan yöntemin adıdır.
-
blockType: bu blok tipidir; uzantılar için en yaygın olanları şunlardır:
- "komut": bir şey yapar ama bir değer döndürmez
- "raportör": bir dize veya sayı döndürür
- "Boolean": bir boole döndürür (büyük harf kullanımına dikkat edin)
- "hat": olay yakalama bloğu; Scratch kodunuz bu bloğu kullanıyorsa, Scratch çalışma zamanı, olayın olup olmadığını söylemek için bir boole döndüren ilişkili yöntemi düzenli olarak yoklar.
- metin: bu, parantez içindeki argümanlarla birlikte bloğun kolay bir açıklamasıdır, ör. "'den veri al"
-
argümanlar: bu, her argüman için bir alanı olan bir nesnedir (örneğin, yukarıdaki örnekte "url"); bu nesne sırayla şu alanlara sahiptir:
- tür: "dize" veya "sayı"
- defaultValue: önceden doldurulacak varsayılan değer.
Örneğin, Fetch uzantımdaki bloklar alanı:
"bloklar": [{ "opcode": "fetchURL", "blockType": "raporcu", "metin": "'den veri al", "arguments": { "url": { "type": "string", "defaultValue ": "https://api.weather.gov/stations/KNYC/observations" }, } }, { "opcode": "jsonExtract", "blockType": "reporter", "text": "extract [name] from [data]", "arguments": { "name": { "type": "string", "defaultValue": "sıcaklık" }, "data": { "type": "string", "defaultValue": '{"sıcaklık": 12.3}' }, } },]
Burada iki blok tanımladık: fetchURL ve jsonExtract. İkisi de muhabir. Birincisi, bir URL'den veri çeker ve onu döndürür ve ikincisi, JSON verilerinden bir alan çıkarır.
Son olarak, iki blok için yöntemleri eklemeniz gerekir. Her yöntem, tüm argümanlar için alanları içeren nesneyle birlikte bir nesneyi argüman olarak alır. Bunları bağımsız değişkenlerde küme parantezleri kullanarak çözebilirsiniz. Örneğin, burada bir senkronize örnek:
jsonExtract({ad, veri}) {
var parsed = JSON.parse(data) if (ad in parsed) { var out = parsed[name] var t = typeof(out) if (t == "string" || t == "number") return out if (t == "boolean") dönüş t ? 1: 0 dönüş JSON.stringify(out) } else { return "" } }
Kod, ad alanını JSON verilerinden alır. Alan bir dize, sayı veya boole içeriyorsa, onu döndürürüz. Aksi takdirde, alanı yeniden JSONifiye ederiz. JSON'da isim eksikse boş bir dize döndürürüz.
Ancak bazen, zaman uyumsuz bir API kullanan bir blok oluşturmak isteyebilirsiniz. fetchURL() yöntemi, eşzamansız olan getirme API'sini kullanır. Böyle bir durumda, işi yapan yönteminizden bir söz vermelisiniz. Örneğin:
fetchURL({url}) {
döndürme fetch(url).then(yanıt => yanıt.text()) }
Bu kadar. Tam uzantı burada.
4. Adım: Korumalı Alanda Uzantı Kullanma
Korumalı alan uzantısını kullanmanın iki yolu vardır. İlk önce onu bir web sunucusuna yükleyebilir ve ardından SheepTester'ın Scratch moduna yükleyebilirsiniz. İkinci olarak, onu bir veri URL'sine kodlayabilir ve bunu Scratch moduna yükleyebilirsiniz. Aslında, uzantının eski sürümlerinin sunucu tarafından önbelleğe alınmasıyla ilgili endişeleri ortadan kaldırdığı için, test için ikinci yöntemi biraz kullanıyorum. Javascript'i Github Pages'den barındırabilirken, bunu doğrudan sıradan bir github deposundan yapamayacağınızı unutmayın.
fetch.js'im https://arpruss.github.io/fetch.js adresinde barındırılıyor. Veya uzantınızı buraya yükleyerek bir veri URL'sine dönüştürebilir ve ardından panoya kopyalayabilirsiniz. Veri URL'si, içinde bir dosyanın tamamını tutan dev bir URL'dir.
SheepTester'ın Scratch moduna gidin. Sol alt köşedeki Uzantı Ekle düğmesini tıklayın. Ardından "Bir uzantı seçin"i tıklayın ve URL'nizi girin (isterseniz dev veri URL'sinin tamamını yapıştırabilirsiniz).
Her şey yolunda giderse, Scratch ekranınızın sol tarafında uzantınız için bir girişiniz olacaktır. İşler yolunda gitmediyse, Javascript konsolunuzu (Chrome'da shift-ctrl-J) açmalı ve sorunu gidermeye çalışmalısınız.
Yukarıda, ABD Ulusal Hava Durumu Servisi'nin KNYC (New York'taki) istasyonundan JSON verilerini alıp ayrıştıran ve hareketli grafiği rüzgarın estiği yöne bakacak şekilde döndürürken görüntüleyen bazı örnek kodlar bulacaksınız. Bunu yapmamın yolu, verileri bir web tarayıcısına getirmek ve ardından etiketleri bulmaktı. Farklı bir hava durumu istasyonunu denemek istiyorsanız, hava durumu.gov adresindeki arama kutusuna yakındaki bir posta kodunu girin ve bulunduğunuz yerin hava durumu sayfası size KNYC yerine kullanabileceğiniz dört harfli bir istasyon kodu vermelidir. kod.
Ayrıca, bir "?url=" bağımsız değişkeni ekleyerek, korumalı alan uzantınızı SheepTester modunun URL'sine ekleyebilirsiniz. Örneğin:
sheeptester.github.io/scratch-gui/?url=https://arpruss.github.io/fetch.js
5. Adım: Korumalı Alana Alınmamış Uzantı Yazma: Giriş
Korumalı alanda olmayan bir uzantının yapıcısı, bir Runtime nesnesinden geçer. Bunu görmezden gelebilir veya kullanabilirsiniz. Runtime nesnesinin bir kullanımı, olayları ("şapka blokları") eşitlemek için currentMSecs özelliğini kullanmaktır. Anlayabildiğim kadarıyla, tüm olay bloğu işlem kodları düzenli olarak yoklanır ve yoklamanın her turunda tek bir currentMSecs değeri vardır. Runtime nesnesine ihtiyacınız varsa, muhtemelen uzantınıza şu şekilde başlayacaksınız:
sınıf EXTENSIONCLASS {
yapıcı(çalışma zamanı) { this.runtime = runtime … } … }
Korumalı olmayan uzantıda tüm standart pencere nesnesi öğeleri kullanılabilir. Son olarak, korumalı alanda olmayan uzantınız şu sihirli kod parçasıyla bitmelidir:
(işlev() {
var extensionInstance = new EXTENSIONCLASS(window.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension(extensionInstance) window.vm.extensionManager._loadedExtensions.set(extensionInstance.getInfo().id, serviceName) })()
EXTENSIONCLASS'ı uzantınızın sınıfıyla değiştirmelisiniz.
6. Adım: Korumalı Alana Alınmamış Uzantı Yazma: Basit Oyun Kumandası
Şimdi bir düğmeye basıldığında veya bırakıldığında tek bir olay ("şapka") bloğu sağlayan basit bir gamepad uzantısı yapalım.
Her olay bloğu yoklama döngüsü sırasında, çalışma zamanı nesnesinden ve önceki ve mevcut oyun kumandası durumlarından bir zaman damgası kaydedeceğiz. Zaman damgası, yeni bir yoklama döngümüz olup olmadığını anlamak için kullanılır. Öyleyse başlıyoruz:
sınıf ScratchSimpleGamepad {
yapıcı(çalışma zamanı) { this.runtime = çalışma zamanı this.currentMSecs = -1 this.previousButtons = this.currentButtons = } … } İki girişli bir olay bloğumuz olacak - bir düğme numarası ve olayın basıldığında mı yoksa bırakıldığında mı tetiklenmesini istediğimizi seçmek için bir menü. Yani, işte yöntemimiz
bilgi almak() {
return { "id": "SimpleGamepad", "name": "SimpleGamepad", "blocks": [{ "opcode": "buttonPressedReleased", "blockType": "hat", "text": "button [eventType]", "arguments": { "b": { "type": "number", "defaultValue": "0" }, "eventType": { "type": "number", "defaultValue": "1 ", "menu": "pressReleaseMenu" }, }, },], "menüler": { "pressReleaseMenu": [{text:"press", value:1}, {text:"release", value:0}], } }; } Açılır menüdeki değerlerin sayı olarak bildirilmelerine rağmen hala opcode işlevine dizeler olarak aktarıldığını düşünüyorum. Bu nedenle, gerektiğinde bunları menüde belirtilen değerlerle açıkça karşılaştırın. Şimdi yeni bir olay yoklama döngüsü gerçekleştiğinde düğme durumlarını güncelleyen bir yöntem yazıyoruz.
Güncelleme() {
if (this.runtime.currentMSecs == this.currentMSecs) dönüşü // yeni bir yoklama döngüsü değil this.currentMSecs = this.runtime.currentMSecs var gamepads = navigator.getGamepads() if (gamepads == null || gamepads.length = = 0 || gamepads[0] == null) { this.previousButtons = this.currentButtons = dönüş } var gamepad = gamepads[0] if (gamepad.buttons.length != this.previousButtons.length) { // farklı sayıda düğme, yani yeni oyun kumandası 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) } Son olarak, update() yöntemini çağırarak ve ardından mevcut ve önceki düğme durumlarını karşılaştırarak gerekli düğmeye yeni basılıp basılmadığını kontrol ederek olay bloğumuzu uygulayabiliriz.
buttonPressedReleased({b, eventType}) {
this.update() if (b < this.currentButtons.length) { if (eventType == 1) { // not: bu bir dize olacaktır, bu nedenle onu Boolean olarak ele almaktansa 1 ile karşılaştırmak daha iyidir (this.currentButtons && ! this.previousButtons) { return true } } else { if (!this.currentButtons && this.previousButtons) { return true } } } false döndür } Ve son olarak sınıfı tanımladıktan sonra sihirli uzantı kayıt kodumuzu ekliyoruz.
(işlev() {
var extensionInstance = new ScratchSimpleGamepad(window.vm.extensionManager.runtime) var serviceName = window.vm.extensionManager._registerInternalExtension(extensionInstance) window.vm.extensionManager._loadedExtensions.set(extensionInstance.getInfo().id, serviceName))
Kodun tamamını buradan alabilirsiniz.
7. Adım: Korumalı Alana Sahip Olmayan Uzantıyı Kullanma
Bir kez daha, uzantınızı bir yerde barındırın ve bu sefer SheepTester'ın Scratch moduna url= argümanı yerine load_plugin= ile yükleyin. Örneğin, basit Gamepad modum için şuraya gidin:
sheeptester.github.io/scratch-gui/?load_plugin=https://arpruss.github.io/simplegamepad.js
(Bu arada, daha gelişmiş bir gamepad istiyorsanız, yukarıdaki URL'den "basit" ifadesini kaldırmanız yeterlidir; rumble ve analog eksen desteğine sahip olacaksınız.)
Yine, uzantı, Scratch düzenleyicinizin sol tarafında görünmelidir. Yukarıda 0 düğmesine bastığınızda "merhaba", bıraktığınızda "hoşçakal" yazan çok basit bir Scratch programı var.
Adım 8: Çift Uyumluluk ve Hız
Korumalı alanda olmayan uzantılar için kullandığım yükleme yöntemini kullanarak uzantı bloklarının çok daha hızlı çalıştığını fark ettim. Bu nedenle, bir Web Worker sanal alanında çalışmanın güvenlik yararlarını önemsemiyorsanız, kodunuz SheepTester'ın moduna ?load_plugin=URL bağımsız değişkeni ile yüklenmekten fayda sağlayacaktır.
Uzantı sınıfını tanımladıktan sonra aşağıdaki kodu kullanarak korumalı alanlı bir uzantıyı her iki yükleme yöntemiyle uyumlu hale getirebilirsiniz (CLASSNAME öğesini uzantı sınıfınızın adıyla değiştirin):
(işlev() {
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) } })()
Önerilen:
BBC Micro:bit ve Scratch - Etkileşimli Direksiyon & Sürüş Oyunu: 5 Adım (Resimlerle)
BBC Micro:bit ve Scratch - Etkileşimli Direksiyon Simidi ve Sürüş Oyunu: Bu haftaki sınıf ödevlerimden biri, yazdığımız bir Scratch programıyla arayüz oluşturmak için BBC Micro:bit'i kullanmak. Bunun, ThreadBoard'umu gömülü bir sistem oluşturmak için kullanmak için mükemmel bir fırsat olduğunu düşündüm! Scratch p için ilham kaynağım
ARDUINO + SCRATCH Atış Oyunu: 6 Adım
ARDUINO + SCRATCH Atış Oyunu: Pastanı kurtar !!!Tehlikede. Yaklaşan dört sinek var. Sinekleri vurmak ve pastanızı kurtarmak için sadece 30 saniyeniz var
Adım Adım Arduino Uno ile Akustik Kaldırma (8 adım): 8 Adım
Arduino Uno ile Akustik Kaldırma Adım Adım (8 adım): ultrasonik ses dönüştürücüler L298N erkek dc pinli Dc dişi adaptör güç kaynağı Arduino UNOBreadboardBu nasıl çalışır: İlk olarak, Arduino Uno'ya kod yüklersiniz (dijital ile donatılmış bir mikrodenetleyicidir) ve kodu dönüştürmek için analog bağlantı noktaları (C++)
Kendin Yap Servo Uzantıları: 4 Adım
Kendin Yap Servo Uzantıları: Tellerin yeterince uzun olmadığı servo motorlar kullanan bir Arduino veya robotik projesi üzerinde mi çalışıyorsunuz? O zaman servo uzantılarına ihtiyacınız var. Servo eklentilerini birçok hobi mağazasından ve internet üzerinden satın alabilirsiniz. Belirli bir servo markası için tasarlanmışlardır
Uzantıları Taşınabilir Bir Uygulamayla Kaydedin: 5 Adım
Uzantıları Taşınabilir Bir Uygulamayla Kaydedin: Benden hoşlanıyorsanız, en sevdiğiniz programlarla birlikte bir parmak sürücünüzü yanınızda taşırsınız. Bazı programların profilleri (firefox) vardır ve bazılarının acil durumlar için olması harikadır. Sebep ne olursa olsun, programı bağlamayı amaçlı bulabilirsiniz ve