これがサンプルのソースだっ

さて、いよいよ始まりました「解剖記」。この解説は、ある程度HSPの命令に関しては覚えてる人を対象にしてます。だからいちいち命令に関しての解説はしません。でも、この部分ではこういうことをやってるんだよ、みたいな解説をしていくつもりなんで、初めてHSPやる人が「シューティングってどうやって作るんだろ?」って思ったときに見てもなるべくわかるようにはするつもりです。では能書きはここまでにして、サンプルのソースを見てみることにしましょう。


; シューティングゲームサンプル
; by たかのん
; HSP v2.5 で作成されています
; 敵と自機の距離によって画面に倍数が表示されます。
; この倍数は、距離が近いほど大きくなります。


;■ 初期設定
	screen 0,640,480,1
	title "Sample Shooting by たかのん"
	highscore=5000
*gamestart
	cls 4
	randomize
	move=5			;自機の移動速度を指定
	smax=50 		;星の最大数
	emax=50			;敵の最大数
	tmax=200		;敵弾最大数
	wmax=3			;自機弾最大数
	imax=10			;倍数表示最大数
	vmax=10			;情報表示最大数
	bmax=10			;爆風最大数
	level=1			;難易度


;■ 配列定義
	dim sx,smax		;星のx軸座標
	dim sy,smax		;星のy軸座標
	dim sc,smax		;星の色
	dim ss,smax		;星の移動速度

	dim ex,emax		;敵x軸座標
	dim ey,emax		;敵y軸座標
	dim ef,emax		;敵固さ・生死
	dim en,emax		;敵種類
	dim exv,emax		;敵x方向運動量
	dim eyv,emax		;敵y方向運動量
	dim et,emax		;敵出現からの時間

	dim tx,tmax		;敵弾x軸座標
	dim ty,tmax		;敵弾y軸座標
	dim tf,tmax		;敵弾on/off
	dim txv,tmax		;敵弾x方向運動量
	dim tyv,tmax		;敵弾y方向運動量

	dim wx,wmax		;自機弾のx軸座標
	dim wy,wmax		;自機弾のy軸座標
	dim wf,wmax		;自機弾のOn/Off
	dim wyv,wmax		;自機弾のy軸移動距離

	dim ix,imax		;倍数x軸座標
	dim iy,imax		;倍数y軸座標
	dim iff,imax		;倍数表示時間
	dim iv,imax		;倍数フォントサイズ

	dim bx,bmax		;爆風x軸座標
	dim by,bmax		;爆風y軸座標
	dim bf,bmax		;爆風表示時間


;■ バッファへ画像の読みこみ
	buffer 2,640,480,1
	pos 0,0
	picload "sample.bmp",1


;■ 効果音とBGMの読みこみ
	sndload "Int01.mid",0,1
	sndload "dmg.wav",1,0
	sndload "exp.wav",2,0
	sndload "shot.wav",3,0
	sndload "kin.wav",4,0


;■ 星の準備
	repeat smax
		rnd sx.cnt,640
		rnd sy.cnt,480
		rnd sc.cnt,8
		ss.cnt=sc.cnt+3
		sc.cnt=sc.cnt*32+31
	loop


;■ 平方根の準備
	dim calc,900
	repeat 900
		temp=cnt : calc.cnt=temp*temp
	loop


;■ スタート前準備
	mx=295 : my=400		;自機の初期位置を指定
	mf=8			;自機の初期シールドを指定
	gameovertime=0
	score=0
	frame=0
	highdst=0
	snd 0
	gsel 0,1
	palcopy 2
	gmode 2

