「タートルグラフィック」
では、Smalltalkのプログラムの基本的な流れがわかったところで、具体的な機能を使ってみることにしましょう。まず、グラフィック関係から。Squeakでは、配置したモーフを動かして線を描いたりできましたね? あれ、実はSmalltalk本体にある「タートルグラフィック」という機能の応用なのです。
タートルグラフィックっていうのは、Logo(ロゴ)って言語なんかで採用されて広まったものなのだけど、「亀さんが歩き回るみたいに描く」からこう呼びます。つまり「○○の地点から××の地点まで線を描いて」っていうんでなくて、「まっすぐいって、右に曲がって、またまっすぐいって」というように、進む距離と方向を指定していくことで一筆書きのように描かせるものです。座標を使ったものと違い、どんな図形が描かれていくのが直感的にわかり、教育的な目的などでは特に使いやすいものといえますね。
では、このタートルグラフィックを使った簡単な例を作ってみましょう。前回、「MyTestClass」という実験用クラスを作ったので、これにクラスメソッドとしてサンプルを追加しましょう。
ワールドメニューの「開く」から「package browser」を選んでパッケージブラウザを開きます。そして作成した「MyTestClass」を選択し、そのクラスメソッド(クラス一覧の「Class」ってボタンを選ぶ)から「calc
message」というカテゴリを選んでください。すると、下のソースコードを表示するエリアにテンプレートとなるテキストが表示されるので、これを書き換えます。
guruguru: t1 haba: t2 |
さて、これでできあがりです。記入したテキスト部分で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」・・といった名前に変換されちゃったんで、なんかそういう形で変数名つけちゃう癖があるのかも・・。
moveStar: t1 size: t2 degree: t3 count: t4 |
MyTestClass moveStar:a楕円2787 size:100 degree:150 count:12
実際にやってみるとわかりますが、ここで描いた図形は、さっきのPenオブジェクトによるタートルグラフィックと違い、ウィンドウの上に描かれたりはしません。一番下の、デスクトップの上に描かれます。また、描いた図形はウィンドウが重なったりしても消えません。単純にディスプレイに描画するPenと違い、モーフによる描画では「デスクトップに、部品類が重なったりしても消えたりしないグラフィックを描く」ような仕組みが用意されているのですね。同じタートルグラフィック仲間といえども、両者はだいぶ性質が違っていることがわかります。
さて、ここで使った機能をざっと整理しておきましょう。基本的に、これらはプレーヤーのメソッドになります。
オブジェクト player ——オブジェクトのプレーヤー。プレーヤーのコスチュームは、costume。
オブジェクト setPenColor: Colorオブジェクト ——プレーヤーのペンの色を設定。
オブジェクト setPenSize: 整数 ——プレーヤーのペンサイズを設定。
オブジェクト setPenDown: 真義値 ——ペンが降りているか否か。
オブジェクト forward: 整数 ——ペンを整数ドット進める。
オブジェクト turn: 整数 ——ペンを英数度回転させる。
これらで、プレーヤーを動かしてタートルなグラフィックを描かせることができます。先ほどのPenの描画と比べながら動かしてみると、両者の違いがよくわかりますよ。
また、ここではペンを使いましたが、setPenDownしなければ、forwardとturnでモーフを単純に動かすこともできるわけです。とりあえず、これらでモーフ(プレーヤー)をいろいろと操作してみると、Smalltalkからのモーフの扱い方が少しずつわかってくるでしょう。