Სარჩევი:

Scratch 3.0 გაფართოებები: 8 ნაბიჯი
Scratch 3.0 გაფართოებები: 8 ნაბიჯი

ვიდეო: Scratch 3.0 გაფართოებები: 8 ნაბიჯი

ვიდეო: Scratch 3.0 გაფართოებები: 8 ნაბიჯი
ვიდეო: MKS Monster8 - Basics 2024, ივლისი
Anonim
Scratch 3.0 გაფართოება
Scratch 3.0 გაფართოება

Scratch გაფართოებები არის Javascript კოდის ნაჭრები, რომლებიც დაამატებენ ახალ ბლოკებს Scratch- ში. მიუხედავად იმისა, რომ Scratch შეფუთულია რამდენიმე ოფიციალური გაფართოებით, არ არსებობს მომხმარებლის მიერ შექმნილი გაფართოებების დამატების ოფიციალური მექანიზმი.

როდესაც მე ვაკეთებდი Minecraft– ს მაკონტროლებელ გაფართოებას Scratch 3.0– ისთვის, გამიჭირდა დაწყება. ეს ინსტრუქცია ერთად აგროვებს ინფორმაციას სხვადასხვა წყაროებიდან (განსაკუთრებით ეს), პლუს რამდენიმე რამ, რაც მე თვითონ აღმოვაჩინე.

თქვენ უნდა იცოდეთ როგორ დაპროგრამდეთ Javascript– ში და როგორ უმასპინძლოთ თქვენს Javascript ვებსაიტს. ამ უკანასკნელისთვის მე გირჩევთ GitHub გვერდებს.

მთავარი ხრიკია გამოიყენოთ SheepTester– ის Scratch რეჟიმი, რომელიც გაძლევთ საშუალებას ჩატვირთოთ გაფართოებები და მოდულები.

ეს ინსტრუქცია დაგეხმარებათ ორი გაფართოების გაკეთებაში:

  • ამოღება: მონაცემების ჩატვირთვა URL– დან და JSON ტეგების ამოღება, მაგალითად ამინდის მონაცემების ჩატვირთვისთვის
  • SimpleGamepad: თამაშის კონტროლერის გამოყენება Scratch– ში (აქ არის უფრო დახვეწილი ვერსია).

ნაბიჯი 1: გაფართოებების ორი ტიპი

არსებობს ორი სახის გაფართოება, რომელსაც მე მოვუწოდებ "დაუსაბუთებელ" და "ქვიშის ყუთში". Sandboxed გაფართოებები მუშაობს როგორც ვებ მუშაკები და შედეგად აქვს მნიშვნელოვანი შეზღუდვები:

  • ვებ მუშაკებს არ შეუძლიათ გლობალური წვდომა ფანჯრის ობიექტში (სამაგიეროდ, მათ აქვთ გლობალური თვით ობიექტი, რაც გაცილებით შეზღუდულია), ასე რომ თქვენ არ შეგიძლიათ გამოიყენოთ ისინი ისეთი რამისთვის, როგორიცაა გეიმპედის წვდომა.
  • Sandboxed გაფართოებებს არ აქვთ წვდომა Scratch გაშვების ობიექტზე.
  • Sandboxed გაფართოებები ბევრად უფრო ნელია.
  • Javascript კონსოლის შეცდომის შეტყობინებები ქვიშიანი გაფართოებებისათვის Chrome- ში უფრო საიდუმლოებაა.

Მეორეს მხრივ:

  • სხვა ადამიანების ქვიშიანი გაფართოებების გამოყენება უფრო უსაფრთხოა.
  • Sandboxed გაფართოებები უფრო სავარაუდოა, რომ იმუშაოს ნებისმიერი ოფიციალური გაფართოების ჩატვირთვის მხარდაჭერით.
  • Sandboxed გაფართოებების შემოწმება შესაძლებელია ვებ სერვერზე ატვირთვის გარეშე მონაცემებში: // URL.

ოფიციალური გაფართოებები (როგორიცაა მუსიკა, კალამი და ა.შ.) ყველა დაუსაბუთებელია. გაფართოების კონსტრუქტორი იღებს გაშვების ობიექტს Scratch– დან და ფანჯარა სრულად არის მისაწვდომი.

Fetch გაფართოება შეფუთულია, მაგრამ Gamepad– ს სჭირდება ნავიგატორი ობიექტი ფანჯრიდან.

