衝突チェック

スプライトの移動の次は当たり判定をしてみましょう。

先にこの章で説明すると言っていたスプライトの優先順位について説明しておきます。

スプライトナンバーの若い方がディスプレイ手前に表示されます。

キャラクターが重なって隠れては困るものの方のスプライトナンバーを小さくしておきましょう。

少し長くなってしまいましたが前章のサンプルに敵を加えたものを解説していきたいと思います。

#include "hspdx.as"
	randomize
	es_ini
	es_screen 640,480,8
	if stat==1 : dialog "DirectXの初期化に失敗しました" : end
	if stat==2 : dialog "スクリーンの初期化に失敗しました" : end
	buffer 2,,,1
	picload "shoot2.bmp"
	es_buffer 2,0,-1
	if stat : es_bye : dialog "転送に失敗しました" : end
	es_size 80,60,70,0
	es_pat 0,0,0,0 ; 左移動時
	es_pat 1,80,0,0 ; 通常
	es_pat 2,160,0,0 ; 右移動時
	es_pat 3,0,60,0 ; 敵1
	es_size 50,40,80,0
	es_pat 4,80,60,0 ; 敵2左移動時
	es_pat 5,130,60,0 ; 敵2通常
	es_pat 6,180,60,0 ; 敵2右移動時
	es_size 8,20,0,0
	es_pat 7,140,100,5 ; 炎1_1
	es_pat 8,148,100,5 ; 炎1_2
	es_pat 9,156,100,5 ; 炎1_3
	es_pat 10,148,100,5 ; 炎1_2
	es_pat 11,164,100,5 ; 炎2_1
	es_pat 12,172,100,5 ; 炎2_2
	es_pat 13,180,100,5 ; 炎2_3
	es_pat 14,172,100,5 ; 炎2_2
	es_size 20,20,100,0
	es_pat 15,80,100,0 ; 弾1
	es_pat 16,100,100,0 ; 弾2
	es_pat 17,120,100,0 ; 弾3
	es_link 10,7
	es_link 14,11
	gsel 0
	es_window 0,0,640,480
	es_area -80,-80,645,485

*start
	x=70 : y=90 : life=50 : score=0
	repeat 10
		es_kill cnt
		es_kill cnt+11
	loop
	es_set 10,x*4,y*4,1
	es_set 19,x*4+37,y*4+58,7
	repeat
		if dam > 0 : es_cls 200 : dam- : else : es_cls 0,0,50
		es_pos 10,x*4,y*4
		es_pos 19,x*4+37,y*4+58
		color 255 : es_boxf 10,460,life*2+10,470
		str score,5
		pos 5,5 : es_mes "SCORE "+score
		int score
		es_draw
		es_getfps fps
		pos 570,455 : es_mes "FPS : "+fps
		es_sync 1
		stick k,15
		if k==128 : end
		if k & 1 {
			if bend=0 : bend=1 : es_set 10,x*4,y*4,0
			x- : if x < 0 : x=0
		} else {
			if bend=1 : bend=0 : es_set 10,x*4,y*4,1
		}
		if k & 2 : y- : if y < 0 : y=0
		if k & 4 {
			if bend.1=0 : bend.1=1 : es_set 10,x*4,y*4,2
			x+ : if x > 139 : x=139
		} else {
			if bend.1=1 : bend.1=0 : es_set 10,x*4,y*4,1
		}
		if k & 8 : y+ : if y > 104 : y=104
		if k & 16 : gosub *cartridge
		gosub *e_generation1
		gosub *e_generation2
		gosub *collision
		if life < 1 : break
		await
	loop
	goto *gameset

*cartridge ; 自機弾生成
	es_new generation,0
	if generation < 5 {
		es_set generation,x*4+30,y*4-5,15
		es_type generation,4
		es_adir generation,32,1000
	}
	return

*e_generation1 ; 敵1生成
	rnd r,20
	if r > 0 : return
	es_new generation,11
	if generation < 16 {
		rnd r,95
		rnd r.1,7
		es_set generation,r*6,-59,3
		es_set generation+9,r*6+36,-65,12
		es_type generation,2
		if r.1 > 3 : r.1+=57
		es_adir generation,r.1,200
		es_adir generation+9,r.1,200
	}
	return

