Help us understand the problem. What is going on with this article?

SmalltalkからScratchをいじる(3) スプライトの位置を表示する

More than 3 years have passed since last update.

プログラムが期待した通りに動かないときに、内部状態を見たいことがあります。
今回はその一例としてプログラム実行中のスプライトの位置を表示するようにScratchを改造します。(Smalltalkを使えるようにする方法やハロの出し方等はこちらを参照)

※今回はScratchのコードをいじります。必ずバックアップをとっておきましょう。(バックアップ手順はこちら

やりたいこと

以下のスクリプトがあるとします。(ここからダウンロードできます。)
0_script.png

旗をクリックして実行した時のスプライトの位置を文字情報として、逐次表示するようにします。
result.png
※残念ながらスプライト名が日本語の場合は文字化けしてしまいます

手順

  1. スプライトを動かす方の「旗がクリックされたとき」のブロックにハロを表示します。ハロの下側に"EventHat"と表示されます。レンチのアイコンをクリックして「inspect morph」でインスペクタを開きます。
    halo.png

  2. 画面上部左側の枠を少しスクロールさせて、"scratchProc"をクリックします。scratchProcの中身を表示したまま、旗をクリックしてScratchを動かしたり、止めたりしてください。このブロックが実行中の場合は"a Scratch Process"と、止まっている場合は"nil"と表示されます。
    inspector.png
    このオブジェクトはScratchのブロックの実行を管理するためのオブジェクトです。

  3. ブロックが実行されている時に"scratchProc"のところでメニューを表示(Windowsの場合は右クリック、macの場合はoption+クリック)し、"browse full"を選択します。(Alt/Command + b でも可)
    menu.png

  4. 緑のウィンドウが開きます。これはシステムブラウザ(またはクラスブラウザ)と呼ばれ、ScratchやScratchを動かしているSmalltalk自体のコードを閲覧、変更することができます。
    browser.png

  5. ウィンドウ上部の右から2番目の枠から"entry point"をクリックし、その後、一番右の枠から"runStepFor:"をクリックします。

  6. ウィンドウ下部に"runStepFor:"メソッドのコードが表示されます。3行目(| t2 |と書かれている下)にself halt.という行を挿入します。(最後のドットを忘れずに)
    browser2.png
    self halt.は実行を一時停止させるための命令です。

  7. コードの変更が終わったら、変更を反映させるために、メニューを表示させて、"accept"をクリックします。(Alt/Command + s でも可)
    accept.png

  8. 初めてacceptを実行した場合、変更した人の名前(イニシャル)を聞かれます。Smalltalkはコードを変更した場合、だれがいつ、どのような変更をしたのか記録されます。あなたのイニシャルを入力して、Acceptをクリックしてください。
    name.png

  9. Scratchが実行状態になると、下記の赤いウィンドウが表示されます。先ほど挿入したself haltが実行されると、このウィンドウが表示されます。
    halt.png
    この時Scratchの世界は停止しています。Scratchのウィンドウを見ると、スプライトはマウスカーソルを追いかけず停止したままになっています。

  10. ウィンドウ上部の一番右の"Debug"をクリックしてください。別のウィンドウが表示されます。このウィンドウをデバッガ(Debugger)といいます。画面上部の上から3番目の"ScratchProcess>>runStepFor:"をクリックしてください。
    debugger.png
    先ほど編集した"runStepFor:"のコードが表示され、haltのところがハイライトされています。haltのところで止まっていることを表します。

  11. インスペクタからコードを実行できたように、デバッガからもコードを実行できます。先ほどのself haltを削除して、topBlock addHalo: nilと入力してください。入力した文字だけを選択し、"do it"(Alt/Command + d)をしてみてください。
    doit.png
    ScratchProcessオブジェクトが持っているtopBlockは最初に処理されるブロックを表します。「旗がクリックされたとき」のブロックにハロが表示されます。

  12. 今度はデバッガ上で、topBlock scriptOwner xposと入力してください。入力した文字だけを選択し、"print it"(Alt/Command + p)をしてみてください。
    printit.png
    topBlock scriptOwnerでスプライトを取得し、そのx座標を表示しました。

  13. 次にスプライトの位置情報を表示するためのウィンドウを起動します。文字表示用のウィンドウをトランスクリプト(Transcript)と呼びます。デバッガはそのままにして、背景をクリックしてメニューを開き、"open"→"transcript"でトランスクリプトが表示されます。
    transcript.png

  14. トランスクリプトを表示したまま、またデバッガに戻り、最初にself haltを入力した場所に、下記のコードを入力してください。(これまでprint it やdo itしたコードは消してください。)

    Debuggerの中で実行.st
    Transcript show: Time now;
      show: topBlock scriptOwner objName;
      show: ' x='; show: topBlock scriptOwner xpos;
      show: ' y='; show: topBlock scriptOwner ypos;
      cr.
    
  15. 入力した文字を選択して、"do it"すると、トランスクリプトに時刻、スプライトの名前、座標が表示されます。
    transcript2.png
    ※スクリプト名が日本語の場合は文字化けしてしまいます。

  16. 無事に動きそうなら、Alt/Command + sを押して、コードの変更を反映します。

  17. 反映すると画面上部の枠の一番上が"ScratchProcess>>runStepFor:"になっています。そのあたりでメニューを表示(windowsなら右クリック、macはopt+クリック)して、"restart"を選択すると変更後のコードで再実行されます。
    restart.png

  18. self haltを消したので、デバッガはもう起動しなくなります。かわりにトランスクリプトに情報が表示されるようになります。
    (早すぎて分かりにくい場合はScratchのメニューから編集→ステップ実行を設定→ブロックを点滅させる(遅く)でゆっくりにできます)

元に戻す

元に戻す場合はクラスブラウザから先の挿入したコードを削除してもよいですが、オブジェクトの状態がおかしなことになっている可能性もあることに注意してください。デバッガで止めたり、コードを変更したり、インスペクタからオブジェクトにメッセージを送ったりしていると、コードは元と同じでもオブジェクトが本来あるべき状態になっておらず、通常のScratchと異なる動作をする可能性があります。
また、Smalltalkが持っているバージョン管理システムを使う方法もあるのですが、配布されているScratchはコードがついていないためこの機能は使えません。また、バージョン管理しているのはコードだけで、オブジェクトの状態を戻すことはできません。

解説

これまで様々なオブジェクトをインスペクタで見てきました。見ているオブジェクトの種類によってインスペクタのタイトルは異なっています。例えば、スプライトをインスペクタで開いたら、タイトルはScratchSpriteMorphとなり, ステージならScratchStageMorph、処理の実行を表すオブジェクトならScratchProcessとなります。
このタイトルに表示されているのはクラスと呼ばれるものを表します。オブジェクトがメッセージを受け取った時、どのように振る舞うかはクラスによって決まります。
システムブラウザはクラスの閲覧/編集のためのツールです。クラスを見て、どのようなメッセージを受け取れるか、どのように処理を行っているのか、を知ることができます。デバッガで処理を止めながら動作を確認/修正することもできます。

補足

普通に配布されているScratchはコードが付属していません。今回システムブラウザで見たコードは逆コンパイルされて生成されたものです。コンパイルとはコードを実行可能な形式に変換すること、逆コンパイルは実行可能な形式からコードを復元することをいいます。コードにはコードコメントや変数名など理解の手助けとなる情報がありますが、コンパイルすると失われます。そのため、逆コンパイルで生成したコードはそれらが失われたコードになります。
ソースコードつきイメージはこちらからダウンロード可能です。
http://wiki.scratch.mit.edu/wiki/Scratch_1.4_Source_Code

そもそもScratchを動かしているSmalltalkは非常に古いバージョン(少なくとも10年以上前のバージョン)のため、使いにくい部分もあります。コードの理解をしたい場合などは最新のSmalltalk上で動作するPhratchを検討するのもよいかもしれません。
http://qiita.com/search?utf8=%E2%9C%93&sort=rel&q=phratch

maeda_
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした