2015年8月15日 星期六

用Python擴充我的Scratch2 -- 原理與Hello World篇

話說6月中旬,才剛開始研究在Scratch2上如何使用Arduino,感謝許仁傑老師的文章與建議,讓我很快的能開始使用s2a_fm(當然也感謝原作者Alan Yorinks)。雖然在便利性方面,可能還是mblock較好。但是自己從s2a_fm中,卻學到「Scratch 2.0離線版擴充積木」的運作方式,也算是一個意外的收獲了。這篇文章其實是自己的學習整理,如果有人有興趣的話,歡迎一起討論。不過要有心理準備,就像s2a_fm的安裝一樣,比較麻煩,還要寫code,但是…好外掛,不開嗎?




在開始之前,再提一些事。本篇文章是原理與基礎練習,不含相關應用(有緣再寫?),我的測試環境是windows8.1,使用的程式為python3.4,python3的語法介紹不在此篇的範圍內,安裝與環境建置就要請想試的人自行找資料(我只會皮毛)。當然,如果你有慣用的程式語言(C++、Java、C#…),只要能達到同樣的功能,就不必非得用python不可。


一開始我為了想知道s2a_fm的運行方式(好奇寶寶?),找到了一份有關Scratch2擴充積木的說明文件,裡面有自訂新積木的方式,以及與外部程式通訊的方式(注意,此方法為Scratch Http Extension,只適合Scratch2離線版使用,見詳情)

大致上的原理,我畫了一張圖如下:

左邊的是Scratch2,右邊是helper程式。要幫Scratch2做擴充功能,要做兩件事。第一是在Scratch2中載入一個s2e的積木描述檔。第二是要有一個helper程式。Scratch2會以HTTP 協定的Get 方式(有寫過網頁互動程式,對Get Method應該很清楚),與 helper程式溝通,helper程式就會把新積木的功能執行或是把資料傳回Scratch2。( Scratch2與Scratch1.4,在擴充機制上,扮演的角色剛好相反,在Scratch2是Http用戶端,在Scratch1.4是伺服端)

這樣可能還是不清楚(因為有些細節沒提到),那實際來做做看吧。以下是一個base_helper.s2e的描述檔


注意描述檔雖然只是普通的文字檔,但是要用 UTF-8的格式儲存,描述檔是語法是JSON(一種用文字來表達物件的格式,請見JSON),extensionName是擴充積木的整體名稱,extensionPort是Http協定的Port號碼(可自訂,通常1024~65535)這個Port號碼到時要與helper程式一致,才能通訊。

接下來blogSpecs裡的是自訂的積木(可多組),這邊定義了一個積木,有三個參數,分別用雙引號包住,說明如下圖
第一個參數是積木種類,這個的" "(內有一個空格),代表的是命令積木(command),是由Scratch2向helper程式送出命令。(還有其他種類,請參考Scratch官方文件)

第二個參數是積木格式,也就是積木上看到的字

第三個參數在這裡是命令名稱,也就是實際送出給helper程式的命令名稱

s2e檔在Scratch2的匯入方式如下圖:



剛剛定義的新積木,在Scratch2中會在「更多積木」中出現

到這裡為止的步驟,有裝過s2a_fm的人應該不陌生,但是這次是要做自己的擴充積木哦!

接下來是用python寫的base_helper_py3.py 伺服程式 (從s2a_fm中精簡出來)

程式的功能是一個非常陽春的HTTP伺服器,只會處理Scratch送來的Get Request ,做出新積木的動作。撇開HTTP的細節不管,上面這個程式,可以簡要的只看35~45行的code,這一塊是處理Get Request的地方。裡面的39、40兩行,代表的是,如果送來的命令是hello (剛剛在 s2e描述檔中自訂的命令名稱),就會在終端機印出Hello World!

另外程式要注意的是第12行的PORT號碼,要跟s2e中是一樣的才行。

接下來就是實際執行helper程式了,請用python3以上來執行,執行的畫面如下

執行後,scratch2的新積木本來是紅燈的地方,已變成綠燈,表示已與helper伺服程式連上了

那就來把這個「第一個程式的名字是?」的積木按一按,看會發生什麼事呢?


到這邊,Scratch2擴充積木的Hello World 版算是完成了( Hello World常常是程式語言教學的第一個程式),不過還有一件事想搞清楚,按了自製積木後,scratch2到底送出什麼命令?很簡單,只要在helper伺服程式的第42行,加入

if cmd_list[0] != "poll" : print (self.path)

就可以了(程式只有一行,不要分兩行,注意要與39行的if保持同樣的縮排,這是python特有的語法,還有為什麼要排除poll,因為如果不排除,poll命令一秒送約30次,poll太多會看不到其他命令),運行的結果如下:

原來當我們按下新積木時,scratch2送出的命令是/hello,這個技巧很有用,可以用來觀察,在不同的積木定義下,scratch2送出的實際命令是什麼。

最後以下圖做一個概念的總結


這篇文章大致到這裡,礙於篇幅僅能介紹一種積木。這一篇完成的事看起來沒什麼,就是實做一個Hello World擴充程式,但是這也是s2a_fm如何寫出的基礎,別忘了,只要能掌握到helper伺服程式,就可以做許多的擴充功能,讓Scratch與不同的硬體 ,作業系統,甚至是與網際網路做各種有趣連結。






4 則留言:

  1. 請問這有辦法在mblock上實現嗎

    回覆刪除
    回覆
    1. mblock有自己的擴充,用javascript,但我沒研究

      刪除
  2. 張老師你好,我是一位小學四年級學生家長,想為小孩開拓電腦資訊視野,先前接觸Scratch與Arduino,苦腦沒有一個完美結合,在網上搜尋文章發現老師的文,但家中為Mac系統,不知老師是否也有相關文章或步驟可參考?

    回覆刪除
    回覆
    1. 抱歉沒看到這篇。我這篇的擴充是透過python,Mac是支援python的,所以理論上是可行的, 不過我沒有Mac,沒試過

      刪除