API (Application Program Interface) VB6 | |
キー入力 |
VisualBasic(VB)のKeyDown, KeyUp, KeyPressプロシージャはキーが押されときに呼び出される。ひとつのキー、例えば[A]キーを押し続けるとリピート機能が働き、連続して[A]が入力される。しかし、リピート機能が働いているときに別のキーを押すとリピート機能が中断する。また、キーを同時に2つ押しても早く押されたキーのデータしか得られない。
ゲームなどで、移動しながらミサイルを撃つとき、移動のキーを押したままで発射のキーも押したいが、VBでは発射のキーを押した時点で移動が止まってしまう。
API関数には、調べたいキーが押されているかどうかを判定する関数GetAsyncKeyStateが用意されている。ただし、関数なのでキーを押したかどうか調べたいところでこの関数を実行する必要がある。
Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
調べたいキーのコードを引数として呼び出すと、そのときに押されていれば0以外の値が返却される。
例えば、スペースキーが押されているか調べたいときは次のようにIf文を書く。
If GetAsyncKeyState(vbKeySpace) <> 0 Then
<<スペースキーが押されたときの処理>>
EndIf
「ゲームの作成」で制作した"UFO Shooting"に追加する
(1) 標準モジュールにAPI関数GetAsyncKeyStateの宣言を追加する。
APIビューアを使ってもよいし、キーボードから入力してもよい。ただし、英大文字・小文字は区別されるので注意して入力すること。
(2) キー入力の処理をForm_KeyDownプロシージャで行っていたが、API関数GetAsyncKeyStateで行うのでForm_KeyDownプロシージャを次のように4カ所変更する。
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)→ Private Sub KeyDown() Dim n As Integer Dim r As Long '自機の移動(←、→)If KeyCode = vbKeyLeft Then '移動(←)→ If GetAsyncKeyState(vbKeyLeft) <> 0 Then '移動(←) imgTaihou.Left = imgTaihou.Left - Abs(Dx) * 1.5ElseIf KeyCode = vbKeyRight Then '移動(→)→ ElseIf GetAsyncKeyState(vbKeyRight) <> 0 Then '移動(→) imgTaihou.Left = imgTaihou.Left + Abs(Dx) * 1.5 End If '自機が両端まで到達したとき → 自機を端に固定 If imgTaihou.Left <= 0 Then '左枠を越えた imgTaihou.Left = 0 ElseIf imgTaihou.Left + imgTaihou.Width >= Form1.ScaleWidth Then '右枠を越えた imgTaihou.Left = Form1.ScaleWidth - imgTaihou.Width End If '- - - - - - - - - - - - - - - '自機弾発射 スペースキーON and 自機弾 表示ON For n = 0 To MaxTama '自機弾数分調べるIf KeyCode = vbKeySpace And imgTama1(n).Visible = False Then→ If GetAsyncKeyState(vbKeySpace) <> 0 And imgTama1(n).Visible = False Then With imgTama1(n) '自機弾発射 .Left = imgTaihou.Left + imgTaihou.Width / 2 .Top = imgTaihou.Top .Visible = True '自機弾表示ON End With r = sndPlaySound("ir_end.wav", SND_ASYNC) Exit For '1発だけ発射してforを抜け出す End If Next n End Sub
(3) このままでは、サブプロシージャKeyDownはどこからも呼び出されないので、呼び出す命令をタイマーに追加する。
Private Sub Timer1_Timer() 'ゲームのメイン処理 Dim flag As Integer Dim n As Integer KeyDown 'キー入力処理 ←追加 Idou '自機弾移動処理 TekiIdou '敵移動処理 Tekidan '敵弾発射と敵弾移動処理 UFO 'UFO出現とUFO移動処理 AtariHantei '当たりの判定 Bakuha '爆破図表示 '- - - - - - - - - - - - - - - 'ゲームオーバー If TaihouNokori = -1 Then MsgBox "GAME OVER" Unload Me End If '- - - - - - - - - - - - - - - 'ゲームクリア flag = 0 '敵の残り確認 For n = 0 To MaxTeki If imgTeki(n).Visible = True Then '敵の残り有り flag = 1 Exit For End If Next n If flag = 0 Then 'Game Clear MsgBox "クリア!! 続けます!" InitGame '再スタート End If End Sub
実行すると、自機を移動しながら自機弾を発射することができる。
【問題点】サブプロシージャの呼出しが続くので処理が重たくなり、動作が遅く感じられる。
改善策 → サブプロシージャの呼出しをやめ、プロシージャの処理をタイマー(メイン処理)の中に入れてしまう。かなり長いプログラムになる。
各処理をタイマー(メイン処理)の中に入れると下のリストのようになる。
このとき、KeyDown(キー入力処理)、 Idou(自機弾移動処理)、 TekiIdou(敵移動処理)、 Tekidan(敵弾発射と敵弾移動処理)、 UFO(UFO出現とUFO移動処理)、
AtariHantei(当たりの判定)、 Bakuha(爆破図表示)のプロシージャは不要になるので削除する。
キー入力 | |
Copyright © 2002 Hiroshi Masuda |