GO BACK

Squeak教室 上級編その3

「タートルグラフィック」



■タートルグラフィックとは?

 では、Smalltalkのプログラムの基本的な流れがわかったところで、具体的な機能を使ってみることにしましょう。まず、グラフィック関係から。Squeakでは、配置したモーフを動かして線を描いたりできましたね? あれ、実はSmalltalk本体にある「タートルグラフィック」という機能の応用なのです。

 タートルグラフィックっていうのは、Logo(ロゴ)って言語なんかで採用されて広まったものなのだけど、「亀さんが歩き回るみたいに描く」からこう呼びます。つまり「○○の地点から××の地点まで線を描いて」っていうんでなくて、「まっすぐいって、右に曲がって、またまっすぐいって」というように、進む距離と方向を指定していくことで一筆書きのように描かせるものです。座標を使ったものと違い、どんな図形が描かれていくのが直感的にわかり、教育的な目的などでは特に使いやすいものといえますね。

 では、このタートルグラフィックを使った簡単な例を作ってみましょう。前回、「MyTestClass」という実験用クラスを作ったので、これにクラスメソッドとしてサンプルを追加しましょう。

 ワールドメニューの「開く」から「package browser」を選んでパッケージブラウザを開きます。そして作成した「MyTestClass」を選択し、そのクラスメソッド(クラス一覧の「Class」ってボタンを選ぶ)から「calc message」というカテゴリを選んでください。すると、下のソースコードを表示するエリアにテンプレートとなるテキストが表示されるので、これを書き換えます。

guruguru: t1 haba: t2
| n p |
n _ 360 // t1.
p _ Pen new.
p roundNib: 3.
p color: Color red.
p down.
t1
timesRepeat: [p go: t2.
p turn: n].
p up


 さて、これでできあがりです。記入したテキスト部分でescキーを押してメニューを呼び出し、「了解」を選んでメソッドを作成しましょう。

 今回のものは、キーワードをもったメソッドです。ワークスペースを呼び出し、そこから「MyTestClass guruguru:6 haba:100」というように実行してみましょう。画面中央に、一辺100ドットの長さの正6角形が描かれますよ。


 実行してみると、画面にいきなり赤い六角形が現れてびっくりしたことと思います。これ、ウィンドウなどがあってもそのまま上に描かれてしまいます。そしてウィンドウをドラッグやリサイズすると、描いた図形が消えてしまったりウィンドウ部分だけ移動してしまったりします。要するに、ウィンドウとか描画用の領域とかそういうものが確保されててそこに描かれているんでなくて、いきなり画面そのものにグワッて描かれちゃってるんですね。

 さて、ここで使ったのは「Pen」というクラスです。これは、文字どおりタートルグラフィックのためのもので、このPenオブジェクトを作り、それに「まっすぐ行け、曲がれ」と命令してやれば、その通りに動くわけです。今回使ったメッセージ類を整理するとこんな感じになります。

new ——インスタンス(要するに、オブジェクトね)を作る。
roundNib: 整数 ——ペンの形状を円に、太さを整数にする。四角形のペン用にsquarNib:もある。
down ——ペンをおろす。以後、動かすと線を描く。あげるときは、up
go: 整数 ——整数ドットだけ前に進む。
turn: 整数 ——整数度だけ右に回る。マイナスにすると左に回る。
color: Colorオブジェクト ——ペンの色を設定する。色はColorオブジェクトを設定する。

 Penオブジェクトは、位置と向きの情報を持ったオブジェクトです。初期状態では、画面の中央に、0度(真上)を向いた状態で作成されます。で、それからgoとturnで位置や向きを動かして操作するわけです。

 ちょっとわかりにくいのは、Colorでしょう。これはColorクラスのインスタンス(オブジェクト)で設定します。ColorクラスにはあらかじめたくさんのColorオブジェクトが用意されていて、色の名前でそれらを呼び出せます。「red」「green」「blue」「black」「white」「cyan」「magenta」「yellow」といった感じです。この他、RGBをそれぞれ指定してColorオブジェクトを得ることもできます。これは、こんなメッセージを利用します。

変数Color r: 実数 g: 実数 b: 実数  (※実数は0〜1の間)

 それから、今回は「決まった回数だけ繰り返す」というものとして「timesRepeat:」というものを使っています。to: do:の場合は繰り返しの回数を変数で調べられますが、「そんな必要ない、単純に決まった回数だけ繰り返せばいい」というときもありますね? そういう場合に用いられます。これはシンプルなので使い方はすぐわかるでしょう。

整数 timesRepeat: [ 実行する文 ]

 もう1つ触れておきたいのは「引数を持ったメソッド」の書き方についてです。メソッドは、最初にメソッド名を書いて定義しましたが、今回の例を見ると最初の文はこうなっていますね?

guruguru: t1 haba: t2

 これは、「guruguru: 引数haba: 引数」というように、guruguru: haba:というセレクタに2つの引数がそれぞれ引き渡されたような形になってます。従って、メッセージは例えば「guruguru: 10 haba: 123」といった形になるわけです。引数を持ったメソッド、また複数のセレクタからなるメソッドはこのように定義をします。

 それから、ここでは引数を渡す変数名を「t1」「t2」としてありますが、これは特に意味はありません。別にどんな変数名でも大丈夫です。昔、Smalltalkではこのように「t1」「t2」「t3」・・といった名前に変換されちゃったんで、なんかそういう形で変数名つけちゃう癖があるのかも・・。