;■ メインルーチン
*main
	redraw 2
	color bgcolor,0,0 : bgcolor=0
	boxf 0,0,640,480
	gosub *message					;ゲーム情報
	gosub *haikei					;星の描写
	gosub *jikimove				;自機移動
	gosub *weapon					;自機弾
	if frame\(25-level)=0 : gosub *enemyborn	;敵生成
	gosub *enemymove				;敵移動
	gosub *tekitamamove				;敵弾移動
	if pat&128>0 : gosub *pausegame			;ポーズ
	getkey returntop,121 : if returntop=1 : end 	;強制終了(F10)
	if mf<1 : mxv=0 : myv=0 : gameovertime++ : gosub *bomb
	if gameovertime>100 : goto *gameover
	await 30
	redraw 1
	frame++
	level=frame/500+1
	if level>20 : level=20
goto *main


;■ 自機移動
*jikimove
	if mf>0 : stick pat,79
	shottime--
	if mf>0 : if (pat&64>0)&(shottime<0) : shot=1
	xv=(pat>>2&1)-(pat&1)
	yv=(pat>>3&1)-(pat>>1&1)
	if mf>0 : mx=xv*move+mx : my=yv*move+my
	if mx<0		: mx=0
	if mx>590	: mx=590
	if my<0		: my=0
	if my>430	: my=430
	pos mx,my : gcopy 2,xv*50+50,0,50,50
return


;■ 背景描写
*haikei
	repeat smax
		color sc.cnt,sc.cnt,sc.cnt
		sy.cnt=sy.cnt+ss.cnt
		if sy.cnt>480 : sy.cnt=0 : rnd sx.cnt,640
		pset sx.cnt,sy.cnt
	loop
return


;■ 自機弾発射
*weapon
	repeat wmax
		if (shot=1)&(wf.cnt<1) {
			wf.cnt=1
			wx.cnt=mx+12
			wy.cnt=my-40
			shot=0
			shottime=1
	;		snd 3			;効果音がうるさいので切ってあります^^;
			}
		if wf.cnt<1 : continue
		pos wx.cnt,wy.cnt : gcopy 2,150,0,25,50
		wy.cnt=wy.cnt-40
		if wy.cnt<-50 : wf.cnt=0
	loop
return


;■ 敵生成
*enemyborn
	rnd temp,7
	if temp=0 : return
	repeat emax
		if ef.cnt>0 : continue
		if temp=1 : en.cnt=1
		if temp=2 : en.cnt=1
		if temp=3 : en.cnt=1
		if temp=4 : en.cnt=2
		if temp=5 : en.cnt=2
		if temp=6 : en.cnt=3
		ef.cnt=en.cnt		; 固さ
		rnd ex.cnt,640		; 初期出現位置x軸
		ey.cnt=-50		; 初期出現位置y軸
		exv.cnt=0		; 初期移動量x軸
		eyv.cnt=10		; 初期移動量y軸
		et.cnt=0
		break
	loop
return


;■ 敵移動
*enemymove
	repeat emax
		et.cnt++
		if ef.cnt<1 : continue
		ent=cnt
		repeat wmax
			if wf.cnt<1 : continue
			ddx=(ex.ent+25)-(wx.cnt+12) : if ddx<0 : ddx=-ddx
			ddy=(ey.ent+25)-(wy.cnt+25) : if ddy<0 : ddy=-ddy
			if (ddx>=0)&(ddx<20)&(ddy>=0)&(ddy<40) {
				ef.ent-- : wf.cnt=0
				if ef.ent>0 {
					pos wx.cnt,wy.cnt
					gcopy 2,175,25,25,25
					snd 4
					score++
				}
				else {
					pos ex.ent,ey.ent
					gcopy 2,200,0,50,50
					snd 2
					gosub *messageborn
				}
			}
		loop
		if en.cnt=1 : gosub *enemy1
		if en.cnt=2 : gosub *enemy2
		if en.cnt=3 : gosub *enemy3
	loop
return

