今回が初の実践的なDirectXプログラムになりそうです。カーソルキーからの入力をもとに、3D空間の中をレーシングカーが走るプログラムを作ってみます。
DirectX対応アプリケーションのプロジェクトを新規作成します。プロジェクト名は "driving" などとしておきます。別途、"model.x" という自動車の形を定義するXファイルが必要になりますので、プロジェクトのディレクトリに保存しておいてください。
→model.xをダウンロード
FPSを計算する際に必要な変数、及び自動車のメッシュオブジェクト・運動制御のための変数を定義します。MAX_SPEEDの値を変えることで、最高速度を設定することができます。
#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 '速度
ライトの設定及び自動車のメッシュオブジェクトの生成を行います。
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")
InitProc=1
End Function
pModelオブジェクトを破棄します。
Sub QuitProc()
' TODO: この位置にアプリケーションの終了処理を記述してください。
'メッシュモデルを破棄
Delete pModel
'DirectXの終了処理
dx_Quit()
End Sub
GetKeyState関数を使ってカーソルキーからの入力を処理します。「↑」キーが押されたときはアクセルオンの状態にし、自動車を加速させます。加速は、速度を管理するvelocity変数の値を増加させることで再現します。「←」または「→」キーが押された時はX座標とZ座標の角度を管理するdirection_xz変数の値を変化させ、進行方向を変更し、ハンドル操作を再現します。また、ハンドル操作はある一定以上の車速が出ているときにのみ有効なところも注目すべき点です。こうすることで、自然なハンドル操作を演出できるようになります。
最終的にはVectorPositionの値を変更し、自動車の位置を移動させます。
Sub InputActionProc()
' TODO: この位置に入力に関するコードを記述してください。
' (キーボード、マウス、ジョイパッド、ジョイスティックなどによる入力)
' メモ - キャラクタの移動など、状況進行(アクション)を意味するコードを
' 記述することもできます。
'ESCキーが押されたときは終了する
If GetKeyState(VK_ESCAPE) and &H8000 Then
PostQuitMessage(0)
End If
'アクセル制御
If GetKeyState(VK_UP) and &H8000 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 GetKeyState(VK_LEFT) and &H8000 Then
'方向キー(左)
direction_xz=direction_xz-2/FPS
If direction_xz<0 Then direction_xz=D3DX_PI*2+direction_xz
ElseIf GetKeyState(VK_RIGHT) and &H8000 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
End Sub
pModelオブジェクトの描画、カメラ・視野の設定を行います。カメラは原点よりも手前上に位置付け、原点に方向を向かせます。
FPSを計算し、車速情報と共に画面にテキストを描画します。
Sub RenderProc()
' TODO: この位置に描画に関するコードを記述してください。
'自動車を描画
Dim VectorDirection=[0,0,0] As D3DVECTOR
VectorDirection.y=direction_xz
pModel->Draw(VarPtr(VectorPosition),VarPtr(VectorDirection))
'カメラを設定
Dim VectorEye=[0,5,-10] As D3DVECTOR
Dim VectorAt=[0,0,0] As D3DVECTOR
Dim VectorUp=[0,1,0] As D3DVECTOR
dx_SetCamera(VarPtr(VectorEye),VarPtr(VectorAt),VarPtr(VectorUp))
'視野を設定
dx_SetProjection(60*D3DX_PI/180,
1,
0.01,
2000.0)
'FPSを計算
temp_FPS=temp_FPS+1
If GetTickCount()-temp_Count>1000 Then
temp_Count=GetTickCount()
dwFPS=temp_FPS
temp_FPS=0
End If
'テキスト情報を描画
Dim buf[255] As Char
wsprintf(buf,Ex"%dfps %dm/s %dkm/h\nESCキーで終了",dwNowFPS,Int(velocity),Int(velocity*3600/1000))
dx_DrawText(ScreenX*2/3,ScreenY-50,buf,D3DCOLOR_XRGB(200,200,200))
End Sub
正常に実行できたでしょうか?起動直後にプログラムが止まってしまうときなどは、XファイルがきちんとEXEファイルと同じディレクトリに格納されているかを確認してみましょう。
これだけのコーディングでレーシングゲームの基礎プログラムを作れてしまいましたね。アクセル/ブレーキ/ハンドルの制御をより滑らかなものに改良すれば、よりリアルな走行が楽しめるかと思います。次回はこのプログラムにエンジン音を付けてみます。
講座インデックスへ戻る | ©2005 Discoversoft |