ExcelVBAゲームプログラミング?

初心者でもきっとできる!
Excelさえ持っていれば特別なソフトは不要!
すぐにでも始められる簡単ゲームプログラミング!
今すぐ始めよう!

サンプルやゲームのダウンロードができる別館も好評運営中です。
ご意見やご質問、ゲームの感想等は掲示板までお気軽に。是非、皆さんの声を聞かせてください。運営、開発の励みになります。



各種ダウンロードはコチラ ↓ 意見・感想・質問はコチラ ↓
影倉庫 Shadow warehouse サポート掲示板
ブログの全体像はコチラ ↓ リンクのページはコチラ ↓
サイトマップ 自分本位なリンク


スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。






Chapter.36 [ 移動処理その3:キー入力判定API ]

■自由度の高い移動処理

前回はかなり内容が複雑でしたが、皆さん、無事にマスターできたでしょうか。

さて、移動処理の3回目となる今回は、『キー入力の判定』について解説したいと思います。

前回の講座で、キャラクターを移動させる方法を紹介しました。繰り返し処理を使って、キャラクターに見立てたイメージコントロールを、少しずつ動かして移動させましたね。まずは入門編という意味で、前回は直進するだけの移動を解説しました。

しかしゲームの種類にもよるんでしょうが、シューティングゲームやアクションゲームで考えた場合、大抵は主人公となるキャラクターが、プレイヤーの意思に応じて自由に動かせるようになっています。
前回のように、直進するだけの移動では、これがうまく実現できませんね。まっすぐにしか進めないルールのゲームならともかく、普通はプレイヤーが好きなようにキャラクターを操作できるようになっているはずです。

今回は、この『プレイヤーが自由に操作できるキャラクター』を実現するべく、『キー入力の判定』というテーマを掲げました。今回の講座の内容をしっかりと習得できれば、キーボードのカーソルキーを使って、自由に移動するキャラクターを作ることができます。これで作成できるゲームの幅が大きく広がりますので、是非、がんばって習得してほしいと思います。


■キー入力判定の種類

実は、VBAでキーの入力を判定する方法は、ざっと分けて2種類あります。

1つ目は、『キー入力イベントを使用する』という方法です。
VBAは非常にイベントと相性のいい言語です。……と言ってもよくわからないですよね。相性がいいってどういうこと? そもそもイベントってなによ? っていう感じだと思います。

実はじゃんけんゲームのところでも少し触れたのですが、イベントの概念を理解していることは、ゲームを作成する上で非常に重要です。この機会にしっかり覚えておいてください。

イベントというのは、パソコンを使用するユーザーの操作を言います。
例えば、『コマンドボタンを押す』というユーザーの操作は、パソコン側から見ると『コマンドボタンのクリックイベント』です。
同様に、『Excelのファイルを開く』というユーザーの操作は、パソコンから見れば『Excelファイルのオープンイベント』になります。
画面上でマウスが動いているだけだって、パソコンから見ると『マウスのムーブ(Move)イベント』なんです。少しイメージしにくいかもしれませんが、我々ユーザーがパソコンで何らかのを操作すると、必ず、何かしらの反応がありますよね。
キーを押したり、クリックしたり、そういった操作をすることで、必ず何かしらの成果があります。これは、パソコン側がユーザーの操作に対して反応してくれるおかげです。

パソコンは、このように、ユーザーの操作の全てを『イベント』として受け取ります。そして、それに応じた処理を行ってくれるのです。

VBAは、この『イベント』を用いてプログラミングがしやすい仕組みになっています。実際に今までも、コマンドボタンのクリックイベントを何度か講座内で使っていますよね。

キー入力判定の1つ目の方法は、このイベントを使ってキー入力判定を実装する方法です。細かい仕組みは今回解説しませんが、タイピングゲームや、単純なキー入力だけで作成できるパズルゲームやカードゲームなど、それほど激しい判定を必要としないゲームを作成する場合には、非常に役に立つ手法のひとつです。


