2003年はロボット法が制定され,アトムが生まれる年である。手塚治虫さんの『鉄腕アトム』にしても,スタンリー・キューブリック監督の『2001年宇宙の旅』にしても,過去に描かれた未来への夢に現実が追いついたためしはない。でも,スペースシャトル,ホンダのASIMO,ソニーのAIBOと夢の素はちゃんと生まれている。彼らの予想力が優れていたのか,それとも夢は実現するということなのか。いずれにして21世紀はロボットの世紀になりそうな気がする。
では,このMindStorms日記もLEGOマインドストームでロボットを作りプログラミングをして…と進めばよいのだが,そうは問屋がおろさず,こうしろうはFlash MXのスクリプト言語ActionScriptでプログラムを作る楽しさに魅せられているようだ。
プログラムを作成する場合,まず,そのプログラムの目的,目標を定め,構造,部品と仕様を決め,そして実際にプログラミングを行っていくわけだが,自分が良く知っている言語の場合は最初から必要な機能を全部書いていくことが多い。この方法はいかにも職業人という意味でのプロ的な仕事のやり方であるが,最初から考えつくされているので,作業中にドキドキやワクワクを感じることがあまりない。それに対し,経験のない言語の場合はインクリメンタルなプログラミングを行うことが多い。まず,基本的な流れを書いて,それに肉付けしていくように機能を拡張していく。
最初から全部の機能を書いていくと,コンパイルエラーやバグ潰しというマイナスイメージの作業に時間を取られることが多い(それはそれで,スッキリ解決した時の爽快感が大きいのだが)。インクリメンタルな手法では,シンプルな機能をまず作成しそれを少しずつ充実させていくので,エラーに悩まされることが少なく,小刻みに成功体験を味わえるので,プラス思考でプログラミングを行える。仕事として行うと効率面に難があるかもしれないが,学習には向いている。
前回でこうしろうは,インクリメンタルなプログラミングのサイクルにはまったようだ。そんなこうしろうを通して本年はプログラミングの面白さ『Fun to Program』をお伝えしていきたいと思います。どうぞよろしく。
Flashはアニメーションから進化したソフトウエアなので,プログラムの開発環境として捉えると独特なところがある。
フラッシュでアニメーションを作る時は,ステージと呼ばれる長方形の面にムービークリップ(イラストや画像)を配置していくのだが,ステージには深みというかレイヤー(層)がある。この時点で3次元だ。それにもましてFlashならではという概念がタイムライン,つまり時間軸である。タイムラインの中にフレームを配置し,その中でムービークリップが時間の流れに従い,変化していくのである。この時間軸を加えると,Flash MXは4次元の開発環境と言えるかもしれない。
12月31日 仕事や掃除も片付き,こうしろうがFlashで作成中のシューティングゲーム(らしきもの)について一緒に考えてみた。108話でスペース・キーを押すとペン先にようなロケットからミサイルが出るようになった。右・左矢印でロケットは移動する。ロケットの機能は整った。今度は撃つ対象を作らないといけない。
こうしろうは妙にかわいいUFOのムービークリップを作成し,ペン先ロケットとは別のレイヤーに配置した。それから,フレームを追加しActionScriptを記述した。
まずは,完成イメージからご覧下さい。
shot3.html
(表示にはMacromedia Flash Player6が必要です)
実行するとUFOがボタッ,ボタッと落ちてきたでしょ。実は最初に作ったプログラムでは,もっとたくさんUFOがボタッ,ボタッ,ボタッ,…と落ちてきていたのである。最初のコードはフレーム1から3に以下のように記述されていた。
[フレーム1]
hukasa = 1;
[フレーム2]
newName = "ufodrop"+hukasa;
_root.ufodrop.duplicateMovieClip(newName, hukasa);
hukasa++;
[フレーム3]
gotoAndPlay(_currentFrame - 1);
フレーム1で1を代入しているhukasaはUFOを出現させる深度(レイヤー位置)を指定する変数だ。フレーム2のhukasa++で加算している。_root.ufodrop.duplicateMovieClip(newName, hukasa);がUFOを出現させるコードである。ufodrop はこうしろうが作成した妙にかわいいUFOのムービークリップにつけた名前(インスタンス名)である。それを1つだけステージの端に配置してduplicateMovieClipメソッドで複製することでUFOを発生させているのである。各フレームは時間の流れに伴い順に実行されるので,フレーム3のgotoAndPlay(_currentFrame - 1);でフレーム2に戻り,次から次へとUFOを出現させることになる。
残念ながら,このコードではイナゴの大発生のようにUFOがステージを埋め尽くしてしまった。さあ,ここからが頭の使いどころである。どうすればイナゴの大発生を抑えられるか?ではなくて,射的の的として適切な数のUFOを出現させることができるか。
こうしろうは「カウンタ用の変数追加して,そいつの値をみてduplicateMovieClipを実行すればいいがや」と富山弁で考えた。
[フレーム1] counter = 0;
↓
[フレーム2] counter++;
if (counter == 5) { //counterが5だったら
duplicateMovieClip //UFOを出現させ,
counter = 0; //counterを0クリアする
}
↓
[フレーム3] gotoAndPlay(_currentFrame - 1); //フレーム2へ
彼の頭に浮かんだイメージは多分こんな感じだ。素朴な方法である。このやり方の利点は見た目のわかりやすさである。
私が考えた方法は,元々使っている変数hukasaを利用するやり方である。
[フレーム1] hukasa = 1;
↓
[フレーム2] if ((hukasa % 5) == 0) { //hukasaを5で割ったあまりが0だったら
duplicateMovieClip //UFOを出現させる
}
↓
[フレーム3] gotoAndPlay(_currentFrame - 1);
剰余(あまり)を求める演算子%でhukasaを5で割ったあまりを0と比較することで5で割り切れる数かを判断し,UFOを出現させている。これで5回に1回だけUFOを発生させることができる。こうしろう案と比べると,カウント専用の変数を使わなくても済む。『あたしンち』の母風に言うと「ケチと節約」である。プログラミングにおいて「ケチと節約」は重要なテーマなのである。
「しかし,どちらの方法もFlash的ではないなあ」と首をひねり,結局採用したのがコレ。
[フレーム1] hukasa = 1;
↓
[フレーム2] duplicateMovieClip //UFOを出現させる
↓
[フレーム3,4,5,6]
↓
[フレーム7] gotoAndPlay(_currentFrame - 5);
3,4,5,6とダミーのフレームを追加し,_currentFrame - 5でフレーム2に戻すようにした。フレーム7まで移動するのに時間が掛かるのでUFOの発生数が減る。
時間軸を意識しなくてはいけないから難しいと考えるよりも,UFOの数の加減をフレームの出し入れだけで「できて便利!」と前向きに考えて2003年MindStorms日記はスタートした。
…のですが,今回のFlashムービーでは,スペース・キーを押してもペン先型ロケットからミサイルは発射されない。ロケットがフォーカスを得られず,キーボード入力が伝わらないことが原因だと思われる。次回,こうしろうはこの問題を解決できるのかどうか。乞うご期待!