DirectXプログラミング講座 〜Vol18. 【2Dシューティング】自機を動かそう〜

前回の章で自機が表示できたら、今度はそれをキーボード操作で動かしてみます。今回はDirectInputを介してキーボード入力を検地するため、CInputKeyboardクラスを利用します。

前回のVol17. 【2Dシューティング】自機と背景を表示しようで作成したプロジェクトを編集する形で作業を進めます。


今回のサンプルプロジェクト

コーディング作業

前回のVol17. 【2Dシューティング】自機と背景を表示しようで作成したコードに手を加える形で作業を進めます。赤色で示すコードが前回からの変更点または追加点です。

"fight.abp" の先頭部分のコーディング

DirectInputでキーボード入力を受け付けるためのCInputKeyboardオブジェクトポインタを定義します。

#include "fight.idx"


Dim ScreenX=640 As Long	'ディスプレイの幅  (ピクセル単位)
Dim ScreenY=480 As Long	'ディスプレイの高さ(ピクセル単位)

' TODO: この位置にグローバル変数を定義してください。

Const SCREENBASE_X=140   'ゲーム画面左上のスクリーンX座標
Const SCREENBASE_Y=0     'ゲーム画面左上のスクリーンY座標
Const SCREEN_WIDTH=360   'ゲーム画面の幅
Const SCREEN_HEIGHT=480  'ゲーム画面の高さ

'DirectInput用
Dim pInKey As *CInputKeyboard

'背景画像
Dim pImage_BackGround As *CImage2D

'キャラクタマップ画像
Dim pImage_CharaMap1 As *CImage2D
Dim pImage_CharaMap2 As *CImage2D

'自機クラス
Dim pMyPlane As *CPlane

CPlaneのコーディング

自機キャラクタを十字方向に移動するためのメンバ関数MoveUp、MoveDown、MoveLeft、MoveRightを定義します。これら移動のためのメンバ関数は、キーボード入力に従って、描画毎に呼び出されることになります。このアプリケーションは、60FPS(一秒間に60回の描画)のため、移動スピード、即ち一回分の呼び出しでどれだけ自機キャラクタを移動させるかを指定します。この移動スピードは、メンバ変数speedで管理します。

EreaOutCheck関数は、自機キャラクタがゲーム画面の外にはみ出さないよう、チェックを行う関数です。もしもはみ出していた場合は、座標を修正する機能を持ち合わせます。

今回は自機キャラクタをキーボード操作に従って移動させるのが目的ですが、ついでなので、自機の傾きまで処理してしまいましょう。使用しているキャラクタマップでは、自機キャラクタの傾きに対応する5枚の画像が存在します。

移動状況に応じて、RudderSituationを5段階で変化し、Draw関数が実行されるときにそれを参照します。

'---------------
' 自機クラス
'---------------
Class CPlane
    '位置・高さ・幅
    x As Long
    y As Long
    width As Long
    height As Long

    '移動スピード
    speed As Long

    '傾き
    RudderSituation As Single


    '自機が画面からはみ出さないようにチェックする関数
    Sub EreaOutCheck()
        If x-width/2<0 Then
            x=width/2
        End If
        If x+width/2>SCREEN_WIDTH Then
            x=SCREEN_WIDTH-width/2
        End If

        If y-height/2<0 Then
            y=height/2
        End If
        If y+height/2>SCREEN_HEIGHT Then
            y=SCREEN_HEIGHT-height/2
        End If
    End Sub