■モーフは操作できる?

 Squeakでは、モーフにもタートルグラフィックな機能が用意されたりしてましたね。では、モーフは操作できるんでしょうか。そもそも、モーフな部品って、Smalltalkではどういう扱いになってるんでしょう。それを知るために、ちょっとした実験をしてみます。

 まず、ワークスペースを開き、タイトルバー左側にあるメニュー表示のアイコンをプレスしてメニューを呼び出します。そして、「」を選んで下さい。



 これで、モーフをワークスペースにドロップすると、そのモーフを参照する名前が書き出されるようになります。試しに、楕円の部品を1つ作成し、それをワークスペースにドロップしてみましょう。「a楕円2787」といった名前が書き出されますよ。あ! これは環境や作ったオブジェクトによって番号とか違っているので、それぞれの環境でどんな名前になるか確認して下さい。



 では、この「a楕円2787」というやつに向かってメッセージを送れば、モーフを自由に動かしたりできるんだな、と思った人。あなたは鋭い! が、今一歩、詰めが甘い。確かにそうなんですが、例えばこの楕円に先ほどのようにタートルグラフィックのメッセージをを送っても、うまく動きません。なぜなら、この「a楕円2787」は、こうした操作のためのメソッドがないからです。じゃ、どうするのか?というと、「プレーヤー」というものに登場してもらうことになります。

 モーフというのは、画面に表示されている部品の他、「Squeak・トーイで操作する部品」としての性格も持ってないといけません(いや、なくてもいいけど、そうするとSqueak・トーイとして使えない)。パネルを使って部品を進めたり回転したりというのは、「Squeak・トーイで操作する機能」が用意してあって、それにタートルグラフィックな機能などが用意されているんですね。これが「プレーヤー」です。また、プレーヤーに設定されているモーフの部品は「コスチューム」という形で組み込まれます。

 コスチュームは、プレーヤーに設定されたモーフの部品で、プレーヤーはコスチュームの部品をのっけて、ワールドの中をえっちらおっちら動き回っている、って感じでしょうか。従って、表示などに関して操作したいときはコスチュームのオブジェクトにお願いすればいいですが、今回のタートルグラフィックみたいに、Squeak・トーイのパネルで使うような操作をさせる場合にはプレーヤーの方にメッセージを送らないといけません。

 では、実際にこの楕円を操作してみましょう。やっぱり、「MyTestClass」のクラスメソッドとして実装してみることにします。

moveStar: t1 size: t2 degree: t3 count: t4
| obj |
obj _ t1.
obj player setPenColor: Color red.
obj player setPenSize: 3.
obj player setPenDown: true.
t4 asInteger
timesRepeat: [obj player forward: t2.
obj player turn: t3].
obj player setPenDown: false


 できあがったら、ワークスペースから以下のように実行してみましょう。あ! 楕円の名前は、それぞれの環境に合わせて変更して下さいね。

MyTestClass moveStar:a楕円2787 size:100 degree:150 count:12

 ここでは、「moveStart: 動かすモーフ size: 一辺の長さ degree: 回転角度 count: 回数」という形で指定をします。すると、モーフが指定の通りに動き回り、図形を描いてくれます。


 実際にやってみるとわかりますが、ここで描いた図形は、さっきのPenオブジェクトによるタートルグラフィックと違い、ウィンドウの上に描かれたりはしません。一番下の、デスクトップの上に描かれます。また、描いた図形はウィンドウが重なったりしても消えません。単純にディスプレイに描画するPenと違い、モーフによる描画では「デスクトップに、部品類が重なったりしても消えたりしないグラフィックを描く」ような仕組みが用意されているのですね。同じタートルグラフィック仲間といえども、両者はだいぶ性質が違っていることがわかります。

 さて、ここで使った機能をざっと整理しておきましょう。基本的に、これらはプレーヤーのメソッドになります。

オブジェクト player ——オブジェクトのプレーヤー。プレーヤーのコスチュームは、costume。
オブジェクト setPenColor: Colorオブジェクト ——プレーヤーのペンの色を設定。
オブジェクト setPenSize: 整数 ——プレーヤーのペンサイズを設定。
オブジェクト setPenDown: 真義値 ——ペンが降りているか否か。
オブジェクト forward: 整数 ——ペンを整数ドット進める。
オブジェクト turn: 整数 ——ペンを英数度回転させる。

 これらで、プレーヤーを動かしてタートルなグラフィックを描かせることができます。先ほどのPenの描画と比べながら動かしてみると、両者の違いがよくわかりますよ。

 また、ここではペンを使いましたが、setPenDownしなければ、forwardとturnでモーフを単純に動かすこともできるわけです。とりあえず、これらでモーフ(プレーヤー)をいろいろと操作してみると、Smalltalkからのモーフの扱い方が少しずつわかってくるでしょう。


GO NEXT


GO HOME