さて、それに対して、キー入力判定のもうひとつの方法が、『APIを使ってキー入力を判定する』という方法です。

この方法は、先ほどのイベントでのキー入力判定に比べ、非常に細かく、激しい入力を必要とするゲームに向いています。シューティングやアクションを作成したいと考えた場合には、ほぼ必須のテクニックといってもいいでしょう。
APIを使用しているので、一見とっつきにくい印象を持ちますが、私の感覚では、イベントでのキー入力判定よりも簡単なような気がします。

今回は、この『APIを使ってキー入力を判定する』方法について、具体的に見ていきたいと思います。


■キー入力判定APIの仕組みを理解する

まずはキー入力判定に使用するAPIから紹介します。
そのAPIは『GetAsyncKeyState』という、少し名前の長いAPIです。

GetAsyncKeyState関数は、今現在キーが押されているかどうかを、リアルタイムに教えてくれる関数です。多少の予備知識が必要ですが、使い方は非常に簡単なので、この機会に覚えておくといいでしょう。

Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Long

宣言文はこのようになっています。

注目すべきは、括弧で囲まれている部分です。そこには『(ByVal vKey As Long)』と書かれていますね。そこに『~ As Long』とあることから、この関数が引数として整数型のデータを取ることがわかりますね。ここに、各種のキーを表すコードを入れて関数を呼び出すと、そのキーが今現在押されているのかどうか、結果を教えてくれます。
具体的に言うと、次の例で示すように、任意のキーを表すコードを渡してGetAsyncKeyState関数を呼び出します。すると、GetAsyncKeyState関数は何らかの数値を返してくるので、その結果を変数に確保します。
変数の中に入っている数値が、0(ゼロ)よりも小さい数値だった場合には、そのキーが押されているということになり、それ以外の場合には、キーが押されていないということになります。

※ここで登場する変数 L はLong型の変数です。

L = GetAsyncKeyState(調べたいキーのキーコード)

ここで変数 L の中身を調べるとキー入力の状態がわかる。
0よりも小さい数値の場合(L < 0なら)キーは押されている。
それ以外の場合にはキーは押されていない。

各キーがどのようなコードで表されるのかは、この講座の最後に、一覧表で用意してあります。使い方が理解できたら、活用してみてください。


それでは、実際にキャラクターを移動する処理に、このAPIを取り入れて考えてみましょう。

前回のコードを改造して、キーの入力を受け付けるようにしてみます。
変更するのは以下の点です。

①キーボードのカーソルキーごとに状態を調べる
②押されているキーがあるなら移動するようにする
③コードの終了を定義するためにひと手間加える

まずは①です。

キーボードのカーソルキーは、それぞれ次のようなキーコードで表されます。
 ←キー(左):37
 ↑キー(上):38
 →キー(右):39
 ↓キー(下):40

カーソルキーは、ご存知の通り4つの方向を持っています。ですから、4つのキーの状態をGetAsyncKeyState関数でそれぞれ調べます。GetAsyncKeyState関数の引数に、上のキーコード(37~40)を入れて呼び出せばいいのですね。

そして次は②の部分です。
先ほど調べたGetAsyncKeyState関数の結果から、もしキーが入力されている(押されている)と判断できた場合には、それぞれの方向に、TopプロパティやLeftプロパティを適宜設定し直して、表示される位置を変更します。

こうすることで、1回のループが行われるたびに、キーの状態に応じてキャラクターが動いているように見えるようになります。

しかし、重要なのが③のところです。
前回は、移動の仕方が真下方向への直進だけでしたね。ですから、ある特定の場所に来たときに、強制的に繰り返し処理を終了して、コードを止めました。
今回の場合は、キー入力の状態によって、どこにキャラクターが表示されているのかは不確定です。特定の場所に来たときに処理が終了するという現状のやり方は、コードを止めるための判断とはなりにくいですね。

そこで、ユーザーフォームが閉じられたときには、全てのコードが止まるようにしておきましょう。
こうしておけば、ユーザーフォームの『×』ボタンがクリックされると同時に、強制的に処理が止まるようになり、確実にコードを止めることができます。
これを実現するためには、ユーザーフォームの『QueryCloseイベント』を使います。