Public

    'コンストラクタ
    Sub CPlane()
        width=32
        height=32

        '初期位置
        x=SCREEN_WIDTH/2
        y=SCREEN_HEIGHT*0.8

        '初期スピード
        speed=5
    End Sub

    'デストラクタ
    Sub ~CPlane()
    End Sub


    '描画
    Sub Draw()
        Dim TextureX As Long, TextureY As Long
        TextureX=32*(Fix(RudderSituation)+2)
        TextureY=0

        pImage_CharaMap1->DrawStretch(
            x-width/2    +SCREENBASE_X,
            y-height/2   +SCREENBASE_Y,
            width,
            height,

            TextureX,
            TextureY,
            32,
            32)
    End Sub

    '自機を移動させる関数
    Sub MoveUp()
        y=y-speed
        EreaOutCheck()
    End Sub
    Sub MoveDown()
        y=y+speed
        EreaOutCheck()
    End Sub
    Sub MoveLeft()
        x=x-speed
        EreaOutCheck()

        If RudderSituation>-2 Then
            '左方向に移動中は自機の傾きをマイナス値にする
            RudderSituation=RudderSituation-1/speed
        End If
    End Sub
    Sub MoveRight()
        x=x+speed
        EreaOutCheck()

        If RudderSituation<2 Then
            '右方向に移動中は自機の傾きをプラス値にする
            RudderSituation=RudderSituation+1/speed
        End If
    End Sub
    Sub NoMove()
        '移動していないときは自機の傾きを0に近づける
        If RudderSituation<0 Then
            RudderSituation=RudderSituation+1/speed
        ElseIf RudderSituation>0 Then
            RudderSituation=RudderSituation-1/speed
        End If
    End Sub
End Class

InitProc関数のコーディング

CInputKeyboardオブジェクトを生成するためのコードを追加します。

Function InitProc()
    'DirectXを初期化
    If dx_Init(hMainWnd,ScreenX,ScreenY,FALSE)=0 Then
        InitProc=0
        Exit Function
    End If

    'マウスカーソルを非表示にする
    ShowCursor(FALSE)

    ' TODO: この位置にアプリケーションの初期化コードを記述してください。

    'キーボードデバイスオブジェクトを生成
    pInKey=New CInputKeyboard


    '背景画像を生成
    pImage_BackGround=New CImage2D
    pImage_BackGround->SetTexture("back_ground.bmp",D3DCOLOR_XRGB(0,0,0))

    'キャラクタマップイメージを生成
    pImage_CharaMap1=New CImage2D
    pImage_CharaMap1->SetTexture("chara_map1.bmp",D3DCOLOR_XRGB(0,0,0))
    pImage_CharaMap2=New CImage2D
    pImage_CharaMap2->SetTexture("chara_map2.bmp",D3DCOLOR_XRGB(0,0,0))

    '自機を生成
    pMyPlane=New CPlane


    InitProc=1
End Function

QuitProc関数のコーディング

CInputKeyboardオブジェクトを破棄するためのコードを追加します。

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

    'キーボードデバイスオブジェクトを破棄
    Delete pInKey


    '背景画像を破棄
    Delete pImage_BackGround

    'キャラクタマップイメージを破棄
    Delete pImage_CharaMap1
    Delete pImage_CharaMap2

    '自機を破棄
    Delete pMyPlane


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

InputActionProc関数のコーディング

CKeyboard::GetStateを呼び出し、キーボードの状況をKeyState配列に取得します。状況に応じて、CPlaneクラス内で定義されているMoveUp、MoveDown、MoveLeft、MoveRightの各メンバ関数を呼び出します。今回は、自機キャラクタの傾きも想定しているので、何も移動しないときはNoMove関数を呼び出します。

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
        '方向キー(上)が押されているとき
        pMyPlane->MoveUp()
    ElseIf KeyState[DIK_DOWN] and &H80 Then
        '方向キー(下)が押されているとき
        pMyPlane->MoveDown()
    End If

    If KeyState[DIK_LEFT] and &H80 Then
        '方向キー(左)
        pMyPlane->MoveLeft()
    ElseIf KeyState[DIK_RIGHT] and &H80 Then
        '方向キー(右)
        pMyPlane->MoveRight()
    Else
        '左右キーが押されていないとき
        pMyPlane->NoMove()
    End If
End Sub

実行してみよう

方向キーを使って自機キャラクタが移動できれば成功です。移動に応じてしっかりと傾いているかもチェックしておきましょう。今回からESCキーで終了できます。



講座インデックスへ戻る ©2005 Discoversoft