DirectXプログラミング講座 〜Vol20. 【2Dシューティング】敵機を出現させよう〜

一定間隔で続々と敵機がゲーム中に出現させるプログラムを作ってみます。


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

コーディング作業

前回のVol19. 【2Dシューティング】ショット(弾)の発射で作成したコードに手を加える形で作業を進めます。赤色で示すコードが前回からの変更点または追加点です。

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

敵機の基本的な構造は、ショット(弾)とほとんど同じです。

MAX_ENEMIESで管理できる敵機の最大数を定義します。続いて、すべての敵機オブジェクトを総括して管理するためのオブジェクトポインタ配列pEnemiesArrayを定義します。TempTime_Enemie変数は一定間隔で敵機を出現させるために使用するカウンタ変数になります。

#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  'ゲーム画面の高さ

Const MAX_SHOTS=50     '弾の最大数
Const MAX_ENEMIES=50   '敵機の最大数

'DirectInput用
Dim pInKey As *CInputKeyboard

'背景画像
Dim pImage_BackGround As *CImage2D

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

'ショット(弾)を管理する配列
Dim pShotsArray[ELM(MAX_SHOTS)] As *CShot
Dim ShotTime As Long, TempTime_Shot As Long

'自機クラス
Dim pMyPlane As *CPlane

'敵機クラス
Dim pEnemiesArray[ELM(MAX_ENEMIES)] As *CEnemie
Dim TempTime_Enemie=0 As Long

敵機の管理及びCEnemieのコーディング

まずは、CEnemieオブジェクトが生成されたときに呼び出されるAddEnemie関数、消滅するときに呼び出されるDeleteEnemie関数を定義します。AddEnemie関数は、敵機を管理するためのオブジェクト配列pEnemiesArrayに生成直後のCEnemieオブジェクトを登録する働きをします。DeleteEnemie関数はその逆で、CEnemieオブジェクトが破棄されるときにpEnemiesArrayからそのオブジェクトを排除する働きをします。

'-------------
' 敵機の管理
'-------------
Sub AddEnemie(pEnemie As *CEnemie)
    Dim i As Long

    For i=0 To ELM(MAX_ENEMIES)
        If pEnemiesArray[i]=0 Then
            pEnemiesArray[i]=pEnemie
            Exit For
        End If
    Next
End Sub
Sub DeleteEnemie(pEnemie As *CEnemie)
    Dim i As Long

    For i=0 To ELM(MAX_ENEMIES)
        If pEnemiesArray[i]=pEnemie Then
            pEnemiesArray[i]=0
            Exit For
        End If
    Next
End Sub

'--------------
' 敵機クラス
'--------------
Class CEnemie
    '位置
    x As Long
    y As Long
    width As Long
    height As Long

    'スピード
    speed As Long

    Sub EreaOutCheck()
        'はみ出しチェック
        If y>SCREEN_HEIGHT Then
            '画面をはみ出したので、自爆させる
            Delete VarPtr(This)
        End If
    End Sub

Public
    Sub CEnemie()
        width=24
        height=24

        speed=1

        '初期位置
        x=Rnd()*SCREEN_WIDTH
        y=0

        AddEnemie(VarPtr(This))
    End Sub

    Sub ~CEnemie()
        DeleteEnemie(VarPtr(This))
    End Sub


    '描画
    Sub Draw()
        pImage_CharaMap1->DrawStretch(
            x-width/2    +SCREENBASE_X,
            y-height/2   +SCREENBASE_Y,
            width,
            height,

            0,
            160,
            width,
            height)

        y=y+speed
        EreaOutCheck()
    End Sub
End Class

InputActionProc関数のコーディング

一定間隔で敵機を出現させるためのコードを記述します。今回は、1/3秒間隔で敵機を出現させてみます。

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

    ShotTime=ShotTime+1
    If KeyState[DIK_SPACE] and &H80 Then
        'スペースキーが押された、弾を発射
        If ShotTime>TempTime_Shot+3 Then
            pMyPlane->Shot()

            TempTime_Shot=ShotTime
        End If
    End If

    '一定間隔で敵機を生成
    TempTime_Enemie=TempTime_Enemie+1
    If (TempTime_Enemie mod 20)=0 Then
        Dim pEnemie As *CEnemie
        pEnemie=New CEnemie
    End If
End Sub

RenderProc関数のコーディング

敵機を描画するためのコードを追加します。

Sub RenderProc()
    ' TODO: この位置に描画に関するコードを記述してください。

    Dim i As Long

    '背景を描画
    pImage_BackGround->Draw(
        SCREENBASE_X,
        SCREENBASE_Y,
        SCREEN_WIDTH,
        SCREEN_HEIGHT)

    '自機を描画
    pMyPlane->Draw()

    '弾を描画
    For i=0 To ELM(MAX_SHOTS)
        If pShotsArray[i] Then
            pShotsArray[i]->Draw()
        End If
    Next

    '敵機を描画
    For i=0 To ELM(MAX_ENEMIES)
        If pEnemiesArray[i] Then
            pEnemiesArray[i]->Draw()
        End If
    Next
End Sub

実行してみよう

実行してみると、続々と敵機が出現してきますね。今回のプログラムでは、まだ敵機をショットで破壊することができません。次回は、「敵機と弾」「敵機と自機」の当たり判定を行って、敵機を攻撃すると消滅するプログラムを作ってみます。



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