VBAアクションゲーム?Excelで動かそう!>世留と仙人>第1編序章・第1章
第1編 アクションゲームの基本〜イベントリブン型プログラムからの脱却〜
序章
ExcelVBAの参考書をご覧になった方は多いと思います。初めに紹介されているVBAプログ
ラムはどんなモノだったでしょう。殆どはボタンを押すとメッセージが表示されるいわゆ
る「HelloWorld」タイプのプログラムではないでしょうか。VBAプログラムは通常イベン
トトリブン型とよばれる、ユーザーの操作に応じて何らかのアクションを返す形式を取り
ます。ボタンを押すとメッセージを表示する、はい・いいえの選択によって異なる結果を
返す、そういうプログラムが一般的ですし、また、業務に使用するソフトを作成するなら
その手法で事足ります。
一方、アクションゲームはどうでしょう?たとえばシューティングゲームを考えてみまし
ょう。確かにユーザーの操作に応じて何らかのアクションを返すところは一緒です。右キ
ーを押したときに自機を右に移動させれば良いのですから。ただ、アクションゲームはそ
れだけでは成立しません。ユーザーが何もしない間も、敵やミサイルを動かさなければな
りませんし、さらには、敵やミサイルを動かし続けつつ、ユーザーの操作を監視していな
ければなりません。しかもこれらを同時に行う必要があります。またパソコンの性能によ
って移動速度が変わらないよう、常に最適な速度で動かしつつユーザーの操作に備える、
そんなプログラムが不可欠です。
大変そう・・・と思われる方もいるかもしれませんね。ところが、そんなに大変ではない
ところにVBAのすごさがあります。VBAでアクションゲームを作るための基本法則・・・そ
れを明らかにすることが本編の目的です。世留君にお付き合いいただけたら、きっと、世
留君同様、簡単なアクションゲームが作れるようになっているはずです。
第1章 3箇条その1 キー入力判定
エクセル仙人と世留君はいつものように世間話中。
世留 仙人、Excelってアクションゲームが作れるんですね。
仙人 どうしたんじゃ、急に。
世留 「エクセルで動かそう!」というホームページを見てたら、エクセルで作ったアク
ションゲームが沢山あって。ほら見てくださいよ。エクセルでインベーダーまでで
きるんですよ。
仙人 ほほー、
(HPを見る)
あはは、これは面白いギャグじゃのう。
世留 ・・・・それは掲示板です。書き込み見て笑わないで下さい。気持ち悪い。
(マウスを奪い取り)
ここです。
仙人 (CELLVADERを試す)
うーん、なるほど。大した命令は使っておらんようじゃの。
世留 えっ?こんなに動いているのに。本当ですか。僕にも作れますかねえ?
仙人 ああ、作れるとも。ムズカシイ知識は必要ないじゃろう。自動記録を卒業したお前
さんなら大丈夫じゃよ。
世留 それじゃあ、パックマンでも作りましょうよ。早く早く!
仙人 待て待て、あわてん坊はお前さんの悪い癖じゃ。パックマンはymatsuさんのHPに
告知されている近田の新作じゃな。わしに相談来ないところ見ると、順調にいって
いるか、まったくさぼっておるかどちらか・・・
まあパックマンはお前さんにはちと荷が重そうじゃ。いくら作れると言っても、物
事には順序がある。まずは簡単なモノからスタートするのが良いじゃろう。頑張り
なさい。
世留 頑張りなさいって・・一緒に作ってくれるんじゃないんですか?
仙人 ほっほっほ。わしもそこまで暇ではない。まずはお前さんが自由に作って見なされ。
世留 (泣きそうになりながら)
作り方どころか何を作ったらいいかもわからないですよお。
仙人 作りたいモノがなくて作れるわけがなかろう。
まずは作りたいモノをイメージしなされ。そしてコードを思い浮かべるのじゃ。
少しでもコードが思い浮かぶようであれば、大丈夫。それはお前さんにも作れる。
世留 そんな・・・・難しいですよお。
仙人 ほっほっほ。何か出来たら持って来なされ。
世留 ・・・・・・・・・・・・。
数日後 朝早く世留君は仙人の家を訪問しました。
世留 仙人、仙人!つくりましたよ。
仙人 ほお。それはよかったのう。わしの言ったとおりじゃろう。おめでとうさん。それ
じゃあ、わしはもう一眠り・・・。
世留 寝ないで下さい、仙人。作ってはみたものの、駄目なんです。助けて下さい。
仙人 なんじゃ、完成したんじゃなかったのか。どれどれ、ファイルを開いて見なされ。
世留 (ファイルを開く)
仙人 ほー。これは何じゃね?単なるセルに数字を入力しただけに見えるが。
世留 (ムッとしながら)ゲームです!
仙人 どれどれボタン1を押してみよう。
お、数字が変化するのお。で、どこがゲームなんじゃ?
世留 だから助けて下さいって!数字が止まらないんですよ。
仙人 止めるコードを書かねば止まるわけがないじゃろ。コードは、と・・・・
Sub
strat()
Dim i As Integer
For i = 1 To 1000
Range("A1").Value = Int(Rnd * 10)
Next i
End Sub
仙人 ほー、お前さんにしては良くかけておるのお。ふむふむ、セルA1にランダムな0
〜9までの数字を入れなさいと、それを1000回繰り返しなさい、とな。
世留 ちゃかさないで下さい。何かのキーを押したら数字が止まるようにしたいんです。
そんで7だったら、大当たり!ねっ仙人、ゲームでしょ。でも、キーを押したら止
まるっていうのが出来ないんですよ。
仙人 なるほど。キー入力の判定が抜けておるのお。他にも沢山手直しする必要がありそ
うじゃ。
しかたない。おーい、ばあさん、お茶を入れてくれ。世留の分もな。
仙人 (お茶をすすりながら)
キーを押したら数字が止まる、それが7だったら大当たりと表示。それがお前さん
のやりたいことじゃな。
世留 そうです。まったく思いつかないんです。
仙人 まずは出鱈目でよいからコードを書いて見なされ。自分のやりたい処理をコード化
する、大事なことじゃ。
世留 出鱈目?そんなことで大丈夫かなあ。
(コードを書き始める)
できました。こんなイメージです
Sub strat()
Dim i As Integer
For i = 1 To 1000
Range("A1").Value = Int(Rnd * 10)
if
キーが押された then
If
Range("A1").Value = 7 Then
MsgBox "大当たり!"
Else: MsgBox "はずれ!"
End If
End If
Next i
End Sub
仙人 よしよし、よくできた。キーが押されたならセルA1の値により分岐させる。
「7」なら大当たり、その他ははずれ、と、こういうことじゃな。ここまで書けた
らできたも同然。あとはAPIを使うだけじゃ。
世留 API!?聞いたことはありますがそんなのいきなり無理です。やったことありま
せん。
仙人 ははは、とりあえずAPIという名前を知っておれば上出来じゃ。呪文の一種だと
思いなされ。最初にこうして
(ちょこちょことキータイプ)
Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long
Sub strat()
Dim i As Integer
・・・・・・・・・・・・・・・・
これで準備完了じゃ。キー入力が取得できるでのう。
世留 意味がわかりません。
仙人 ほっほっほ、そのうちわかるはずじゃ。今は コードの一番最初にこうすることで
お前さんのやりたいことができるようになったと考えなされ。
さて、お次は・・・どのキーを押したら止まるようにしたいのじゃね?
世留 一番押しやすいシフトキーを。
仙人 (ちょこちょことキータイプ)
For
i = 1 To 1000
Range("A1").Value
= Int(Rnd * 10)
’if
キーが押された then
If
GetAsyncKeyState(16) <> 0 Then
If
Range("A1").Value = 7 Then
MsgBox "大当たり!"
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
これでOKじゃ。動かして、シフトキーを押しなされ。
世留 (操作してみる)
ほんとだ!止まった。できた!仙人、もう少し詳しく教えて下さいよお。
仙人 コードとしてはお前さんの出鱈目コードに2行追加しただけじゃよ。
GetAsyncKeyStateはWin32APIといってのお、エクセルではなくWindowsが持って
いる関数じゃ。モジュールの冒頭に
Declare Function GetAsyncKeyState Lib "User32.dll"
(ByVal vKey As Long) As Long
と記述することによって、使えるようになるのじゃ。これを宣言という。
お前さんにわかりやすく説明すると
Declare
頼むから使わしてくれ
Function GetAsyncKeyState この関数を
Lib "User32.dll"
ここにあるから。
ってな感じかのう。
世留 ・・・・わかりやすいけど、
・・・それ、本当にあってますか?
仙人 ほっほっほ。少なくてもアクションゲームを作るだけなら、これで十分じゃ。まあ
それ以上知りたければ、参考書を読むのがいいじゃろう。宣言した後は宣言した関
数を自由に使えるのじゃよ。GetAsyncKeyState(キーを指定)関数というのはのお、
今指定したキーが押されているかどうか、その瞬間瞬間に判定してくれるんじゃ。
押されていなければ0、押されていればそれ以外が戻ってくる。判定したいキーは
キーコードで指定する。シフトキーのコードは「16」じゃからシフトキーが押さ
れているかどうかの判定はGetAsyncKeyState(16)とするのじゃ。
世留 わかりました。仙人っ、完成しましたね。次はパックマンに・・・
仙人 ほれ、またあわてん坊の悪い癖じゃ。はて、このゲーム、面白いかのう?
世留 (しばらく遊んでみて)
・・・・・面白くないです。あっ、しかも、動かなくなった。
仙人 そうじゃろう。残念ながらこれではアクションゲームといえんのじゃ。どこが面白く
ないのじゃ?
世留 そうですねえ。まず、「7」を狙えないこと。数字の変化が早すぎて見えない。途中
で終わっちゃうのも変ですね。for〜next文でループしているだけだから規定回数ルー
プし終わったら終わっちゃいますね。
仙人 よくわかっておるようじゃ。今いった2点はアクションゲームを作る上で非常に重要
でのう、キー入力判定を含めてアクションゲーム作成3箇条ともよばれておるぞ。
世留 3箇条!すごそうですね。誰がそう呼んでるのですか?
仙人 今のところ近田だけじゃ。
世留 なんか怪しいなあ。で、仙人、残りの2箇条は何ですか?
仙人 @がキー入力判定で、Aは恒常ループ、Bが同期wait処理の三箇条じゃよ。
世留 かっこいいですねえ。早く教えて下さい。
仙人 よしよし。3箇条いずれが欠けてもアクションゲームは作れない。特にB同期Wait処
理はグラフィックの書き換えが遅いエクセルではおろそかに出来ないテクニックじゃよ。
ミリ秒単位で正確に制御することがアクションゲームには必要じゃからのう。
世留 ミリ秒単位・・・・難しそうですが、とにかく僕にもわかるようにお願いします。
仙人 わかったわかった。その前に、お前さん、お昼でもいただくか。おーい、ばあさん。
世留君にも昼食用意してやってくれ。
※ゲームで使われるキーコード
カーソルキー ←:37 ↑:38 →:39 ↓:40
Shift:16 Space:32 Ctrl:17 Rtn:13 Esc:27 BS:8
アルファベット:No+64
テンキー:No+96
フルキー数字:No+48
ファンクションキー:No+111
※キー入力判定
Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long
’if
キーが押された then
If
GetAsyncKeyState(16) <> 0 Then
VBAアクションゲーム?Excelで動かそう!>世留と仙人>第1編序章・第1章