前回までの章で、最低限のシューティング理論をマスターできましたでしょうか?今回からは、シューティングテンプレートに対して、演出効果という付加価値をつけていきたいと思います。
まずは、敵機をやっつけたときに起こる爆発を再現してみましょう。
理論は至って簡単。敵機を撃墜し、プログラム側で敵機を破棄する際に爆発のアニメーションを生成するのです。
アニメーションとはいっても、特別なことはやりません。ビットマップをコマ送りにして画面に表示するだけです。考えてみれば、自機の動き、弾の動きなんかも時間と共に画面の中を駆けずり回る、アニメーションと捉えることができますね。
Vol17. 【2Dシューティング】自機と背景を表示しようで用意したキャラクタマップその2(chara_map2.bmp)に、爆発アニメーションのコマ画像が含まれているので、それを利用します。
↑の画像をコマ送りにすると…
のような感じで表示できるんですね☆
前回のVol21. 【2Dシューティング】当たり判定で作成したコードに手を加える形で作業を進めます。赤色で示すコードが前回からの変更点または追加点です。
MAX_BLASTSで管理できる爆発の最大数を定義します。続いて、すべての爆発オブジェクトを総括して管理するためのオブジェクトポインタ配列pBlastsArrayを定義します。
#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 '敵機の最大数 Const MAX_BLASTS=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 '爆発を管理する配列 Dim pBlastsArray[ELM(MAX_BLASTS)] As *CBlast
まずは、CBlastオブジェクトが生成されたときに呼び出されるAddBlast関数、消滅するときに呼び出されるDeleteBlast関数を定義します。AddBlast関数は、敵機を管理するためのオブジェクト配列pBlastsArrayに生成直後のCBlastオブジェクトを登録する働きをします。DeleteBlast関数はその逆で、CBlastオブジェクトが破棄されるときにpBlastsArrayからそのオブジェクトを排除する働きをします。
CBlastは、爆発を管理するクラスです。メンバ変数TempTime、TempStepを利用して一定間隔でのコマ送り再生を可能にしています。爆発し終わると、自動的にオブジェクト自身を破棄します。
'-------------
' 爆発の管理
'-------------
Sub AddBlast(pBlast As *CBlast)
Dim i As Long
For i=0 To ELM(MAX_BLASTS)
If pBlastsArray[i]=0 Then
pBlastsArray[i]=pBlast
Exit For
End If
Next
End Sub
Sub DeleteBlast(pBlast As *CBlast)
Dim i As Long
For i=0 To ELM(MAX_BLASTS)
If pBlastsArray[i]=pBlast Then
pBlastsArray[i]=0
Exit For
End If
Next
End Sub
'-----------------
' 爆発クラス
'-----------------
Class CBlast
'位置
x As Long
y As Long
width As Long
height As Long
TempTime As Long
TempStep As Long
Public
Sub CBlast(sx As Long, sy As Long)
x=sx
y=sy
width=32
height=32
TempTime=0
TempStep=-5
AddBlast(VarPtr(This))
End Sub
Sub ~CBlast()
DeleteBlast(VarPtr(This))
End Sub
Sub Draw()
pImage_CharaMap2->DrawStretch(
x-width/2 +SCREENBASE_X,
y-height/2 +SCREENBASE_Y,
width,
height,
Abs(TempStep)*32,
160,
width,
height)
TempTime=TempTime+1
If TempTime=3 Then
If TempStep>=5 Then
'爆発しきったとき
Delete VarPtr(This)
Exit Sub
End If
TempStep=TempStep+1
TempTime=0
End If
End Sub
End Class
敵機と弾の当たり判定によって敵機を破棄する際に、爆発(CBlastクラス)を生成します。
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
'-----------------------
' 弾と敵機の当たり判定
'-----------------------
Dim i As Long, i2 As Long
Dim pos1 As POINTAPI, size1 As SIZE
Dim pos2 As POINTAPI, size2 As SIZE
For i=0 To ELM(MAX_SHOTS)
If pShotsArray[i] Then
For i2=0 To ELM(MAX_ENEMIES)
If pEnemiesArray[i2] Then
pShotsArray[i]->GetHitPositionAndSize(pos1,size1)
pEnemiesArray[i2]->GetHitPositionAndSize(pos2,size2)
If HitTest(pos1,size1,pos2,size2) Then
'爆発を生成
Dim pBlast As *CBlast
pBlast=New CBlast(pos2.x,pos2.y)
'ヒットしたときは弾、敵機ともに破棄
Delete pShotsArray[i]
Delete pEnemiesArray[i2]
Exit For
End If
End If
Next
End If
Next
'-------------------------
' 敵機と自機の当たり判定
'-------------------------
For i=0 To ELM(MAX_SHOTS)
If pEnemiesArray[i] Then
pMyPlane->GetHitPositionAndSize(pos1,size1)
pEnemiesArray[i]->GetHitPositionAndSize(pos2,size2)
If HitTest(pos1,size1,pos2,size2) Then
'ヒットしたときは敵機を破棄(同時にビープ音を鳴らす)
Delete pEnemiesArray[i]
MessageBeep(0)
Exit For
End If
End If
Next
End Sub
爆発を描画するためのコードを追加します。
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
'爆発を描画
For i=0 To ELM(MAX_BLASTS)
If pBlastsArray[i] Then
pBlastsArray[i]->Draw()
End If
Next
End Sub
敵機を撃墜してみてください。意外とリアルな爆発、ご体験できましたでしょうか??次回は、更に臨場感を高めるために、効果音を鳴らしてみます。
講座インデックスへ戻る | ©2005 Discoversoft |