VBAアクションゲーム?Excelで動かそう!VBA−SoftPACELLMAN作成日記



 
Excelでパックマンを!パッセルマン作成日記

 since 2003/3/23 


 エクセルワークシート上でパックマンを再現しようとしています。完成時期は当「Excelで動かそう!」サイト開設1周年の2003年8月15日が目標、今後、試作品ダウンロードやコード閲覧ができるようにしたいと思っています。私が頭の中で考えていることもわかります、しばらくほったらかして何もしないであろうこともばれてしまいそうです(笑)。日記形式ですので私の備忘録も兼ねて、作品の進捗に関わらず思いついたこと、閃いたこと、疑問なども書いていきます。
 パックマンって、クリアーパターンがあるのですね。その通り動かせば、必ず面クリアーできる移動の仕方がある。そこまで再現できるかなあ。パッセルマン作成、この先、色んな局面で行き詰まることが目に見えています。丸見せ状態で一つの作品を作っていくと、ひょっとしたらどなたかが知恵を授けてくれるかも知れないと、期待を込めた日記形式のアップ実験です。
 なぜこんなことをするのか?それはExcelとパックマンが好きだから!
 ご意見、ご感想いただければと思います。のんびりゆっくりと、月1回の更新を目処に、やっていきます。


     
     Excelマップデータ(セルに値が入っている)      全てセルの背景色です

 

 

2003/03/16 Ver002 (4時間) 
メイン画面作成、キャラクターパターン作成、パッセルマンの初期移動処理

一番面倒なキャラクターパターンを用意できた。これで前に踏み出せる。移動処理は仮のモノ、残像(消し残り)が残ったりするので要見直し。
「PAC_CEL」で刺激を受けなければ、やはり着手しなかったと思う。武藤さんに感謝。


2003/03/21 Ver004完成 (4時間)
パッセルマンの移動処理VerUP、壁への衝突判定処理、モンスターの表示

 一気にゲームらしくなった。壁の判定は、あらかじめ用意したMAPデータ(MAPの色番号をセル値でもっている)をバリアント型変数に一括収納したものを参照している。この収納、予想通り異常に速い。満足。現在のパッセルマン移動方向前16ドットに壁があるかないかで判断させている。このルーチンはモンスターにもそのまま使えるはず。上手くいったのは、キャラクターの移動速度の反映。Speedバッファなるものを用いスピードに応じた一定の貯金ができたときに、移動処理を行うこととした。現在は仮に16段階で移動スピードを設定。これで、「あー追いつかれる〜」という動きが再現できた。キャラクターはいずれも、1ドット単位の画面書き換え。セル色の書き換えは、オフセットとリサイズを駆使して極限までシェイプアップしている。移動に関しては、速度反映も含め、思った以上の出来。まるでスプライト機能があるかのごとく滑らかに動いている。感動。1回のループで全てのキャラクターを書き換えるわけではないので、副産物として全体の処理速度が向上する(つまり全く無駄がない)Mainループとなった。
次はドットの消去判定かな?ココを先にやっとかないと面倒なことになりそう。ここでも一括収納配列が役立つ予感、移動毎に判定させても、変数内処理だからタイムロスは0か。ああ、考えるだけでも楽しいなあ。


2003/03/22 WAV音データ多重再生の問題に関しての考察
 Win32APIのPlaySound関数は軽くて使い勝手もよいのだが、多重再生ができない(同時に2種類以上のwavを再生できない)問題がある。いや、やってやれないことはないのだろうが、wavデータを生成するコードを書いてそれをVBA上で走らせる必要があり、そんなこと現実的には、VBAの速度面からも私の技術面からも、できない。ということはつまりPlaySound関数に頼っている限り、モンスターの移動音とパッセルマンのエサを食べる音を同時に鳴らせないという事態が発生することになる。かつてのCELLVADERの時は割り切って音の優先順位を付け、爆発>自機ミサイル>UFO出現>インベーダーの移動音という順番で下位のモノは切り捨ててしまった。結果、あのインベーダー特有の「デッデッデッデ」という侵略音は、じーっとしていればようやく聞こえるという何とも寂しいモノとなってしまった。
 ところが何とかなるものだ。bykinさんの新作ゲーム
