前回までのレーシングカーを走らせるプログラムでは、キーボード入力はGetKeyStateというWin32APIの関数を使っていました。今回はそこのコードを変え、DirectInputを活用したものに改良してみます。
DirectInputはキーボード、マウス、ジョイスティックなどのデバイスからの入力を、OSを介さずにハードウェアから直接行うための機能です。微々たるものですが、動作速度が速くなります。
このステップでは、CInputKeyboardクラスを利用してキーボード入力を行います。CInputKeyboardクラスの利用方法はとても簡単です。CInputKeyboardクラスを生成し、GetStateというメンバ関数を呼び出すだけでDirectInputを使ったキーボードからの入力判定を行うことができます。
前回の "driving" プロジェクトを改良する形で作業を進めます。
CInputKeyboardオブジェクトポインタを定義します。
#include "driving.idx"
Dim ScreenX=640 As Long 'ディスプレイの幅 (ピクセル単位)
Dim ScreenY=480 As Long 'ディスプレイの高さ(ピクセル単位)
' TODO: この位置にグローバル変数を定義してください。
Const MAX_SPEED = 25 '最高速(メートル/秒)
Const FPS = 60 'FPSの基準値
'FPSを計算するための変数
Dim dwNowFPS=FPS As DWord
Dim temp_FPS=FPS As DWord
Dim temp_Count As DWord
'自動車
Dim pModel As *CMeshModel 'メッシュモデル
Dim VectorPosition=[0,0,-5] As D3DVECTOR '位置
Dim direction_xz=D3DX_PI As Single 'XZ平面上の方向
Dim velocity As Single '速度
'エンジンノイズの音源
Dim pEngineNoise As *CAudio3D
Dim dwDefaultFrequency As DWord
'リスナー
Dim pListener As *CListener
Dim pLisModel As *CMeshModel
Dim ListenerPosition=[0,1,0] As D3DVECTOR '位置
'DirectInput用
Dim pInKey As *CInputKeyboard
CInputKeyboardオブジェクトを生成します。
Function InitProc()
'DirectXを初期化
If dx_Init(hMainWnd,ScreenX,ScreenY,FALSE)=0 Then
InitProc=0
Exit Function
End If
'マウスカーソルを非表示にする
ShowCursor(FALSE)
' TODO: この位置にアプリケーションの初期化コードを記述してください。
'ライト
dx_SetDefaultLight()
'------------------------
' メッシュモデルの初期化
'------------------------
'自動車
pModel=New CMeshModel("model.x")
'リスナー
pLisModel=New CMeshModel("listener.x")
'----------------------------
' リスナーの初期化
'----------------------------
'CListenerオブジェクトを生成
pListener=New CListener
'リスナーの位置を設定
pListener->SetPosition(ListenerPosition.x,ListenerPosition.y,ListenerPosition.z)
'----------------------------
' 音源(エンジン音)の初期化
'----------------------------
'CAudio3Dオブジェクトを生成
pEngineNoise=New CAudio3D
'セカンダリモードに設定
pEngineNoise->SetSecondary()
'読み込み
pEngineNoise->Load("EngineNoise.wav")
'デフォルト時の周波数を取得
pEngineNoise->GetFrequency(VarPtr(dwDefaultFrequency))
'最短距離、最長距離を設定
pEngineNoise->SetMinDistance(0)
pEngineNoise->SetMaxDistance(50) '50メートルの距離まで音が届く
'リピート回数を無限に設定
pEngineNoise->SetRepeats(DMUS_SEG_REPEAT_INFINITE)
'再生
pEngineNoise->Play()
'-----------------------------
' DirectInputの初期化
'-----------------------------
'キーボードデバイスオブジェクトを生成
pInKey=New CInputKeyboard
InitProc=1
End Function
CInputKeyboardオブジェクトを破棄します。
Sub QuitProc()
' TODO: この位置にアプリケーションの終了処理を記述してください。
'メッシュモデルを破棄
Delete pModel
'リスナーのメッシュモデルを破棄
Delete pLisModel
'エンジン音を停止し、破棄
pEngineNoise->Stop()
Delete pEngineNoise
'リスナーを破棄
Delete pListener
'キーボードデバイスオブジェクトを破棄
Delete pInKey
'DirectXの終了処理
dx_Quit()
End Sub
CInputKeyboard::GetState関数を呼び出し、KeyStateバイト配列に現在のキーボードの状況を取得します。あとは、KeyState配列の中身を調べるだけで、どのキーが押されているかを判定することができます。KeyState配列内の1バイトで表現されているキーの状況は、最上位ビットがオンであるかオフであるかで判断できます。
Sub InputActionProc() ' TODO: この位置に入力に関するコードを記述してください。 ' (キーボード、マウス、ジョイパッド、ジョイスティックなどによる入力) ' メモ - キャラクタの移動など、状況進行(アクション)を意味するコードを ' 記述することもできます。 Dim KeyState[255] As Byte pInKey->GetState(KeyState) 'ESCキーが押されたときは終了する If KeyState[DIK_ESCAPE] and &H80 Then PostQuitMessage(0) End If 'アクセル制御 If KeyState[DIK_UP] and &H80 Then '方向キー(上)が押されているとき velocity=velocity+0.1 If velocity>MAX_SPEED Then velocity=MAX_SPEED Else '方向キー(上)が離されているとき velocity=velocity-0.1 If velocity<0 Then velocity=0 End If If velocity>3 Then 'ハンドル操作(車が動いているときのみ) If KeyState[DIK_LEFT] and &H80 Then '方向キー(左) direction_xz=direction_xz-2/FPS If direction_xz<0 Then direction_xz=D3DX_PI*2+direction_xz ElseIf KeyState[DIK_RIGHT] and &H80 Then '方向キー(右) direction_xz=direction_xz+2/FPS If direction_xz>=D3DX_PI*2 Then direction_xz=0 End If End If '移動 VectorPosition.x=VectorPosition.x-Sin(direction_xz)*velocity/FPS VectorPosition.z=VectorPosition.z-Cos(direction_xz)*velocity/FPS '速度をもとに周波数を計算(エンジンの吹け上がりサウンドを再現) Dim dwPowerFrequency As DWord dwPowerFrequency=dwDefaultFrequency/4+dwDefaultFrequency*(3/4)*(velocity/MAX_SPEED) pEngineNoise->SetFrequency(dwPowerFrequency) 'エンジン音の音源情報を設定 pEngineNoise->SetPosition(VectorPosition.x,VectorPosition.y,VectorPosition.z) pEngineNoise->SetVelocity( -Sin(direction_xz)*velocity, 0, -Cos(direction_xz)*velocity) 'リスナー/音源のパフォーマンスを更新 pListener->CommitSettings() End Sub
講座インデックスへ戻る | ©2005 Discoversoft |