*e_generation2 ; 敵2生成
	es_new generation,16
	if generation < 19 {
		rnd r,20
		if r > 0 : return
		rnd r,2
		rnd r.1,100
		es_set generation,r*690-50,r.1*4,5
		es_type generation,2
	} else {
		rnd r,30
		if r > 2 : return
		es_get search,r+16,3 : es_get search.1,r+16,5
		es_get search.2,10,3 : es_get search.3,10,5
		es_ang search,search.1,35+search.2,30+search.3
		es_adir r+16,stat,350
	}
	return

*collision ; 衝突チェック
	repeat 5
		es_check chk,cnt,2
		if chk > 10 & (chk < 16) : es_kill chk : es_kill chk+9 
: es_kill cnt : score+=3
		if chk > 15 & (chk < 19) : es_kill chk : es_kill cnt : score+=5
	loop
	es_check chk,10,2
	if chk > 10 & (chk < 16) : es_kill chk : es_kill chk+9 : life-=3 : dam=3
	if chk > 15 & (chk < 19) : es_kill chk : life-=2 : dam=3
	return

*gameset ; ゲームオーバーメッセージ
	es_cls
	color 255
	pos 250,120 : es_fmes "G A M E O V E R"
	pos 250,320 : es_mes "SCORE : "+score
	pos 250,350 : es_mes "ESCkey : exit"
	pos 250,380 : es_mes "ENTERkey : restart"
	es_sync
	repeat
		stick k
		if k & 128 : end
		if k & 32 : break
		wait 10
	loop
	goto *start

当たり判定のチェック命令以外の新命令もありますので上から順に説明していきます。

ラベル「start」の初めにes_killを使用しています。

これは初めてこの行を実行するときにはなくても影響ありませんが、

今回はゲームオーバーしたら再ゲーム、という概念がございますのでその時に使用されるものです。

どういうことをしているかというと、自機から発射された弾と敵を全部消すと言うものです。

コレがなければ再ゲームをしたときに続きからはじめたような状態になってしまいます。

次に出てくるのはes_boxfです。通常のboxfと同じ効果の命令ですが

boxfはウィンドウしか表示させることができないのでes_boxfを使用しただけです(^^;

es_mesが次にありますがこれもboxfと同じ理由でDX画面上には表示させることができないので、

DX用のメッセージ表示命令となっています。

通常のmesと違う点は文字色は白(255,255,255)しかない、フォントの種類・大きさが変更できない、です。

mesではパラメータに変数だけを指定できましたがes_mesでは不可能です。「es_mes ""+変数」としましょう。

次にes_getfpsですね。これはヘルプを見たまんまの命令で説明する必要はないと思いますが、

ヘルプにも記載されている通り1秒間に何回es_syncが実行されたかを示す値です。

このゲームでは60くらい出ていたらちゃんとプレイできるものでしょう。

この程度の目安にするための命令で別になくても影響のない命令です・・・。

そして次に当たり判定に使用されるes_typeが出てきます。

HSPDX.TXTにも書かれていますがp2のtype値に「1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768」

この中から1つ選びp1で指定したスプライトのtypeを決めてやります。

コレをしない場合スプライトのタイプは初期値の1になってしまいます。

とりあえずコレを決める段階で全部のタイプを決めておきましょう。

ここでは1は自機、2は敵機、4は自機弾としています。

ラベル「collision」がこの章のメインとなりますね。ここではes_checkを使用し衝突のチェックをしています。

p2で指定したスプライト(キャラクター?)とp3(es_typeで指定したtype値)とが当たったかを判定しp1に結果を入れます。

当たっていない場合はp1に-1が入り、複数当たっている場合はスプライトナンバーの小さいものがp1に返ります。

p3には複数のtype値を指定することができ指定したいものをすべて足した値をp3に入れます。

最後にes_fmesですが、es_mesと同じ文章を表示させる命令です。

こちらはよりmesっぽくなっていてcolorで色指定、フォントにて種類・サイズ指定ができるようになっています。

es_mesの方が高速に処理できるので使い分けをしましょう。

まだ少し紹介していない命令がありますが、この章でDX講座の最終章とさせていただき終了します。