「ClockPanic」では時計の音と効果音が同時になっているのだ。何でもDirctXのDirctSoundを使用するのだそうで、もちろんVBAからでも簡単に使えるとのこと。bykinさんからちゃっかりとサンプルコードを作ってもらって、あっという間に多重再生問題は解決。bykinさん、ありがとう!ということでPACELLMANは「要DirectX」を謳うこととなりそう。もちろん音が同時に鳴らない通常版も作るべきだろうけど。


2003/03/23 モンスターがエサドットを消してしまう問題に関しての考察
 ワークシートセルで表現している以上、モンスターがエサドットを消してしまうことは仕方ない。なぜなら移動描き変えを1回で済ませているため、前にいた部分を含めて(つまりキャラクターの大きさ+黒い1ライン)矩形セルを一括描き変えしているから。コレに関しては消してしまったあと改めて2×2のエサドットを描き直してやるしかないかと思っていた。でもこれだと1ステップ描写が増えるので速度低下は避けられない。エクセルワークシート上アクションゲームにおいて、判定や演算などの処理時間は微々たるモノで殆どはセル色描き変えに費やされるのね。
 ところがコレに関して良いアイディアが。元データを2種類用意してやればよいのだ。キャラクターの上下左右にエサを2×1ドット配置した別元データを用意すれば!。エサの上を通過したときは座標判定で「後ろにエサ有り」のデータを使って一括描き変え。ステップロスなく、「エサの上を通過」するモンスターを表現できる。閃いたのは、自分で作ったパッセルマンの動きを見ていたとき。作っていく中で思いつくことは多い、実践は大事だ。


2003/05/11 キャラクターの重なりの問題に関しての考察
 プライオリティどころかそもそもスプライト機能がないワークシートセル上で、これを解決する方法はあるのだろか。現在、モンスターが重なると重なった分も含めて描き変えがされるので重なっている部分がチラついてしまっている。力業でセルの背景色を描き変えている=要はドットを塗りつぶしているだけなので、オートシェイプのように上のモノは上に表示、これが出来ない。
 つらつらと考えてみる。重なっているか否かを移動の度に判断、重なっている部分を抜いて描き変えることは可能かどうか。パックマンのキャラクターの重なりは幸い縦or横のみだから、そんなに複雑なことをしないでも可能かも。いや、できる。重なっていない部分の座標を取得して、矩形サイズを算出、あとは例によってオフセット関数とリサイズ関数を駆使すれば、一つのステートメントで実現できるか。ちょっとやってみないとわからないが可能なような気がしてきた。これが上手くいって、あたかも優先順位があるスプライトのように滑らかに動き、かつ重なってくれたら・・・・私は嬉しさの余り失神してしまうかも知れない。


2003/07/06 WAV音データ多重再生の問題に関しての考察、その2
 VBAゲーム作成仲間の
エクセラさんから、メールをいただいた。CELLVADERを改造してみたとのこと。UFOの出現音とミサイル発射音が同時に鳴っていた・・・・なんと、DirectXを使わずにWAV音の同時再生が実現されていたのである。これには驚いた。不可能はないんだなあ。色々実験したくなる多重再生、このテクニック、今後使わせていただきます。
 また、パックマン作ってるけど敵の移動アルゴリズムで困っているとのこと。どうやってる?って。あのエクセラさんをもってしても、モンスターの動きは見抜けたかったようね。むふふ、そうでしょう、そうでしょうとも。多重再生テクを教えていただいたお礼?に行ってみましょう。私がいかにしてモンスターの敵アルゴリズムを解明したか。ちょっとイレギュラーでリアルタイムな日記ではないですが、振り返る感じでまとめてみました。


2003/07/06 モンスターの移動アルゴリズム考 苦悩編