;■ 敵1
*enemy1
	pos ex.cnt,ey.cnt : gcopy 2,250,0,50,50
	dx=mx-ex.cnt
	dy=my-ey.cnt
	if dy<350 {
		if dx<0 {
			exv.cnt=exv.cnt-1
			if exv.cnt<-25 : exv.cnt=-25
		}
		else {
			exv.cnt=exv.cnt+1
			if exv.cnt>25 : exv.cnt=25
		}
	}
	if dx<0 : dx=-dx
	if dx<50 : gosub *tamaborn
	eyv.cnt=4
	ex.cnt=ex.cnt+exv.cnt
	ey.cnt=ey.cnt+eyv.cnt
	if ex.cnt<-50 : ef.cnt=0
	if ex.cnt>640 : ef.cnt=0
	if ey.cnt<-50 : ef.cnt=0
	if ey.cnt>480 : ef.cnt=0
return


;■ 敵2
*enemy2
	pos ex.cnt,ey.cnt : gcopy 2,300,0,50,50
	dx=mx-ex.cnt
	if et.cnt<2 {
		if dx<0 {
			exv.cnt=-6
		}
		else {
			exv.cnt=6
		}
	}
	if et.cnt>25 : eyv.cnt-- : if eyv.cnt<-10 : eyv.cnt=-10
	if ey.cnt>200 : gosub *tamaborn
	ex.cnt=ex.cnt+exv.cnt
	ey.cnt=ey.cnt+eyv.cnt
	if ex.cnt<-50 : ef.cnt=0
	if ex.cnt>640 : ef.cnt=0
	if ey.cnt<-50 : ef.cnt=0
	if ey.cnt>480 : ef.cnt=0
return;


■ 敵3
*enemy3
	pos ex.cnt,ey.cnt : gcopy 2,350,0,50,50
	dx=mx-ex.cnt
	if et.cnt<2 {
		if dx<0 {
			exv.cnt=-3
		}
		else {
			exv.cnt=3
		}
	}
	if ey.cnt>200 : eyv.cnt--
	if et.cnt>20 : if ey.cnt<50 : eyv.cnt++
	if ey.cnt>200 : gosub *tamaborn
	if et.cnt>20 : if ey.cnt<50 : gosub *tamaborn
	ex.cnt=ex.cnt+exv.cnt
	ey.cnt=ey.cnt+eyv.cnt
	if ex.cnt<-50 : ef.cnt=0
	if ex.cnt>640 : ef.cnt=0
	if ey.cnt<-50 : ef.cnt=0
	if ey.cnt>480 : ef.cnt=0
return


;■ 弾生成
*tamaborn
	if frame\(8-(level/4))>0 : return
	dx=mx-ex.cnt : px=dx : if dx<0 : dx=0-dx
	dy=my-ey.cnt : py=dy : if dy<0 : dy=0-dy
	dst=(dx*dx)+(dy*dy)
	edx=ex.cnt+12 : edy=ey.cnt+12
	repeat 900
		if dst<calc.cnt : dst=cnt : break
	loop
	repeat tmax
		if tf.cnt>0 : continue
		tf.cnt=1
		tx.cnt=edx : ty.cnt=edy
		rnd ds,8 : ds=level/5+3+ds
		txv.cnt=px*ds/dst
		tyv.cnt=py*ds/dst
		break
	loop
return


;■ 敵弾移動 & 当り判定
*tekitamamove
	repeat tmax
		if tf.cnt<1 : continue
		tx.cnt=tx.cnt+txv.cnt
		ty.cnt=ty.cnt+tyv.cnt
		if tx.cnt>640 : tf.cnt=0 : continue
		if tx.cnt<-25 : tf.cnt=0 : continue
		if ty.cnt>480 : tf.cnt=0 : continue
		if ty.cnt<-25 : tf.cnt=0 : continue
		pos tx.cnt,ty.cnt : gcopy 2,175,0,25,25
		dx=(mx+25)-(tx.cnt+12) : if dx<0 : dx=-dx
		dy=(my+25)-(ty.cnt+12) : if dy<0 : dy=-dy
		if (dx>=0)&(dx<10)&(dy>=0)&(dy<10) {
			repeat tmax : tf.cnt-- : loop
			pos tx.cnt,ty.cnt
			gcopy 2,175,25,25,25
			bgcolor=128
			snd 1
			mf--
		}
		if (dx>=10)&(dx<40)&(dy>=10)&(dy<40) : score++
	loop