■QueryCloseイベント

QueryCloseイベントとは、『ユーザーフォームが閉じられる直前』に発生するイベントです。
ユーザーフォームの右上にある、『×』ボタンが押された瞬間に発生します。

このとき、コードを強制的に止めてしまえば、繰り返し処理が確実に停止するので安全です。
注意しなくてはならないのは、コードを記述する場所です。
QueryCloseイベントはユーザーフォームで発生するイベントなので、標準モジュールに記述してはいけません。絶対にフォームモジュールに記述してくださいね。具体的には、フォームモジュールに以下のコードを記述します。

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    End
End Sub

なんとあっけないコードなんでしょうか……。実際に必要なのは『End』というところだけです。これはEndステートメントと呼ばれており、『End Sub』や、『End If』などのときに使用するEndと同じものです。
Endと単体で記述した場合には、実行されている全てのコードが強制的に終了します。この機能を使って、繰り返し処理しているコードを強制的に止めます。

フォームモジュールに記述しなくてはならない、というルールさえ間違えなければ、大丈夫なはずです。簡単ですね。


さて、それでは実際に繰り返し処理を行う部分を見てみましょう。
GetAsyncKeyState関数を呼び出している部分と、それに応じてTopプロパティやLeftプロパティが変更されている部分。これがわかれば、あとはほとんど前回と変わりません。

Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMillsecounds As Long)
Declare Function GetTickCount Lib "kernel32.dll" () As Long
Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Long
'GetAsyncKeyStateのAPI宣言文を忘れずに追加しましょう

Sub Main()
    Dim Stm As Long
    Dim Left_Key As Long
    Dim Up_Key As Long
    Dim Right_Key As Long
    Dim Down_Key As Long '各キーの状態を確保する変数を宣言
    Do
        Stm = GetTickCount
        Left_Key = GetAsyncKeyState(37)
        Up_Key = GetAsyncKeyState(38)
        Right_Key = GetAsyncKeyState(39)
        Down_Key = GetAsyncKeyState(40) '各キーの状態を取得
        With UserForm1.Image1
            If Left_Key < 0 Then '左
                .Left = .Left - 1
            End If
            If Up_Key < 0 Then    '上
                .Top = .Top - 1
            End If
            If Right_Key < 0 Then '右
                .Left = .Left + 1
            End If
            If Down_Key < 0 Then '下
                .Top = .Top + 1
            End If
        End With
        DoEvents
        Do
            Call Sleep(1)
        Loop Until GetTickCount - Stm > 50
    Loop
End Sub

新しいAPIとしてGetAsyncKeyState関数が増えています。ちゃんとAPIの宣言文を記述していないとエラーがでますので、忘れずに宣言しておきましょう。

GetAsyncKeyState関数の宣言さえキチンとできていれば、あとはGetAsyncKeyState関数でキーの状態を調べて、If文で各方向ごとに条件分岐させるだけです。これでキャラクターの移動が、キー入力の状態によって変化するようになりました。

あとは前回と同じように、コマンドボタンからこのコードが実行されるようにしてあればOKです。
ユーザーフォームのQueryCloseイベントも、忘れずに準備しておきましょう。そうしておかないと、処理が止まりません、永遠に……。

恐いです。

さて、結構長くなってしまいましたね。
わかりづらい部分もあるかもしれませんが、ひとつひとつ、確実にこなしていってください。気をつけなくてはならない部分が多かったですが、内容としては単純なものがほとんどです。焦らずひとつひとつ設定していけば、前回のコードを流用して意外と簡単に実装できるはずですから、がんばってみてください。

これで、なんとなくシューティングゲームっぽい感じになりましたね。
キーの入力を判定できるといろいろなことができるようになります。ゲームの根本部分に関わるところなので、結構重要な部分です。マスターすればかなりの実力アップになりますよ。


■格言