エサドットの判定処理を考えようとしたが、どうしてもモンスターを動かしたくて仕方ない。次の移動方向だけ、指定すれば、そのまま移動書き換えできるようにコーディングしているのでまさに次に進む方向を決めるだけで、動き出すはず。うーーん動かしたい。とりあえず、直進型の赤を再現してみる。
 1 まずはモンスターの現在の状況を把握
   →進行反対方向以外の3方向は壁?それとも道?
   (反対方向へのUターンは通常移動時には起こらないので3方向のみの判定)
 2 一つのみ
    →直進にしろ、右左折にしろ、そちらに決定
 3 2つ以上(実はここまでの判定は全モンスターに共通であることに気付いた。)
    →分かれ道だ!
     仮に1歩進んだとして、パッセルマンとの直線距離が一番小さくなる道を選択
     具体的には、パッセルマンとモンスターの位置座標差xとyの2乗和で判定。 
うーむ。こうして書いてみると意外に簡単なようだが、ここまで考えを整理するのに1時間以上かかった。コーディングし動かしてみる。モンスターが動く!ちゃんとパッセルマンを追っかけてくる。これまた感動。

 ここで、モンスターの移動アルゴリズムについての整理。CELLVADER完成直後から、もう半年以上も調べ続けているのだが、なかなか結論が出ない。
1 4種のモンスターに異なる性格(おいかけ、まちぶせ、きまぐれ、おとぼけ)がある。
2 時間経過により、縄張り守りモードと追いかけモードに切り替わる。(この切り替え時にはUターンもあり得る)
3 追いかけモードの時はそれぞれの性格に基づきパックマンを追いかける。
  縄張りモードの時は、それぞれが受け持つパワーエサ近辺をウロウロする。
4 例外としていじけモード(パックマンがパワーエサを食べた特に発生)があり、通常と反対方向に移動、Uターンもあり。
 ここまでは間違いないと思われる。現在、縄張りモードと追いかけモードの切り替わりのタイミングがまったく不明。タイムテーブルさえあれば、対応できるようにコーディングしておこう。問題のモンスター性格だが、インターネットや書籍にもこれといった情報はなく、いや、あいまいには出ているのだが、具体的にピンポイントでコード化できるだけの記述が見つからない。一番参考になると思われたのがこちら↓
http://ps2dev.sytes.net/ps2linux/mlarchive/psgame-ml/msg00049.html
あとはプラス自分のプレイ感覚で再現して行くしかなさそう。

でもねえ、昔の、極限までサイズを切りつめたプログラムに、大規模なAIは組めないと思う。おそらく簡潔明快な判定ロジックがあるのだろう。その判定基準を見定めていくこと、再現はこれにかかっている。


2003/07/06 モンスターの移動アルゴリズム、解決編

 モンスターの移動アルゴリズムに関して、半ば諦めていたところに凄い文献を発見。公的に公開されている文書で、端的かつ具体的にモンスターの性格が記述されている判定ロジックそのもののようなテキスト。え、そんなのあるの?あったんです。見つけたときは思わず椅子から立ち上がってしまい印刷ボタンを押すその指先は不覚にも震えてしまったほど。なんとその正体は「パックマン訴訟事件、東京地裁の判決文(東京地裁昭和56年(ワ)第8371号損害賠償請求事件)」。以下原文を引用。

(二) 登場人物の説明
(1) モンスター
イ 常に服のすそをヒラヒラ動かし,進行方向に目を向け迷路上のエサの上を通過して移動し,パックマンの移動に対しそれぞれ左記の性格を有している。
@ オイカケアカベイ
 追跡中はパックマンを最短距離で追跡し休息中は画面右上付近を動き回る。
A マチブセピンキー
 追跡中はパックマンの目の向いている3つ先のマスに向い待伏せをし,休息中は画面左上付近を動き回る。
B キマグレアオスケ
 追跡中は@とパックマンを中心とする点対称のマスを目指し,休息中は画面右下付近を動き回る。
C オトボケグズタ
 追跡中はパックマンから半径約130ドットの外ては@の性格をもってパックマンを追跡し,右半径内ではパックマンの移動と無関係に動く。

