敵と自機弾の当たり判定(2/2) |
3.敵がダメージを受けている時の処理 |
存在フラグが2(ダメージを受けている)であれば、dmgcntを1増やします。dmgcntが3になったら、存在フラグを1(通常)に変更します。
repeat 10
if enemyf.cnt=2 {
dmgcnt.cnt=dmgcnt.cnt+1
if dmgcnt.cnt=3 { enemyf.cnt=1 }
}
loop
4.敵が爆発中の処理 |
存在フラグが3(爆発中)であれば、eplcntを1増やします。eplcntが15になったら、存在フラグを0(消滅)に変更します。
repeat 10
if enemyf.cnt=3 {
eplcnt.cnt=eplcnt.cnt+1
if eplcnt.cnt=15 { enemyf.cnt=0 }
}
loop
5.敵がダメージを受けている絵を表示する |
絵のファイルに、残機数表示用の自機(小さい自機)、爆発、ダメージを受けて真っ白になっている敵を追加しました。
小さい自機の座標は($60,$10)、サイズは16×16です。
爆発パターンの座標は($0,$20)、($20,$20)、($40,$20)、サイズは32×32です。
ダメージを受けているパターンの座標は($60,$20)、($80,$20)、($A0,$20)、サイズは32×32です。
「敵を描画」処理を、ダメージを受けているパターンも表示できるように改造します。存在フラグの値によって、表示する絵を変えます。
; 敵を描画
repeat 10
if (enemyf.cnt=1)|(enemyf.cnt=2) {
gdx=enemyx.cnt:gdy=enemyy.cnt
i=(enemycnt.cnt/4)\4
if enemyf.cnt=1 {
if i=0 { gdox=$80 }
if (i=1)|(i=3) { gdox=$A0 }
if i=2 { gdox=$C0 }
gdoy=0
}
if enemyf.cnt=2 {
if i=0 { gdox=$60 }
if (i=1)|(i=3) { gdox=$80 }
if i=2 { gdox=$A0 }
gdoy=$20
}
gdw=32:gdh=32
gosub *Graphic_Draw
}
loop
6.敵の爆発を表示する |
存在フラグが3である敵につき、爆発の絵を表示します。eplcntが0〜4の時は1番目のパターンを、5〜9の時は2番目のパターンを、10〜14の時は3番目のパターンを表示します。
repeat 10
if enemyf.cnt=3 {
gdx=enemyx.cnt:gdy=enemyy.cnt
if eplcnt.cnt<5 { gdox=0 }
if (eplcnt.cnt>=5)&(eplcnt.cnt<10) { gdox=$20 }
if eplcnt.cnt>=10 { gdox=$40 }
gdoy=$20
gdw=32:gdh=32
gosub *Graphic_Draw
}
loop
7.スコア、残機数を表示する |
文字列を出力する処理をサブルーチン化します。出力する座標をmsx,msyに、文字列をmescontに代入してこのサブルーチンを呼ぶものとします。(ms,mesはmessage、contはcontentsの略です。)
*wrtmes
; msx,msy : 出力する座標
; mescont : メッセージの内容
ddcolor 255,255,255
ddpos (640-xsize)/2+msx,(480-ysize)/2+msy
font "MS 明朝",16
ddprint mescont
return
本サンプルプログラムでは、文字色は白、フォントは大きさ16のMS 明朝で統一することにします。
点数を表示します。スコアを左上に、ハイスコアを右上の方に表示します。
msx=0:msy=0
mescont="SCORE:"+score
gosub *wrtmes
msx=160:msy=0
mescont="HI-SCORE:"+hiscore
gosub *wrtmes
"+"演算子を文字列に対して使った場合は、「連結」の意味になります。"+"の左の文字列と右の文字列をつなげて一つにします。上のように、文字列に数値をつなげることもできます。
自機の残り数を表示します。小さい自機を、残機数の分だけ横に並べて表示します。が、実際の残機数より1つ少なく描くのが一般的です。
すると、nplayerが1以下の時は、この処理をやる必要はないということになります。
if nplayer>1 {
repeat nplayer-1
gdx=cnt*18 :gdy=36
gdox=$60 :gdoy=$10
gdw=16 :gdh=16
gosub *Graphic_Draw
loop
}
8.その他 |
敵が移動するのは、通常状態の時かダメージを受けている時です。そこで、「敵の移動」処理にも修正が必要になります。
; 敵の移動
repeat 10
if (enemyf.cnt=1)|(enemyf.cnt=2) {
・
・
・
}
loop
以上をまとめますと、敵と自機弾の当たり判定に関する処理は以下のようになります。
; プログラム起動時の初期設定 hiscore=50000 ; 敵の変数宣言 dim enelife,10 dim dmgcnt,10 dim eplcnt,10 ; ゲームスタート時の初期設定 score=0 oneup=50000 nplayer=3 ; メインループ ; 敵の移動 repeat 10 if (enemyf.cnt=1)|(enemyf.cnt=2) { ; 変更した行 i=enemycnt.cnt\16 enemyx.cnt=enemyx.cnt+enemvdx.i enemyy.cnt=enemyy.cnt+enemvdy.i if enemyy.cnt>=ysize { enemyf.cnt=0 } enemycnt.cnt=enemycnt.cnt+1 } loop ; 敵の出現 if mappnt\64=0 { n=0 w=-1 repeat 10 if enemyf.cnt=0 { repeat rnd r,xsize/32-2 if r!w { break } loop w=r enemyx.cnt=(r+1)*32 enemyy.cnt=-32 enemyf.cnt=1 enemycnt.cnt=0 enelife.cnt=3 ; 追加した行 n=n+1 if n=2 { break } } loop } ; 敵がダメージを受けている時の処理 repeat 10 if enemyf.cnt=2 { dmgcnt.cnt=dmgcnt.cnt+1 if dmgcnt.cnt=3 { enemyf.cnt=1 } } loop ; 敵が爆発中の処理 repeat 10 if enemyf.cnt=3 { eplcnt.cnt=eplcnt.cnt+1 if eplcnt.cnt=15 { enemyf.cnt=0 } } loop ; 敵と自機弾の当たり判定 repeat 4 if shotf.cnt=1 { x=shotx.cnt:y=shoty.cnt f=0 repeat 10 if ((enemyf.cnt=1)|(enemyf.cnt=2))&(x<(enemyx.cnt+32))& ((x+4)>enemyx.cnt)&(y<(enemyy.cnt+32))& ((y+16)>enemyy.cnt) { f=1 enemyf.cnt=2 dmgcnt.cnt=0 enelife.cnt=enelife.cnt-1 if enelife.cnt=0 { enemyf.cnt=3 eplcnt.cnt=0 score=score+200 if score>hiscore { hiscore=score } if score>=oneup { nplayer=nplayer+1 oneup=oneup+100000 } } } loop if f=1 { shotf.cnt=0 } } loop ; 敵を描画 repeat 10 if (enemyf.cnt=1)|(enemyf.cnt=2) { gdx=enemyx.cnt:gdy=enemyy.cnt i=(enemycnt.cnt/4)\4 if enemyf.cnt=1 { if i=0 { gdox=$80 } if (i=1)|(i=3) { gdox=$A0 } if i=2 { gdox=$C0 } gdoy=0 } if enemyf.cnt=2 { if i=0 { gdox=$60 } if (i=1)|(i=3) { gdox=$80 } if i=2 { gdox=$A0 } gdoy=$20 } gdw=32:gdh=32 gosub *Graphic_Draw } loop ; 敵の爆発を描画 repeat 10 if enemyf.cnt=3 { gdx=enemyx.cnt:gdy=enemyy.cnt if eplcnt.cnt<5 { gdox=0 } if (eplcnt.cnt>=5)&(eplcnt.cnt<10) { gdox=$20 } if eplcnt.cnt>=10 { gdox=$40 } gdoy=$20 gdw=32:gdh=32 gosub *Graphic_Draw } loop ; 点数表示 msx=0:msy=0 mescont="SCORE:"+score gosub *wrtmes msx=160:msy=0 mescont="HI-SCORE:"+hiscore gosub *wrtmes ; 自機残り数表示 if nplayer>1 { repeat nplayer-1 gdx=cnt*18 :gdy=36 gdox=$60 :gdoy=$10 gdw=16 :gdh=16 gosub *Graphic_Draw loop } ; メッセージ出力 *wrtmes ; msx,msy : 出力する座標 ; mescont : メッセージの内容 ddcolor 255,255,255 ddpos (640-xsize)/2+msx,(480-ysize)/2+msy font "MS 明朝",16 ddprint mescont return「敵と自機弾の当たり判定」処理より「敵がダメージを受けている時の処理」、「敵が爆発中の処理」を前にしています。逆にすると、dmgcntやeplcntに0を設定しても、すぐさま1になってしまうからです。「敵の出現」より「敵の移動」を前にしたのと同じような理由です。
実行画面