キー入力判定には2種類の方法がある
GetAsyncKeyState関数の使い方を理解する


以下にキーコードの一覧を載せておきます。必要に応じて、調べてみてください。


キーの種類キーコードキーの種類キーコード
BackSpace
8
A
65
Tab
9
B
66
Enter
13
C
67
Shift
16
D
68
Ctrl
17
E
69
Alt
18
F
70
Pause
19
G
71
Esc
27
H
72
Space
31
I
73
PageUp
33
J
74
PageDown
34
K
75
End
35
L
76
Home
36
M
77
37
N
78
38
O
79
39
P
80
40
Q
81
Insert
45
R
82
Delete
46
S
83
*
106
T
84
+
107
U
85
-
109
V
86
.
110
W
87
/
111
X
88
0(キーボード)
48
Y
89
1(キーボード)
49
Z
90
2(キーボード)
50
F1
112
3(キーボード)
51
F2
113
4(キーボード)
52
F3
114
5(キーボード)
53
F4
115
6(キーボード)
54
F5
116
7(キーボード)
55
F6
117
8(キーボード)
56
F7
118
9(キーボード)
57
F8
119
0(テンキー)
96
F9
120
1(テンキー)
97
F10
121
2(テンキー)
98
F11
122
3(テンキー)
99
F12
123
4(テンキー)
100
NumLock
144
5(テンキー)
101
CapsLock
240
6(テンキー)
102
半/全
244
7(テンキー)
103


8(テンキー)
104


9(テンキー)
105



関連記事






Comment

Name
E-mail
URL
Comment
Pass  *
Secret? (管理者にだけ表示)

メールフォーム

影斬に物申すという方はこちら

名前 :
メール:
件名 :
本文 :

可能な限り要望には応えますが、必ず返信や回答ができることを、保障するものではありません。
ご了承ください。

Chapters

コンテンツ一覧