思わず唸ってしまう見事なロジック、美し過ぎる・・・・。そして一気に解決。

 ひょっとしたら、全てのモンスター移動判定は配列の共通ルーチンでいけるのでは?守りモードの時は、パッセルマンの位置ではなく 守るべき座標との直線距離に変えるだけ。追いかけモードの時も同様、それぞれのモンスターの性格付けに応じて、対象座標を変えるだけか。たとえば、まちぶせなら、パックマン進行方向48ドット先を基準に、最短直線距離となるように、移動させればよい。おとぼけは直線距離が130ドット以上の場合はあかべえと同様、それ以外は乱数。きまぐれはずーと乱数。いじけモードの時は、通常判定後それぞれの反対方向へ。お、これでUターンも再現できる(勝手にUターンするはず)。出来た!・・・・頭の中で(笑)

 あれほど、再現どころがさっぱり実現方法がわからなかったモンスターの移動アルゴリズム・・・・守りモードと追いかけモードの切り替え時間、モンスターの移動速度変化がわかれば、ほぼ完璧に再現できる可能性が出てきた。視界良好、満足この上なし。コーディングも「おいかけ」のをいじるだけだから2,3時間?

後日談、早速コードに組み込んでみる。できた!4種のモンスターがそれぞれの性格に基づきパックマンを追いかけてくる!これで最大の難関、パックマン再現における大きな山を超えたようだ。同時に達成感のあまり作成意欲も著しく減退中・・・・。


2003/07/13 ブラウザ上で遊べるパックマン

「ブラウザ上でパックマンが遊べる」。javaやFlashに詳しい方なら当然のことかもしれないが、Excel上で動くゲームを作っている立場からすると不思議の一言。なぜ動く?セルもないのに、なんていうのは冗談としてもブラウザで遊べるのは魅力であり、そのお手軽さはエクセルにはない何よりのアドバンテージ。・・・・でも再現ハードルはExcel上の方が高そうな気がするのは、判官贔屓か。
 ということで、しばらくアルゴリズムの難しい話が続きましたから、ここらで一息、ご紹介させていただきます。
一休システム(無料Webゲームセンター)から左メニューの「パックマン」をクリック、なんとそのままブラウザ上で「フラッシュマン」が遊べます。気になる再現度は、なかなかのもの。当然のように滑らかに動くモンスター達。効果音やステージクリアーのデモもばっちり。・・・でも敵移動アルゴリズムは乱数のようです。


2003/08/04 モンスターがエサドットを消してしまう問題に関して、解決編

2003年8月15日動かそうサイト1周年に、エクセルで作ったパックマンをアップする、そんな目標を掲げて3月から実験的に始めたこの作成日記、現段階でアクセスがなんと2344、試作品ダウンロードもない、まともな画像1枚ない中、これは快挙といえるのではないでしょうか。ひょっとしたら世間の人々は、このパッセルマン完成を待ってくれているのではないか、そんな気がしてくるが、そんな気がするだけでそんなことはない。今回は画像アップです。臆病な私よ、さようなら。

で納期的には、もう追いつめられてますが、実は全然楽勝。妻と娘が実家に帰省している今の私には無限と思われる時間と、至福と言うべき環境があるのです。スーパー買い物カートの上ではなく、ダイニングテーブルの上にがっちりと2台のノートパソコンを置き、1台は常日頃すばらしい機動力を発揮してくれるメインマシン=ミニノート、もう1台は6年前の初代A4ノート、もうすぐ4歳の娘に悪戯されてしまうため普段は封印しているマウスもしっかり繋げ、メインの6.4インチミニ液晶ではなく、無線LANでファイル共有しているMMX166の初代A4ノート12インチの広大な液晶ディスプレイいっぱいにVBA画面を開き、横にはお気に入りの焼酎をロックで・・・・これで、開発が進まないはずがあろうか。

課題となっていた、掲題「モンスターがエサドットを消してしまう問題」に関して快調に解決したので、謹んでご報告いたします。

じゃーん!


ドットを食らって疾走するパッセルマン、その横で待機モード中のあかべえが進んでいますが、後ろのドットに注目。ねっ、消えてないでしょ。モンスターがドットの上をまるでスケートリンクを滑るかのように通過していくのがわかると思います。え、わからない?・・・わかって!

