2011年7月7日木曜日

ドリトルの壁反射をカスタマイズする方法

ドリトルの「ピンポンゲーム」は定番のネタ。教科書の「Activity 6」(34〜38ページ)にも載っている。

移動するタートルや図形の衝突したときに、入射角と反射角が等しいように反射させることで、この手のゲームは成立する。

教科書では、V2.2に対応して、例えばカメ太がタイマーで移動する場合、

カメ太:衝突=タートル:跳ね返る。

と定義する、と書いてある(36ページ)。カメ太の衝突のはずなのに、わざわざその親(プロトタイプ)を指定してメソッド定義する理由はなぜか、気になりませんか。

というわけで、「タートル:」を外して、継承されているはずの「跳ね返る」メソッドを直接実行するようにしてみる。ひとまず、カメ太と壁を描いて、カメ太を直進させてみる。まだ衝突は定義しない。
カメ太=タートル!作る ペンなし。
大工さん=タートル!作る 30 線の太さ (青)線の色。
大工さん!ペンなし 350 300 位置 ペンあり -90 向き 600 歩く 図形を作る。
大工さん!消える。
タイマー!作る 0.01 間隔 5 時間「カメ太!5 歩く」実行。

当然ながら、なにごともなかったかのようにすり抜けていく。

で、衝突の定義を追加。
カメ太=タートル!作る ペンなし。
大工さん=タートル!作る 30 線の太さ (青)線の色。
大工さん!ペンなし 350 300 位置 ペンあり -90 向き 600 歩く 図形を作る。
大工さん!消える。
カメ太:衝突=跳ね返る。
タイマー!作る 0.01 間隔 2 時間「カメ太!5 歩く」実行。
なんと、衝突が発生しない!そこで、メソッド定義に変えてみる。
カメ太=タートル!作る ペンなし。
大工さん=タートル!作る 30 線の太さ (青)線の色。
大工さん!ペンなし 350 300 位置 ペンあり -90 向き 600 歩く 図形を作る。
大工さん!消える。
カメ太:衝突=「!跳ね返る」。
タイマー!作る 0.01 間隔 2 時間「カメ太!5 歩く」実行。 

するとなんと素敵なことに、衝突した瞬間、「"_active"オブジェクトが作られていません("なら")」というエラーが発生する!

普通の人はここで戸惑って「ごめんなさい」と謝るところだけれど、こちらは「なぜタートルのメソッドでなければならないのか」を疑っているので、「これはしめた!」と思うところ。

「なら」というわけで、条件文に使われている変数名だろうとあたりをつけて、ローカル変数(というか引数)を指定してやる。ただし、衝突の引数は、衝突相手のオブジェクトなので、_activeは第二引数にして、以下のように書いてみる。
カメ太=タートル!作る ペンなし。
大工さん=タートル!作る 30 線の太さ (青)線の色。
大工さん!ペンなし 350 300 位置 ペンあり -90 向き 600 歩く 図形を作る。
大工さん!消える。
カメ太:衝突=「|相手 _active|!跳ね返る」。
タイマー!作る 0.01 間隔 2 時間「カメ太!5 歩く」実行。

ナイス!「"_hittarget"オブジェクトが作られていません("向き?")」というエラーメッセージ。名前からしてこれは衝突相手を意図したものということで、第一引数名をこれに変更。

見事に反射する。というわけで、この「_hittarget」と「_active」という、いかにも内部変数な名前が、「跳ね返る」メソッドの引数として使われていて、子ども側でそれに合わせてやらないと、未定義オブジェクトに対するメッセージ送信となってエラーが発生するということがわかる。

ちなみにdolittle.jarをunzipで展開してdolittle.iniファイルを眺めると、高麗大の青木さんががんばって改良した「タートル:跳ね返る」メソッド定義が、まさにこの2つの引数をとるように書かれているのがわかる。青木さんありがとう。

これで、ドリトルの「跳ね返る」メソッドを使いながらオリジナルの衝突メソッドを定義することができるようになった。

例えば壁に反射するときには、「カキン!」という効果音を入れたくなるもの。というか、動きを見ていれば、音が脳内で鳴り響く。そこで、効果音を追加してみる。
カメ太=タートル!作る ペンなし。
大工さん=タートル!作る 30 線の太さ (青)線の色。
大工さん!ペンなし 350 300 位置 ペンあり -90 向き 600 歩く 図形を作る。
大工さん!消える。
壁反射音=メロディ!作る『↑ど16↑ど16』追加
             (楽器!『ウッドブロック』作る)設定。
カメ太:衝突=「|_hittarget _active|!跳ね返る。壁反射音!演奏」。
タイマー!作る 0.01 間隔 2 時間「カメ太!5 歩く」実行。
成功するはず。お試しあれ。

で、効果音つきのスカッシュゲーム風に仕上げてみた。パドルの移動は、マウスカーソルの位置に合わせるようにしている。ご参考まで。

カメ太=タートル!作る ペンなし。

大工さん=タートル!作る ペンなし。
大工さん!30 線の太さ(青)線の色。
大工さん!-300 300 位置 0 向き ペンあり。

壁=大工さん!650 歩く 90 右回り 600 歩く 90 右回り 650 歩く 図形を作る。

パドル=大工さん!ペンなし -350 75 位置 ペンあり -90 向き
    25 線の太さ(ピンク)線の色 150 歩く 図形を作る。

大工さん!消える。

パドル:上下=「パドル!-350 ((マウス!縦の位置?) + 75) 位置」。

壁衝突音=メロディ!作る『↑ど16↑ど〜』追加(楽器!『ウッドブロック』作る)設定。
パドル音=メロディ!作る『↓ど16』追加(楽器!『ミュートギター』作る)設定。

カメ太:衝突=「|_hittarget _active|!跳ね返る。
       「(_hittarget == 壁)」!なら「壁衝突音!演奏」そうでなければ「パドル音!演奏」実行」。

速さ=5。

カメ太!((90!乱数) - 45)向き。

アウト音=メロディ!作る『↓↓↓み8み8』追加(楽器!『シンセベース1』作る)設定。

アウト=「アウト音!演奏。タイマー!作る 3 時間「」実行 待つ。
               カメ太!中心に戻る ((90!乱数) - 45) 向き」。

タイマー!作る 3 間隔 30 時間「速さ=(速さ)+ 1」実行。

タイマー!作る 0.01 間隔 30 時間
       「カメ太!(速さ) 歩く。パドル!上下。
       「(カメ太!横の位置?) < -400」!なら「ルート!アウト」実行。
       」実行。

なお、3秒ごとにカメ太の動きが速くなるようにしてみた。ゲーム時間は30秒で、そのまま終了するので、メッセージを出すなど改良していただけるとありがたい。