■Chapter 一覧■
    全てのChapterの一覧です。
    直接アクセスしたい方はこちらをご利用下さい。

    Chapter.1 [ 知っておくべき心得 ]
    Chapter.2 [ Excelってなんだろう ]
    Chapter.3 [ Excelの基本画面 ]
    Chapter.4 [ VBAとは? ]
    Chapter.5 [ モジュールについて ]
    Chapter.6 [ 変数 ]
    Chapter.7 [ 変数の型と宣言 ]
    Chapter.8 [ プロシージャとスコープ ]
    Chapter.9 [ ゲームつくる様々な手法 ]
    Chapter.10 [ ユーザーフォーム ]
    Chapter.11 [ プロパティウィンドウ ]
    Chapter.12 [ 乱数 ]
    Chapter.13 [ 条件分岐 ]
    Chapter.14 [ ゲーム画面のデザイン ]
    Chapter.15 [ コード記述の基本作法 ]
    Chapter.16 [ じゃんけんゲーム:1 名前をつける ]
    Chapter.17 [ じゃんけんゲーム:2 フォームの起動 ]
    Chapter.18 [ じゃんけんゲーム:3 乱数の種 ]
    Chapter.19 [ じゃんけんゲーム:4 イベント ]
    Chapter.20 [ じゃんけんゲーム:5 引数 ]
    Chapter.21 [ じゃんけんゲーム:6 役判定 ]
    Chapter.22 [ じゃんけんゲーム:7 予測と制限 ]
    Chapter.23 [ Withステートメント ]
    Chapter.24 [ 画像を表示させる ]
    Chapter.25 [ 画像表示の発展形 ]
    Chapter.26 [ 繰り返し処理 For文 ]
    Chapter.27 [ 繰り返し処理 Do~Loop文 ]
    Chapter.28 [ Exitステートメント ]
    Chapter.29 [ フォーム上の位置情報 ]
    Chapter.30 [ API基礎知識 ]
    Chapter.31 [ API補足知識 ]
    Chapter.32 [ メインループを考える ]
    Chapter.33 [ 同期処理の概念 ]
    Chapter.34 [ 移動処理その1:画面設定と考え方 ]
    Chapter.35 [ 移動処理その2:DoEvents ]
    Chapter.36 [ 移動処理その3:キー入力判定API ]
    Chapter.37 [ 条件分岐のさらなる探求 Select Case ]
    Chapter.38 [ アニメーション ]
    Chapter.39 [ 配列変数 ]
    Chapter.40 [ ゲームの初期化 ]
    Chapter.41 [ シューティングゲーム1:ゲーム設計 ]
    Chapter.42 [ シューティングゲーム2:メインプロセス ]
    Chapter.43 [ シューティングゲーム3:構造体 ]
    Chapter.44 [ シューティングゲーム4:定数 ]
    Chapter.45 [ シューティングゲーム5:プレイヤーキャラクター ]
    Chapter.46 [ シューティングゲーム6:ショットを撃つ① ]
    Chapter.47 [ シューティングゲーム7:ショットを撃つ② ]
    Chapter.48 [ シューティングゲーム8:Mod演算子の活用 ]
    Chapter.49 [ シューティングゲーム9:敵キャラクター登場 ]
    Chapter.50 [ シューティングゲーム10:衝突判定 ]
    Chapter.51 [ シューティングゲーム11:衝突の実体 ]
    Chapter.52 [ シューティングゲーム12:敵の攻撃 ]
    Chapter.53 [ シューティングゲーム13:爆発エフェクト ]
    Chapter.54 [ シューティングゲーム14:残機数表示① ]
    Chapter.55 [ シューティングゲーム15:残機数表示② ]
    Chapter.56 [ シューティングゲーム16:スコアの表示 ]
    Chapter.57 [ シューティングゲーム17:タイトル画面 ]
    Chapter.58 [ シューティングゲーム18:ボスキャラクター ]
    Chapter.59 [ シューティングゲーム19:最後の仕上げへ ]
    Chapter.60 [ シューティングゲーム20:いよいよ完成STG ]
    Chapter.61 [ カードゲームで使えるめくり効果 ]
    Chapter.62 [ ラジアンと角度 ]
    Chapter.63 [ ラジアンの活用:円運動 ]
    Chapter.64 [ ラジアンの活用:任意の角度へ移動する ]
    Chapter.65 [ APIによるサウンド再生:基礎 ]
    Chapter.66 [ APIによるサウンド再生:MIDIと多重再生 ]
    Chapter.67 [ APIによるサウンド再生:MCIコマンドとループ再生 ]
    Chapter.68 [ Function プロシージャ ]
    Chapter.69 [ 値渡しと参照渡し ]
    Chapter.70 [ デバッグ1:イミディエイトウィンドウ ]
    Chapter.71 [ デバッグ2:ローカルウィンドウ ]
    Chapter.72 [ デバッグ3:コード実行の中断 ]
    Chapter.73 [ オブジェクトってなんだ ]
    Chapter.74 [ プロパティ・メソッド・イベント ]
    Chapter.75 [ オブジェクト変数 ]
    Chapter.76 [ オブジェクトとコレクション ]
    Chapter.77 [ 特殊な繰り返し:For Each ]
    Chapter.78 [ エラー処理 ]
    Chapter.79 [ On Error と GoTo文 ]
    Chapter.80 [ Resumeステートメント ]
    Chapter.81 [ バイトとビット ]
    Chapter.82 [ ウィンドウメッセージとイベント ]
    Chapter.83 [ 文字列の基礎 ]
    Chapter.84 [ 文字列操作① ]
    Chapter.85 [ 文字列操作② ]
    Chapter.86 [ タイピングゲーム1:仕様を決める ]
    Chapter.87 [ タイピングゲーム2:キー入力検知 ]
    Chapter.88 [ タイピングゲーム3:文字列照合 ]
    Chapter.89 [ タイピングゲーム4:判定関数 ]
    Chapter.90 [ タイピングゲーム5:ゲーム画面設計 ]
    Chapter.91 [ タイピングゲーム6:問題文のソート ]
    Chapter.92 [ タイピングゲーム7:動的配列 ]
    Chapter.93 [ タイピングゲーム8:キーダウンイベント ]
    Chapter.94 [ タイピングゲーム9:正打数の表示 ]
    Chapter.95 [ タイピングゲーム10:タイムの表示 ]
    Chapter.96 [ クリックゲーム1:イベントの種類 ]
    Chapter.97 [ クリックゲーム2:画面設計 ]
    Chapter.98 [ クリックゲーム3:クリック座標検知 ]
    Chapter.99 [ クリックゲーム4:キャラクター準備 ]
    Chapter.100 [ クリックゲーム5:キャラクターの配置 ]
    Chapter.101 [ クリックゲーム6:キャラクター移動とNot演算子 ]
    Chapter.102 [ クリックゲーム7:クリックのヒット判定 ]
    Chapter.103 [ クリックゲーム8:ヒットマークエフェクト ]
    Chapter.104 [ クリックゲーム9:サウンド処理の実装 ]
    Chapter.105 [ クリックゲーム10:マウスカーソルの変更 ]
    Chapter.106 [ ブロック崩しゲーム1:仕様と概要を決める ]
    Chapter.107 [ ブロック崩しゲーム2:基本概念の確認 ]
    Chapter.108 [ ブロック崩しゲーム3:ベクトルとは ]
    Chapter.109 [ ブロック崩しゲーム4:変数や定数の宣言 ]
    Chapter.110 [ ブロック崩しゲーム5:初期化処理の実装 ]
    Chapter.111 [ ブロック崩しゲーム6:ブロックの配置 ]
    Chapter.112 [ ブロック崩しゲーム7:根幹処理とバーの処理 ]
    Chapter.113 [ ブロック崩しゲーム8:線分と線分の交差を判定 ]
    Chapter.114 [ ブロック崩しゲーム9:線分同士の交点 ]
    Chapter.115 [ ブロック崩しゲーム10:ボールの処理 ]
    Chapter.116 [ ブロック崩しゲーム11:最終調整して完成へ ]
    Chapter.117 [ テキストファイル操作基礎 ]
    Chapter.118 [ テキストファイル操作:読み込み編 ]
    Chapter.119 [ テキストファイル操作:CSV読み込み編 ]
    Chapter.120 [ テキストファイル操作:様々な読込編 ]
    Chapter.121 [ テキストファイル操作:バイナリ編 ]
    Chapter.122 [ テキストファイル操作:暗号化編 ]
    Chapter.123 [ テキストファイル操作:復号化編 ]
    Chapter.124 [ クラスモジュールとは ]
    Chapter.125 [ クラスモジュール:メソッド編 ]
    Chapter.126 [ クラスモジュール:プロパティ編 ]
    Chapter.127 [ クラスモジュール:イベント拡張編 ]
    Chapter.128 [ クラスモジュール:イベント自作編 ]
    Chapter.129 [ APIによる描画処理1:ハンドル ]
    Chapter.130 [ APIによる描画処理2:デバイスコンテキスト ]
    Chapter.131 [ APIによる描画処理3:ペン オブジェクト ]
    Chapter.132 [ APIによる描画処理4:ブラシ オブジェクト ]
    Chapter.133 [ APIによる描画処理5:図形描画準備編 ]
    Chapter.134 [ APIによる描画処理6:図形描画実践編 ]
    Chapter.135 [ APIによる描画処理7:画像描画の仕組み編 ]
    Chapter.136 [ APIによる描画処理8:ビットブロック転送編 ]
    Chapter.137 [ APIによる描画処理9:ラスタオペレーション ]
    Chapter.138 [ APIによる描画処理10:マスク描画 概念編 ]
    Chapter.139 [ APIによる描画処理11:マスク描画 実践編 ]


    コードやVBAに関する質問などはサポート掲示板(別館)までお気軽にどうぞ。




fc2 seotool Excel VBA ゲーム プログラミング 講座

Counter

twitter


Shadow BBS - 影掲示板

VBA 関連書籍



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。