もちろん、モンスターは消えたドットの上は消えたまんま通り過ぎていきます。基本的には3/23に日記に書いた実現手法が奏功、その判定やドットの有無データの保持には、MAPデータ
>壁の判定は、あらかじめ用意したMAPデータ(MAPの色番号をセル値でもっている)を
>バリアント型変数に一括収納したものを参照している。
これを、そのまんま、使用しました。配列内での書き換えなので高速極まりない。タイムロス0。

ところが、ドットは2×2ドットなんですね。困った問題が。パッセルマンは1ドット(セル)単位で移動します。2ドットのうち1ドットだけ食べて、急に方向転換した場合、ドットエサが半分残った状態になってしまうのです。これはみっともない。

で、1ドット食べて急反転した場合、パッセルマンのお尻にエサドットをつけたグラフィックデータを使用して、パッセルマンを書き換える、この方法でクリアーできました。

次は、当たり判定かなあ。いや、その前にモンスターの状態も整理しておかねば。


2003/08/15 サイト1周年!いよいよ公開

思えば、ちょうど1年前、CELLVADER完成直後に決意したExcelでのパックマン再現。紆余曲折、試行錯誤を繰り返しながらも、なんとか公開にこぎ着けることができた。

決して完成とは言えない、オリジナルとは程遠い。でも、セルドットで表現したキャラクター達が、あのパックマンのアルゴリズムに則りワークシート上を滑らかに移動している。1年前には考えられなかったこと、これが実現できたことが、大きな喜び。

多くは語るまい、いや語れない。今はただ、完成までの軌跡を記しておくこととしよう。

'*********************************************************
' PACELL-MAN
' for Excel97,2000
' By N.Chikada
'Ver001 2003/03/16
'Ver004 2003/03/21
'Ver006 2003/03/22
'Ver008 モンスターの移動ルーチン反転対応 2H
'Ver009 モンスター移動時のドット非消去 1H
'Ver010 パッセルのドット消去判定、反転時1ドット欠問題対応 2H
'Ver011 モンスターの状態、出現、出動処理,ゲーム終了判定 2H
'Ver012  いじけモードのモンスター移動、反転可能処理 2H
'Ver013 全体の速度調整、モード切替パラメーター化、いじけ時減速 1H
'Ver014 目玉処理 2H
'Ver015 パワーエサ表示、食べたときのいじけ反応 1H
'Ver017 ワープトンネル作成、通過時モンスター速度半減 2H
'Ver018 経過時間処理(移動スピード、面ごとの加速、いじけの有無、モード切替 2H
'Ver019 反転処理見直し、強制反転、自動反転 2H
'Ver020 面ごとのモード変更時間、いじけ時の移動方向見直し 1H
'Ver020 当たり判定、食い点数表示 1H
'Ver021 モンスター食い時の目玉以外凍結処理 2H
'Ver024 パッセル消去処理、残機表示、ゲームオーバー判定 2H
'Ver025 面クリアー処理 1H
'Ver026 スコア高速表示、ハイスコア表示、表示有無OPTION 1H
'Ver027 文字列描画関数、Ready!の消去、GAMEOVERの表示 1H
'Ver028 効果音、同時再生、ループ再生 3H
'Ver029 OPENINGデモ,デモ1、デモ2、その他微調整 4H
'Ver030 恒常ループ化、 Wait導入、最適値設定 2H
'Ver031  そしてリリースへ。
'*********************************************************

 最後に、多くのWeb友人たちの助けと暖かい励ましがなければ、この作品はリリースできなかったこと、この場を借りて御礼申し上げます。ベンチ測定、バグ報告、応援、書き込み、本当にありがとうっ!!

 2003年8月15日「VBAアクションゲーム?Excelで動かそう!」は満1歳の誕生日を迎えました。

1周年記念!これが噂の「ExcelPacman」へ、
どうぞお越し下さい。


続く・・・?(笑)



VBAアクションゲーム?Excelで動かそう!VBA−SoftPACELLMAN作成日記