DirectXプログラミング講座 〜Vol13. 3D空間の中でレーシングカーを走らせよう〜

今回が初の実践的なDirectXプログラムになりそうです。カーソルキーからの入力をもとに、3D空間の中をレーシングカーが走るプログラムを作ってみます。


作成方法



レーシングカーが画面の中を自由に走り回ります

サンプルプロジェクトをダウンロード

DirectX対応アプリケーションのプロジェクトを新規作成します。プロジェクト名は "driving" などとしておきます。別途、"model.x" という自動車の形を定義するXファイルが必要になりますので、プロジェクトのディレクトリに保存しておいてください。
→model.xをダウンロード

●driving.abpの先頭部分のコーディング

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                      '速度

●InitProc関数のコーディング

ライトの設定及び自動車のメッシュオブジェクトの生成を行います。

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

●QuitProc関数のコーディング

pModelオブジェクトを破棄します。

Sub QuitProc()
    ' TODO: この位置にアプリケーションの終了処理を記述してください。

    'メッシュモデルを破棄
    Delete pModel

    'DirectXの終了処理
    dx_Quit()
End Sub

●InputActionProc関数のコーディング

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

●RednerProc関数のコーディング

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