return


;■ 倍率表示
*messageborn
	dmy=my-ey.ent : if dmy<0 : dmy=-dmy
	dstv=480-dmy/50
	if highdst<dstv : highdst=dstv
	dstlevel=level
	dstcore=dstv*dstlevel
	score=en.ent*100*dstcore+score
	repeat imax
		if iff.cnt>0 : continue
		ix.cnt=ex.ent
		iy.cnt=ey.ent
		iv.cnt=dstv
		iff.cnt=20
		il.cnt=dstlevel
		realscore=en.ebt*100
		break
	loop
return

;■ ゲーム情報
*message
	repeat imax
		if iff.cnt<1 : continue
		rnd icr,8 : icr=icr*32+31
		rnd icg,8 : icg=icg*32+31
		rnd icb,8 : icb=icb*32+31
		color icr,icg,icb
		font "MSゴシック",iv.cnt*2+8,1
		pos ix.cnt,iy.cnt
		mes "× "+iv.cnt
		iy.cnt++
		iff.cnt--
	loop

	font "MSゴシック",12,3
	if highscore<score : highscore=score
	color 0,255,255
	pos 10,10 : mes "HIGHSCORE "+highscore

	color 255,255,255
	pos 10,30 : mes "SCORE "+score

	color 0,255,0
	pos 10,50
	mes "HIGH DISTANCE "+highdst

	color 255,255,0
	pos 10,70
	mes "LEVEL "+level

	color 255,255,255
	pos 10,460
	mes "SHIELD "
	if mf<1 : return
	repeat mf
		color 255,cnt*32,0
		pos cnt*10+60,460
		mes "■"
	loop
return


;■ 自機爆風
*bomb
	repeat bmax
		bf.cnt--
		if bf.cnt<1 {
			rnd bf.cnt,10 : bf.cnt=bf.cnt+10
			rnd bx.cnt,50 : bx.cnt=25-bx.cnt+mx
			rnd by.cnt,50 : by.cnt=25-by.cnt+my
		}
		pos bx.cnt,by.cnt
		gcopy 2,200,0,50,50
		rnd dbx,10 : dbx=dbx-5
		bx.cnt=bx.cnt+dbx
		by.cnt=by.cnt+10
	loop
	rnd effect,10
	if effect=0 : snd 1 : bgcolor=128
	if effect=1 : snd 2 : bgcolor=255
return


;■ ポーズ処理
*pausegame
	redraw 2
	font "MSゴシック",40,3
	rnd icr,8 : icr=icr*32+31
	rnd icg,8 : icg=icg*32+31
	rnd icb,8 : icb=icb*32+31
	color icr,icg,icb
	pos 250,200 : mes "PAUSE"
	stick pat : if pat&128>0 : return
	getkey returntop,121 : if returntop=1 : end ; 強制終了(F10)
	await 30
	redraw 1
goto *pausegame


;■ ゲームオーバー
*gameover
	redraw 2
	font "MSゴシック",40,3
	rnd icr,8 : icr=icr*32+31
	rnd icg,8 : icg=icg*32+31
	rnd icb,8 : icb=icb*32+31
	color icr,icg,icb
	pos 200,200 : mes "GAME OVER"
	pos 30,250 : mes "PUSH RETURN TO RESTART"
	stick pat : if pat&32>0 : sndoff : wait 10 : goto *gamestart
	getkey returntop,121 : if returntop=1 : end ; 強制終了(F10)
	await 30
	redraw 1
goto *gameover

簡単に、見やすいように作ったつもりですが、長いです。非常〜に長いです。HSP詳しい人が見たら「無駄が多いなぁ・・・」と思われてしまうこと間違い無しです。でも、半日で作ったんだから許して。変数の整理なんか全然やってないんだから^^;

・・・さて、次章からは、これを解剖して解説していく事にします。

解剖記のメニューへ戻る 次のページへ進む