ნაბიჯი 2: ქვიშის ყუთში გაფართოების დაწერა: ნაწილი I

გაფართოების შესაქმნელად თქვენ ქმნით კლასს, რომელიც აკოდირებს ინფორმაციას მის შესახებ და შემდეგ დაამატეთ ცოტა კოდი გაფართოების რეგისტრაციისთვის.

გაფართოების კლასში მთავარია getInfo () მეთოდი, რომელიც უბრუნებს ობიექტს საჭირო ველებით:

  • id: გაფართოების შიდა სახელი, უნდა იყოს უნიკალური თითოეული გაფართოებისთვის
  • სახელი: გაფართოების მეგობრული სახელი, რომელიც ნაჩვენებია Scratch– ის ბლოკების სიაში
  • ბლოკები: ახალი პერსონალური ბლოკის აღმწერი ობიექტების სია.

და არის არჩევითი მენიუს ველი, რომელიც არ გამოიყენება Fetch– ში, მაგრამ გამოყენებული იქნება Gamepad– ში.

ასე რომ, აქ არის ძირითადი შაბლონი Fetch:

კლასი ScratchFetch {

კონსტრუქტორი () {} getInfo () {return {"id": "მიღება", "name": "მიღება", "ბლოკები": [/* მოგვიანებით დამატება * /]}} / * ბლოკების მეთოდების დამატება * /} Scratch.extensions.register (ახალი ScratchFetch ())

ნაბიჯი 3: ქვიშის ყუთში გაფართოების დაწერა: ნაწილი II

ახლა ჩვენ უნდა შევქმნათ ბლოკების სია getInfo () ობიექტში. თითოეულ ბლოკს სჭირდება სულ მცირე ეს ოთხი ველი:

  • ოპ კოდი: ეს არის მეთოდის სახელი, რომელსაც ბლოკის მუშაობის შესასრულებლად ეძახიან
  • blockType: ეს არის ბლოკის ტიპი; გაფართოებისთვის ყველაზე გავრცელებულია:

    • "ბრძანება": აკეთებს რაღაცას, მაგრამ არ აბრუნებს მნიშვნელობას
    • "რეპორტიორი": აბრუნებს სტრიქონს ან რიცხვს
    • "ლოგიკური": აბრუნებს ბულს (შენიშვნა დიდი ასოებით)
    • "ქუდი": ღონისძიების დაჭერის ბლოკი; თუ თქვენი Scratch კოდი იყენებს ამ ბლოკს, Scratch გაშვების დრო რეგულარულად ატარებს გამოკითხვასთან დაკავშირებულ მეთოდს, რომელიც აბრუნებს ლოგიკურ მონაცემებს იმის შესახებ, მოხდა თუ არა მოვლენა
  • ტექსტი: ეს არის ბლოკის მეგობრული აღწერა, ფრჩხილებში არგუმენტებით, მაგალითად, "მონაცემების მოპოვება - დან"
  • არგუმენტები: ეს არის ობიექტი, რომელსაც აქვს ველი ყველა არგუმენტისთვის (მაგალითად, "url" ზემოთ მოცემულ მაგალითში); ამ ობიექტს თავის მხრივ აქვს ეს ველები:

    • ტიპი: ან "სტრიქონი" ან "ნომერი"
    • defaultValue: ნაგულისხმევი მნიშვნელობა, რომელიც უნდა შეივსოს წინასწარ.

მაგალითად, აქ არის ბლოკების ველი ჩემს Fetch გაფართოებაში:

"ბლოკები": [{"opcode": "fetchURL", "blockType": "reporter", "text": "მონაცემების მოპოვება - დან", "არგუმენტები": {"url": {"type": "string", "defaultValue ":" https://api.weather.gov/stations/KNYC/observations "},}}, {" opcode ":" jsonExtract "," blockType ":" reporter "," text ":" ამონაწერი [სახელი] [data] "," argument ": {" name ": {" type ":" string "," defaultValue ":" temperature "}," data ": {" type ":" string "," defaultValue ": '{"ტემპერატურა": 12.3}'},}},]

აქ ჩვენ განვსაზღვრეთ ორი ბლოკი: fetchURL და jsonExtract. ორივე ჟურნალისტია. პირველი ამოიღებს მონაცემებს URL– დან და აბრუნებს მას, ხოლო მეორე ამოიღებს ველს JSON მონაცემებიდან.

დაბოლოს, თქვენ უნდა შეიტანოთ მეთოდები ორი ბლოკისთვის. თითოეული მეთოდი იღებს ობიექტს არგუმენტად, ობიექტი მოიცავს ველებს ყველა არგუმენტისთვის. თქვენ შეგიძლიათ გაშიფროთ ისინი არგუმენტებში ხვეული სამაგრების გამოყენებით. მაგალითად, აქ არის ერთი სინქრონული მაგალითი:

jsonExtract ({სახელი, მონაცემები}) {

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 == "ლოგიკური") დაბრუნება t? 1: 0 დაბრუნება JSON.stringify (out)} სხვა {დაბრუნება ""}}

კოდი ამოიღებს სახელის ველს JSON მონაცემებიდან. თუ ველი შეიცავს სტრიქონს, რიცხვს ან ლოგიკურს, ჩვენ ამას ვუბრუნებთ. წინააღმდეგ შემთხვევაში, ჩვენ ხელახლა JSONify ველი. და ჩვენ ვუბრუნებთ ცარიელ სტრიქონს, თუ სახელი აკლია JSON– ში.

ზოგჯერ, შეიძლება დაგჭირდეთ ბლოკის გაკეთება, რომელიც იყენებს ასინქრონული API- ს. FetchURL () მეთოდი იყენებს fetch API რომელიც არის ასინქრონული. ასეთ შემთხვევაში, თქვენ უნდა დააბრუნოთ დაპირება თქვენი მეთოდისგან, რომელიც მუშაობს. Მაგალითად:

fetchURL ({url}) {

დაბრუნების მოტანა (url).მერე (პასუხი => პასუხი. ტექსტი ())}

Ის არის. სრული გაფართოება აქ არის.

ნაბიჯი 4: Sandboxed გაფართოების გამოყენება

Sandboxed გაფართოების გამოყენება
Sandboxed გაფართოების გამოყენება
Sandboxed გაფართოების გამოყენება
Sandboxed გაფართოების გამოყენება
Sandboxed გაფართოების გამოყენება
Sandboxed გაფართოების გამოყენება

ქვიშის ყუთში გაფართოების გამოყენების ორი გზა არსებობს. პირველ რიგში, თქვენ შეგიძლიათ ატვირთოთ იგი ვებ სერვერზე და შემდეგ ჩატვირთოთ იგი SheepTester– ის Scratch რეჟიმში. მეორე, შეგიძლიათ მისი კოდირება მონაცემთა URL– ში და ჩატვირთვა Scratch რეჟიმში. მე რეალურად ვიყენებ მეორე მეთოდს შესამოწმებლად, რადგან ის თავს არიდებს შეშფოთებას გაფართოების ძველი ვერსიების სერვერის ქეშირების გამო. გაითვალისწინეთ, რომ მიუხედავად იმისა, რომ თქვენ შეგიძლიათ უმასპინძლოთ javascript Github Pages– დან, ამის გაკეთება არ შეგიძლიათ უშუალოდ ჩვეულებრივი github საცავიდან.

ჩემი fetch.js მასპინძლობს https://arpruss.github.io/fetch.js. ან შეგიძლიათ გადააკეთოთ თქვენი გაფართოება მონაცემთა URL– ზე აქ ატვირთვით და შემდეგ დააკოპირეთ ბუფერში. მონაცემთა URL არის გიგანტური URL, რომელიც შეიცავს მთელ ფაილს მასში.

გადადით SheepTester– ის Scratch რეჟიმში. დააწკაპუნეთ ქვედა მარცხენა კუთხეში დამატების დამატების ღილაკზე. შემდეგ დააწკაპუნეთ "აირჩიეთ გაფართოება" და შეიყვანეთ თქვენი URL (თუ გსურთ, ჩასვით მთლიანი გიგანტური მონაცემების URL).

თუ ყველაფერი კარგად დასრულდა, თქვენ გექნებათ ჩანაწერი თქვენი გაფართოებისთვის თქვენი Scratch ეკრანის მარცხენა მხარეს. თუ საქმე კარგად არ მიდის, თქვენ უნდა გახსნათ თქვენი Javascript კონსოლი (shift-ctrl-J Chrome- ში) და სცადოთ საკითხის გამართვა.

ზემოთ თქვენ იხილავთ კოდის მაგალითს, რომელიც მოიტანს და აანალიზებს JSON მონაცემებს აშშ -ს ეროვნული ამინდის ამინდის KNYC (ნიუ იორკში) სადგურიდან და აჩვენებს მას, ხოლო სპრაიტი გადააქვს ისე, როგორც ქარი უბერავს. მე ეს გავაკეთე მონაცემების ბრაუზერში შეტანით და შემდეგ ტეგების გააზრებით. თუ გსურთ სცადოთ სხვა ამინდის სადგური, შეიყვანეთ მიმდებარე საფოსტო კოდი საძიებო ველში weather.gov და ამინდის ადგილმდებარეობის ამინდის გვერდი უნდა მოგცეთ ოთხი ასო სადგურის კოდი, რომელიც შეგიძლიათ გამოიყენოთ KNYC– ის ადგილას კოდი.

თქვენ ასევე შეგიძლიათ შეიყვანოთ თქვენი sandboxed გაფართოება პირდაპირ URL– ში SheepTester– ის მოდემისთვის „? Url =“არგუმენტის დამატებით. Მაგალითად:

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

ნაბიჯი 5: ჩაწერეთ Unsandboxed გაფართოება: შესავალი

კონსტრუქტორი unsandboxed გაფართოების იღებს გადადის Runtime ობიექტი. შეგიძლიათ იგნორირება გაუკეთოთ ან გამოიყენოთ. Runtime ობიექტის ერთ -ერთი გამოყენებაა მისი currentMSecs თვისებების გამოყენება მოვლენების სინქრონიზაციისათვის ("ქუდის ბლოკები"). რამდენადაც მე შემიძლია გითხრათ, ყველა მოვლენის ბლოკის კოდის გამოკითხვა ხდება რეგულარულად და კენჭისყრის თითოეულ რაუნდს აქვს ერთი მიმდინარე MSecs მნიშვნელობა. თუ თქვენ გჭირდებათ Runtime ობიექტი, თქვენ ალბათ დაიწყებთ თქვენს გაფართოებას შემდეგით:

კლასის EXTENSIONCLASS {

კონსტრუქტორი (runtime) {this.runtime = runtime…}…}

ყველა სტანდარტული ფანჯრის ობიექტის საგნები შეიძლება გამოყენებულ იქნას ყუთში მოთავსებულ გაფართოებაში. დაბოლოს, თქვენი ჩაკეტილი გაფართოება უნდა დასრულდეს ამ ჯადოსნური კოდით:

(ფუნქცია () {

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

სადაც თქვენ უნდა შეცვალოთ EXTENSIONCLASS თქვენი გაფართოების კლასით.

ნაბიჯი 6: ჩაწერეთ Unsandboxed გაფართოება: მარტივი Gamepad

მოდით გავაკეთოთ მარტივი გეიმპადის გაფართოება, რომელიც უზრუნველყოფს ერთი ღონისძიების ("ქუდი") ბლოკს ღილაკზე დაჭერისას ან გათავისუფლებისას.

თითოეული მოვლენის ბლოკირების გამოკითხვის ციკლის განმავლობაში, ჩვენ დაზოგავთ დროის ნიშნულს გაშვების ობიექტიდან და წინა და მიმდინარე გეიმპადის მდგომარეობიდან. დროის ნიშნული გამოიყენება იმის დასადგენად, გვაქვს თუ არა ახალი კენჭისყრის ციკლი. ასე რომ, ჩვენ ვიწყებთ:

კლასი ScratchSimpleGamepad {

კონსტრუქტორი (runtime) {this.runtime = runtime this.currentMSecs = -1 this.previousButtons = this.currentButtons = }…} ჩვენ გვექნება ერთი ღონისძიების ბლოკი, ორი შეყვანისას-ღილაკის ნომერი და მენიუ, რათა შევარჩიოთ გვინდა, რომ ღონისძიება დაიწყოს პრესაში ან გამოშვებაში. ასე რომ, აქ არის ჩვენი მეთოდი

ინფორმაციის მიღება() {

return {"id": "SimpleGamepad", "name": "SimpleGamepad", "blocks": [{"opcode": "buttonPressedReleased", "blockType": "hat", "text": "button [eventType] "," არგუმენტები ": {" b ": {" type ":" number "," defaultValue ":" 0 "}," eventType ": {" type ":" number "," defaultValue ":" 1 "," menu ":" pressReleaseMenu "},},},]," menus ": {" pressReleaseMenu ": [{text:" press ", value: 1}, {text:" release ", value: 0}],}}; } მე ვფიქრობ, რომ ჩამოსაშლელი მენიუს მნიშვნელობები კვლავ გადადის opcode ფუნქციაზე, როგორც სტრიქონები, მიუხედავად იმისა, რომ გამოცხადებულია ციფრებად. ასე რომ აშკარად შეადარეთ ისინი საჭიროებისამებრ მენიუში მითითებულ მნიშვნელობებს. ჩვენ ახლა ვწერთ მეთოდს, რომელიც განაახლებს ღილაკს, როდესაც ხდება ახალი მოვლენის გამოკითხვის ციკლი

განახლება () {

if (this.runtime.currentMSecs == this.currentMSecs) დაბრუნდება // არ არის ახალი კენჭისყრის ციკლი this.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) { // სხვადასხვა რაოდენობის ღილაკები, ასე რომ ახალი gamepad this.previousButtons = for (var i = 0; i <gamepad.buttons.length; i ++) this.previousButtons.push (false)} სხვა {this.previousButtons = this currentButtons} this.currentButtons = for (var i = 0; i <gamepad.buttons.length; i ++) this.currentButtons.push (gamepad.buttons .presspress)} დაბოლოს, ჩვენ შეგვიძლია განვახორციელოთ ჩვენი ღონისძიების ბლოკი განახლების () მეთოდის გამოძახებით და შემდგომ შემოწმებით, არის თუ არა საჭირო ღილაკი დაჭერილი ან გამოშვებული, ღილაკის ამჟამინდელი და წინა მდგომარეობების შედარების გზით

buttonPressedReleased ({b, eventType}) {

this.update () if (b <this.currentButtons.length) {if (eventType == 1) {// შენიშვნა: ეს იქნება სტრიქონი, ასე რომ სჯობს შევადაროთ 1 -ს, ვიდრე მას ლოგიკურად მივუდგეთ, თუ (this.currentButtons &&! this.previousButtons ) {true true}} სხვა {if (! this.currentButtons && this.previousButtons ) {true true}}} დაბრუნება false} და ბოლოს ჩვენ ვამატებთ ჩვენს ჯადოსნურ გაფართოების რეგისტრაციის კოდს კლასის განსაზღვრის შემდეგ

(ფუნქცია () {

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

აქ შეგიძლიათ მიიღოთ სრული კოდი.

ნაბიჯი 7: Unsandboxed გაფართოების გამოყენება

Unsandboxed გაფართოების გამოყენება
Unsandboxed გაფართოების გამოყენება

კიდევ ერთხელ, განათავსეთ თქვენი გაფართოება სადმე და ამჯერად ჩატვირთეთ იგი load_plugin = ვიდრე url = არგუმენტით SheepTester's Scratch mod. მაგალითად, ჩემი მარტივი Gamepad mod– ისთვის, გადადით:

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

(სხვათა შორის, თუ გსურთ უფრო დახვეწილი გეიმპედი, უბრალოდ წაშალეთ "მარტივი" ზემოაღნიშნული URL- დან და გექნებათ ხმაურის და ანალოგური ღერძის მხარდაჭერა.)

ისევ და ისევ, გაფართოება უნდა გამოჩნდეს თქვენი Scratch რედაქტორის მარცხენა მხარეს. ზემოთ არის ძალიან მარტივი Scratch პროგრამა, რომელიც ამბობს "გამარჯობა" როდესაც დააჭირეთ ღილაკს 0 და "ნახვამდის" როდესაც გაათავისუფლებთ მას.

ნაბიჯი 8: ორმაგი თავსებადობა და სიჩქარე

მე შევამჩნიე, რომ გაფართოების ბლოკები უფრო სწრაფად იწყებენ დიაპაზონს იმ ჩატვირთვის მეთოდის გამოყენებით, რომელიც მე გამოვიყენე გამოუყენებელი გაფართოებისთვის. ასე რომ, თუ თქვენ არ გაინტერესებთ Web Worker sandbox– ში გაშვებული უსაფრთხოების სარგებელი, თქვენი კოდი ისარგებლებს? Load_plugin = URL არგუმენტით SheepTester– ის მოდემით.

შეგიძლიათ გააკეთოთ ქვიშის ყუთში გაფართოება ორივე ჩატვირთვის მეთოდთან თავსებადი შემდეგი კოდის გამოყენებით გაფართოების კლასის განსაზღვრის შემდეგ (შეცვალეთ CLASSNAME თქვენი გაფართოების კლასის სახელზე):

(ფუნქცია () {

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

გირჩევთ: