1MAP_STG レーザーを実装 ver.0.008


2019年 5月 2日
 
 
 ver.0.008

5月 3日

 完成しましたのでどうぞ。

 今回の肝は、線と円の当たり判定と、それを利用したレーザーです。

 レーザーは照射面積によってダメージが変わります。
 
 
 HSPソースとグラの zipファイル
 1MAP_STG_ver.0.0008

(一般的にダウンロードされているファイルでは無く、というのは HSPファイルの事ですので大丈夫です。マイナーなだけです(笑))
 
 
全ソース

; 企画第一弾 : 1画面防衛シューティングを作ろう
; var.0.008

#include "hsp3dish.as" ; HSPdishの宣言


gosub *main : end		; メインルーチン

#include "put.hsp"		; 表示
#include "shot.hsp"		; 弾
#include "ene.hsp"		; 敵
#include "syoki.hsp"	; 初期設定


*main ; メインルーチン

	gosub *syoki ; 初期設定

	mainf=0 ; メインフラグ

	while ; ---------- メインルーチン ----------

	 switch mainf
	  case 0 : gosub *titl		: swbreak ; タイトル
	  case 1 : gosub *game_main	: swbreak ; ゲーム
	  case 2 : gosub *game_over	: swbreak ; ゲームオーバー
	 swend

	 if mainf=3 : _break ; end
	wend

	return


*titl ; タイトル

	repeat
	 stick k : if k!0 : mainf=1 : kwc=20 : break ; 何か押したらゲームスタート
	 redraw 0 ; 表示
	  clr		; 画面クリア
	  j_put		; 自機表示
	  c_put		; 照準表示
	  scr_put	; スコア表示

	  font "",22,0 : color 255,255,255
	   pos wx1+(wx-wx1)/2-120,wy/2-50 : mes "1画面防衛シューティング"
	   pos wx1+(wx-wx1)/2-43,wy/2+30  : mes "var.0.008"
	 redraw 1
	 await 1000/15
	loop

	return


*game_main ; ゲーム

	repeat ; ゲームループ ========================================

	 if mainf!1 : break ; ゲームオーバー

; 入力 ----------
	 x=mousex : y=mousey	; マウス、スマホの座標

	 k=0
	 repeat 1
	  if kwc>0 : kwc- : break ; ウエイト
	  stick k,256 ; マウス、スマホクリック
	 loop

	 repeat 1 ; 入力処理
	  if subf=0 { ; バルカンモード

	   if k=256 { ; 押してる
	    if 0<x and x<wx1 and   0<y and y<wy1 : subf=0 : break ; バルカン
	    if 0<x and x<wx1 and wy1<y and y<wy {
		 if kwc=0 : subf=1 : kwc=5
		 break ; レーザーモードへ
		}

		kf=1 : kc+ : cx=double(x) : cy=double(y) : break ; 押している
	   }

	   if kf=0 : break			; 一度も押してない
	    kf=0					; 放した、押しフラグリセット

	   if kc>4 : kc=0 : break	; 4フレーム以上押していた
	    kc=0

	   if jx1<x and x<jx2 and jy1<y and y<jy2 : autof=(autof+1)\2 : esn_set 0 : break ; 自機の位置の場合、オート切り替え

	   esn_set 1				; 近くの標的をセット

	   if vc=0 or vcn>0 : break	; 弾切れ or バルカン発射中
	   vcn+=vnb					; バルカン発射
	  }

	  if subf=1 { ; レーザーモード
	   if k!256 : break ; ボタン押してない

	   if 0<x and x<wx1 and   0<y and y<wy1 : subf=0 : break ; バルカン
	   if 0<x and x<wx1 and wy1<y and y<wy {
		if kwc=0 : subf=0 : kwc=5 : ; レーザーリセット
		break
	   }

	   if lf>0 : subf=0 : break ; 発射中

	   lf=1 : subf=0 : kwc=20 ; レーザー発射
	   lxs=double(x) : lys=double(y) ; 目標地点
	  }
	 loop


; 照準 ----------

	 x2=ex(esn)-cx : y2=ey(esn)-cy
	  nd=sqrt(x2*x2+y2*y2); 標的と照準の距離

	 repeat 1 ; 照準の移動
	  if autof=0 : cx=double(x) : cy=double(y) : break ; マニュアルの場合

	  if nd<csp : cx=ex(esn) : cy=ey(esn) : break

; ↑ 標的が照準スピード以下の距離なら、照準座標を標的の座標にする
; ↓ そうでないなら照準スピード分動かす

	  xn=double(ex(esn)-cx) ; 一番近い敵と照準の距離x
	  yn=double(ey(esn)-cy) ; 一番近い敵と照準の距離y

	  rad=atan(xn,yn) ; 距離xyから角度を求める
	
	  cx+=sin(rad)*csp	; 照準移動x
	  cy+=cos(rad)*csp	; 照準移動y
	 loop


; 出現 ----------
	 s_set  ; ショット出現
	 v_set  ; バルカン出現
	 l_set	; レーザー出現
	 e1_set ; 敵1出現
	 e2_set ; 敵2出現
	 e3_set ; 敵3出現


; 移動処理 ----------
	 s_syo  ; ショット処理
	 v_syo  ; バルカン処理
	 l_syo	; レーザー処理
	 e_syo	; 敵処理テーブル


	 redraw 0 ; 表示 ----------
	  clr		; 画面クリア
	  e_put		; 敵表示
	  j_put		; 自機表示
	  s_put		; ショット表示
	  v_put		; バルカン表示
	  l_put		; レーザー表示
	  c_put		; 照準表示
	  scr_put	; スコア表示
waku_put

	 redraw 1

	 await 1000/15 ; ウエイト、FPS 15
	loop ; ====================================================

	return


*game_over ; ゲームオーバー

	repeat
	 stick k : if k!0 : mainf=0 : break ; 何か押したらタイトルへ

	 redraw 0 ; 表示
	  clr		; 画面クリア
	  e_put		; 敵表示
	  j_put		; 自機表示
	  s_put		; ショット表示
	  v_put		; バルカン表示
	  c_put		; 照準表示
	  scr_put	; スコア表示

	  pos wx/2-43,wy/2+50 : mes "GAME OVER"
	 redraw 1

	 await 1000/15 ; ウエイト、FPS 15
	loop

	reset ; ゲーム再初期化

	return


;syoki.hsp

*syoki ; 初期設定

	randomize	; 乱数の初期化

	pai=3.141593
	pai2=pai*2

	rad45=0.7853982		; ラジアンで45度
	rad90=1.5707965		; ラジアンで90度


	wx=640	; 画面の大きさx
	wy=360	; 画面の大きさy

	wx1=70			; サブウエポン表示左エリア
	wx2=wx-wx1		; サブウエポン表示右エリア
	wxn=wx-wx1-wx2	; ゲームエリア
	wy1=wy/2

	gmode 2

	jw1=1 : jo=20 : jo2=jo/2	; 自機、マニュアル
	 celload "jiki_3.png",jw1
	  celdiv jw1,jo,jo,jo2,jo2

	jw2=2						; 自機、オート
	 celload "jiki_2.png",jw2
	  celdiv jw2,jo,jo,jo2,jo2

	sw=3 : so=6 : so2=so/2		; ショット
	 celload "shot_1.png",sw
	  celdiv sw,so,so,so2,so2

	e1w=4 : e1o=20 : e1o2=e1o/2	; 敵1
	 celload "ene_1.png",e1w
	  celdiv e1w,e1o,e1o,e1o2,e1o2

	e2w=5 : e2o=24 : e2o2=e2o/2	; 敵2
	 celload "ene_2.png",e2w
	  celdiv e2w,e2o,e2o,e2o2,e2o2

	e3w=6 : e3o=64 : e3o2=e3o/2	; 敵3
	 celload "ene_3.png",e3w
	  celdiv e3w,e3o,e3o,e3o2,e3o2

	cw=7 : co=32 : co2=co/2		; カーソル
	 celload "csr_2.png",cw
	  celdiv cw,co,co,co2,co2

	hw=8 : ho=16 : ho2=ho/2		; ヒット
	 celload "hit_4.png",hw
	  celdiv hw,ho,ho,ho2,ho2

	vw=9 : vo=16 : vo2=vo/2		; バルカン
	 celload "vulcan_1.png",vw
	  celdiv vw,vo,vo,vo2,vo2

	lw=10 : lo=64 : lo2=lo/2	; レーザー
	 celload "laser.png",lw
	  celdiv lw,lo,lo,lo2,lo2

	ww=11 : wox=wx1 : woy=wy1	; 枠
	 celload "waku_4.png",ww
	  celdiv ww


; 自機 ----------
	jx=wx1+(wx-wx1)/2	; プレイヤーの座標x
	jy=wy/2	; プレイヤーの座標y

	jx1=jx-jo2 ; 自機左座標
	jx2=jx+jo2 ; 自機右座標
	jy1=jy-jo2 ; 自機上座標
	jy2=jy+jo2 ; 自機下座標

	cx=double(jx) ; 照準座標x
	cy=double(jy) ; 照準座標y
	csp=20.0	  ; 照準スピード
	esn=0		  ; 標的

	autof=1	; オートフラグ(0=マニュアル、1=オート)

dim pn,40
; SHOT ----------

	sb=20			; ショット最大数
	 dim sf,sb		; ショット発射フラグ
	 ddim sx,sb		; ショット座標x
	 ddim sy,sb		; ショット座標y
	 ddim sdx,sb	; ショット移動量x
	 ddim sdy,sb	; ショット移動量y
	 ddim sr,sb		; 向き

	 dim sxb,sb		; 終点座標x
	 dim syb,sb		; 終点座標y
	 ddim skn,sb	; 現移動距離
	 ddim skb,sb	; 最終移動距離

	ssp=60.0		; スピード
	sp=6			; パワー
	su=32			; 揺れ幅(集弾値)


; VULCAN ----------

	vb=30			; バルカン最大数
	 dim vf,vb		; バルカン発射フラグ
	 ddim vx,vb		; バルカン座標x
	 ddim vy,vb		; バルカン座標y
	 ddim vdx,vb	; バルカン移動量x
	 ddim vdy,vb	; バルカン移動量y
	 ddim vr,vb		; 向き

	vkc=3			; 1フレームに出現する数
	vsp=60.0;20.0		; スピード
	vp=5			; パワー
	vu=30			; 揺れ幅(集弾値)
	vnb=140			; 1クリックで発射される数
	vc=0			; 残弾数
	vcb=800			; 最大数
	vck=10			; 1つ敵を倒した時に増える数


; LASER ----------

	lf=0		; レーザー発射フラグ
	lx1=0.0		; レーザー始点座標x
	ly1=0.0		; レーザー始点座標y
	lx2=0.0		; レーザー終点座標x
	ly2=0.0		; レーザー終点座標y
	lxs=0.0		; 目標地点x
	lys=0.0		; 目標地点y
	ldx=0.0		; レーザー移動量x
	ldy=0.0		; レーザー移動量y
	lr=0.0		; 向き

	lsp=30.0	; スピード
	lp=10		; パワー
	le=0		; エネルギー
	leb=80		; 1回撃つのに必要なエネルギー
	
	lpb=120		; レーザーエネルギーの残量表示の長さ
	lpf=double(lpb)/double(leb) ; エネルギー1の表示長さ

	;lc=0		; 発射時間
	;lcb=80		; 発射時間最大

	lopx=1.0	; 表示幅x
	lopy=0.5	; 表示幅y


; ENEMY ----------
	eb=40			; 敵最大数
	 dim ef,eb		; 出現フラグ
	 dim ehp,eb		; 耐久度
	 dim eaf,eb		; 当たってるフラグ
	 ddim ex,eb		; 敵座標x
	 ddim ey,eb		; 敵座標y
	 ddim edx,eb	; 敵移動量x
	 ddim edy,eb	; 敵移動量y
	 ddim er,eb		; 向き

	dim escr,4		; スコア

	e1hpb=24		; 耐久度
	e1sp=1.0		; 敵1スピード
	e1c=0			; 出現カウント
	e1cb=10			; 出現間隔(フレーム)
	escr(1)=10		; スコア

	e2hpb=300		; 耐久度
	e2sp=0.5		; 敵2スピード
	e2c=50			; 出現カウント
	e2cb=70			; 出現間隔(フレーム)
	escr(2)=100		; スコア

	e3hpb=5000		; 耐久度
	e3sp=0.1		; 敵2スピード
	e3c=300			; 出現カウント
	e3cb=300		; 出現間隔(フレーム)
	escr(3)=2000	; スコア


	scr=0		; スコア
	hiscr=0		; ハイスコア

	kf=0		; キーを押してるかフラグ
	kc=0		; 何フレームキーを押してるか

	return


#deffunc reset ; ゲーム再初期化

	cx=double(jx) ; 照準座標xリセット
	cy=double(jy) ; 照準座標yリセット

    repeat sb : sf(cnt)=0 : loop ; ショットリセット
	repeat vb : vf(cnt)=0 : loop ; バルカンリセット
	 vcn=0 : vc=0 ; 残弾リセット
	le=0 ; レーザーエネルギーリセット

	repeat eb : ef(cnt)=0 : loop ; 敵リセット

	scr=0 ; スコアリセット
	esn=0 ; 標的リセット

	return


; sgot.hsp 
; ショット --------------------

#deffunc esn_set int esn_setf ; 標的設定

	esn=0		; 一番近い敵No.
	nd1=1000.0	; 一番近い距離

	repeat eb
	 if ef(cnt)=0 : continue

	 if esn_setf=0 : x2=ex(cnt)-jx : y2=ey(cnt)-jy ; 自機に近い
	 if esn_setf=1 : x2=ex(cnt)-cx : y2=ey(cnt)-cy ; 照準に近い

	  nd2=sqrt(x2*x2+y2*y2); 距離

	 if nd2<nd1 : nd1=nd2 : esn=cnt
	loop

	return


; SHOT --------------------
#deffunc s_set ; 出現

	f=0 ; 空きフラグ確認 ----------
	repeat sb : sn=cnt ; ショットNo.
	 if sf(sn)=0 : sf(sn)=1 : f=1 : break ; 使用フラグon
	loop
	if f=0 : return ; 空きが無い


	sx(sn)=double(jx) : sy(sn)=double(jy) ; 初期座標

	xx=int(cx)-su/2+rnd(su) ; ショットの着弾点x
	yy=int(cy)-su/2+rnd(su) ; ショットの着弾点y

	xn=double(xx-jx)		; 自機とマウスの距離x
	yn=double(yy-jy)		; 自機とマウスの距離y

	rad=atan(yn,xn)			; 距離xyから角度を求める

	sr(sn)=rad				; 向き

	sdx(sn)=cos(rad)*ssp	; 角度とスピードから移動量xを求める
	sdy(sn)=sin(rad)*ssp	; 角度とスピードから移動量yを求める


	sxb(sn)=xx : syb(sn)=yy	; 終点座標

	skn(sn)=0.0					; 現移動距離をリセット
	skb(sn)=sqrt(xn*xn+yn*yn)	; 最終移動距離

	return


#deffunc s_syo ; 移動処理

	repeat sb : sn=cnt ; ショット移動処理
	 if sf(sn)=0 : continue ; 無し

	 sx1=sx(sn) ; 始点座標x
	 sy1=sy(sn) ; 始点座標y

	 sx(sn)+=sdx(sn) ; xの移動
	 sy(sn)+=sdy(sn) ; yの移動

	 skn(sn)+=ssp ; どれだけ距離を進んだか
	  if skn(sn)>=skb(sn) { ; 終点判定
	   sx(sn)=double(sxb(sn))
	   sy(sn)=double(syb(sn))
	   sf(sn)=-1 ; 着弾フラグ
	  }

	 sx2=sx(sn) ; 終点座標x
	 sy2=sy(sn) ; 終点座標y

	 sln=sqrt((sx2-sx1)*(sx2-sx1)+(sy2-sy1)*(sy2-sy1)) ; 線の長さ


 ; 敵との当たり判定
	 repeat eb : en=cnt ; 敵No,
	  if ef(en)=0 : continue

;dbg_put
	 if ef(en)=1 : eo2=e1o2			; 敵1の時の大きさ
	 if ef(en)=2 : eo2=e2o2*12/10	; 敵2の時の大きさ
	 if ef(en)=3 : eo2=e3o2 		; 敵3の時の大きさ
	  eo2+=so2 ; 敵の半径にショットの半径を足す

	  f=0
	  repeat 1 ; 当たり判定

; 両端判定
	   if (ex(en)-sx2)*(ex(en)-sx2)+(ey(en)-sy2)*(ey(en)-sy2)<=(eo2*eo2) : f=1 : break ; 終点と敵の当たり判定
	   if (ex(en)-sx1)*(ex(en)-sx1)+(ey(en)-sy1)*(ey(en)-sy1)<=(eo2*eo2) : f=1 : break ; 始点と敵の当たり判定


; ショット軌道と敵との当たり判定

	   sxn=ex(en)-sx1	; 敵x-始点x
	   syn=ey(en)-sy1	; 敵y-始点y

	   cosf=cos(-sr(sn)) ; 角度修正、垂直に
	   sinf=sin(-sr(sn)) ; 角度修正、素直に

	   xf=cosf*sxn-sinf*syn ; 垂直位置に修正した敵のx
	   yf=sinf*sxn+cosf*syn ; 垂直位置に修正した敵のy

	   if abs(yf)<=eo2 and 0<=xf and xf<=sln : f=1 ; 当たり判定
	  loop


; 当たり処理

	  if f=1 {
	   sf(sn)=-1				; 着弾フラグ
	   eaf(en)=1				; 被弾フラグ
	   ehp(en)-=sp				; 耐久度-
	   if ehp(en)<=0 {			; 倒したか
	    scr+=escr(ef(en))		; スコア
	     if hiscr<scr : hiscr=scr ; ハイスコアの更新

	    ef(en)=0				; 敵を消す
	     if en=esn : esn_set 0	; 次の標的を探す
	    vc+=vck					; バルカンの残弾数を増やす
	     if vc>vcb : vc=vcb		; 最大数
	   }
	  }
	 loop

	 if sf(sn)=1 : if sx1<0 or wx<sx1 or sy1<0 or wy<sy1 : sf(sn)=0 : continue ; 場外でフラグ off
	loop

	return



; VULCAN --------------------
#deffunc v_set ; 出現

	repeat vkc : cnt2=cnt ; 1フレームに発射される数
	 if vcn=0 or vc=0 : break ; 発射要求数、または残弾が0

	 f=0 ; 空きフラグ確認 ----------
	 repeat vb : vn=cnt ; ショットNo.
	  if vf(vn)=0 : vf(vn)=1 : f=1 : break ; 使用フラグon
	 loop
	 if f=0 : break ; 空きが無い

	 vcn- ; 発射要求数-
	 vc- : if vc=0 : vcn=0 ; 残弾-

	 vf(vn)=1 ; 使用フラグon
	 vx(vn)=double(jx) : vy(vn)=double(jy) ; 初期座標


	 xn=cx-double(jx)		; 自機とマウスの距離x
	 yn=cy-double(jy)		; 自機とマウスの距離y

	 rd=double(-(vu/2)+rnd(vu+1))/100.0 ; 揺れ幅(ラジアン)
	  rad=atan(yn,xn)+rd	; 距離xyから角度を求める

	 vr(vn)=rad			; 向き

	 vdx(vn)=cos(rad)*vsp	; 角度とスピードから移動量xを求める
	 vdy(vn)=sin(rad)*vsp	; 角度とスピードから移動量yを求める

	 repeat cnt2
	  vx(vn)-=vdx(vn)/3.0 ; 始点座標をバックさせておくx
	  vy(vn)-=vdy(vn)/3.0 ; 始点座標をバックさせておくy
	 loop

	loop

	return


#deffunc v_syo

	repeat vb : vn=cnt ; バルカン移動処理
	 if vf(vn)=0 : continue ; 無し

	 vx1=vx(vn) ; バルカン始点座標x
	 vy1=vy(vn) ; バルカン始点座標y

	 vx(vn)+=vdx(vn) ; xの移動
	 vy(vn)+=vdy(vn) ; yの移動

	 vx2=vx(vn) ; バルカン終点座標x
	 vy2=vy(vn) ; バルカン終点座標y

	 vln=sqrt((vx2-vx1)*(vx2-vx1)+(vy2-vy1)*(vy2-vy1)) ; 線の長さ


	 repeat eb : en=cnt ; 敵との当たり判定
	  if ef(en)=0 : continue

	 if ef(en)=1 : eo2=e1o2			; 敵1の時の大きさ
	 if ef(en)=2 : eo2=e2o2*12/10	; 敵2の時の大きさ
	 if ef(en)=3 : eo2=e3o2 		; 敵3の時の大きさ
	  eo2+=3 ; 敵の半径にバルカンの半径を足す

	  f=0
	  repeat 1 ; 当たり判定
; 両端判定
	   if (ex(en)-vx2)*(ex(en)-vx2)+(ey(en)-vy2)*(ey(en)-vy2)<=(eo2*eo2) : f=1 : break ; 終点と敵の当たり判定
	   if (ex(en)-vx1)*(ex(en)-vx1)+(ey(en)-vy1)*(ey(en)-vy1)<=(eo2*eo2) : f=1 : break ; 始点と敵の当たり判定


; バルカン軌道と敵との当たり判定

	   vxn=ex(en)-vx1		; 敵x-始点x
	   vyn=ey(en)-vy1		; 敵y-始点y

	   cosf=cos(-vr(vn))	; 角度修正、垂直に
	   sinf=sin(-vr(vn))	; 角度修正、素直に

	   xf=cosf*vxn-sinf*vyn ; 垂直位置に修正した敵のx
	   yf=sinf*vxn+cosf*vyn ; 垂直位置に修正した敵のy

	   if abs(yf)<=eo2 and 0<=xf and xf<=vln : f=1 ; 当たり判定
	  loop


; 当たり処理

	  if f=1 {
	   eaf(en)=1				; 被弾フラグ
	  ;vf(vn)=-1				; 着弾フラグ
	   ehp(en)-=vp				; 耐久度-
	   if ehp(en)<=0 {			; 倒したか
	    scr+=escr(ef(en))		; スコア
	     if hiscr<scr : hiscr=scr ; ハイスコアの更新

	    ef(en)=0				; 敵を消す
	    if en=esn : esn_set 0	; 次の標的を探す
	   }
	  }

	 loop

	 if vf(vn)=1 : if vx1<0 or wx<vx1 or vy1<0 or wy<vy1 : vf(vn)=0 : continue ; 場外でフラグ off
	loop

	return


; LASER --------------------
#deffunc l_set ; 出現

	if lf!1 : return ; 発射要求されてない

	if le<leb : lf=0 : return ; エネルギーが無い

	lf=2 : ;le-=leb		; 発射


	lx1=double(jx) : ly1=double(jy) ; 始点座標
	lx2=lx1 : ly2=ly1	; 終点座標

	xn=lxs-lx1			; 自機と目標地点の距離x
	yn=lys-ly1			; 自機と目標地点の距離y

	lr=atan(yn,xn)		; 距離xyから角度を求める

	ldx=cos(lr)*lsp		; 角度とスピードから移動量xを求める
	ldy=sin(lr)*lsp		; 角度とスピードから移動量yを求める

	return


#deffunc l_syo

	if lf<2 or lf=5 {
	 if le<leb : le+ ; エネルギー蓄積
	}

	if lf=2 or lf=3 : le- ; エネルギー消費

	if lf<2 : return ; 発射されてない


; レーザー移動処理

	switch lf
	 case 2 ; 先頭が伸びる
	  lx2+=ldx ; レーザー終点座標x
	  ly2+=ldy ; レーザー終点座標y

	  if lx2<-20 or wx+20<lx2 or ly2<-20 or wy+20<ly2 : lf=3 ; 先頭が画面外
	 swbreak

	 case 3 ; 伸びきってる
	 ;if lc>lcb : lf=4 ; 発射時間を過ぎた
	  if le=0 : lf=4 ; エネルギー切れ
	 swbreak

	 case 4 ; 後尾が縮む
	  lx1+=ldx ; レーザー終点座標x
	  ly1+=ldy ; レーザー終点座標y

	  if lx1<-20 or wx+20<lx1 or ly1<-20 or wy+20<ly1 : lf=5 : lc=0 ; 後尾が画面外
	 swbreak
	 case 5 ; ウエイト
	  lc+ : if lc>20 : lf=0
	 swbreak
	swend

	lln=sqrt((lx2-lx1)*(lx2-lx1)+(ly2-ly1)*(ly2-ly1)) ; 線の長さ


	repeat eb : en=cnt ; 敵との当たり判定
	 if ef(en)=0 : continue

	 if ef(en)=1 : eo2=e1o2			; 敵1の時の大きさ
	 if ef(en)=2 : eo2=e2o2*12/10	; 敵2の時の大きさ
	 if ef(en)=3 : eo2=e3o2 		; 敵3の時の大きさ

	 eo2+=int(double(lo2)*lopx)		; 敵の半径にレーザーの半径を足す

	 f=0
	 repeat 1 ; 当たり判定
; 両端判定
	  if (ex(en)-lx2)*(ex(en)-lx2)+(ey(en)-ly2)*(ey(en)-ly2)<=(eo2*eo2) : f=1 ;: break ; 終点と敵の当たり判定
	  if (ex(en)-lx1)*(ex(en)-lx1)+(ey(en)-ly1)*(ey(en)-ly1)<=(eo2*eo2) : f=1 ;: break ; 始点と敵の当たり判定


; レーザー軌道と敵との当たり判定

	  lxn=ex(en)-lx1		; 敵x-始点x
	  lyn=ey(en)-ly1		; 敵y-始点y

	  cosf=cos(-lr)			; 角度修正、垂直に
	  sinf=sin(-lr)			; 角度修正、素直に

	  xf=cosf*lxn-sinf*lyn ; 垂直位置に修正した敵のx
	  yf=sinf*lxn+cosf*lyn ; 垂直位置に修正した敵のy

	  if abs(yf)<=eo2 and 0<=xf and xf<=lln : f=1 ; 当たり判定
	 loop


; 当たり処理

	 repeat 1
	  if f=0 : break

	  eaf(en)=1					; 被弾フラグ

	  dn=eo2-abs(int(yf))		; 照射面積によるダメージ
	   if ef(en)=1 : if dn>e1o : dn=e1o ; 大きさによる最大ダメージ
	   if ef(en)=2 : if dn>e2o : dn=e2o
	   if ef(en)=3 : if dn>e3o : dn=e3o

	  ehp(en)-=dn				; 耐久度-
	   if ehp(en)>0 : break		; 倒したか

	  scr+=escr(ef(en))			; スコア
	   if hiscr<scr : hiscr=scr	; ハイスコアの更新

	  ef(en)=0					; 敵を消す
	   if en=esn : esn_set 0	; 次の標的を探す
	 loop

	loop

	return


; ene.hsp
; ENEMY --------------------

#deffunc e1_set ; 出現

	if e1c>0 : e1c- : return ; ウエイト中

	 e1c=e1cb ; 出現ウエイトリセット


	f=0 ; 空きフラグ確認 ----------
	repeat eb : en=cnt ; 敵No.
	 if ef(en)=0 : ef(en)=1 : f=1 : break ; 使用フラグon
	loop
	if f=0 : return ; 空きが無い


	ehp(en)=e1hpb ; 耐久力


	r=rnd(4) ; 出現方向
	 if r=0 : exs=wx1+rnd(wx-wx1)-e1o2 : eys=0-e1o2		; 上
	 if r=1 : exs=wx1+rnd(wx-wx1)-e1o2 : eys=wy+e1o2	; 下
	 if r=2 : exs=wx1-e1o2 : eys=rnd(wy)-e1o2	; 左
	 if r=3 : exs=wx+e1o2  : eys=rnd(wy)-e1o2	; 右

	ex(en)=double(exs)	; 初期位置x
	ey(en)=double(eys)	; 初期位置y

	xn=double(jx-exs)	; 敵と自機の距離x
	yn=double(jy-eys)	; 敵と自機の距離y

	rad=atan(xn,yn) 	; 距離xyから角度を求める

	edx(en)=sin(rad)*e1sp	; 角度とスピードから移動量xを求める
	edy(en)=cos(rad)*e1sp	; 角度とスピードから移動量yを求める

	er(en)=-rad+pai	; 向き

	return


#deffunc e2_set ; 出現

	if e2c>0 : e2c- : return ; ウエイト中

	 e2c=e2cb ; 出現ウエイトリセット


	f=0 ; 空きフラグ確認 ----------
	repeat eb : en=cnt ; 敵No.
	 if ef(en)=0 : ef(en)=2 : f=1 : break ; 使用フラグon
	loop
	if f=0 : return ; 空きが無い


	ehp(en)=e2hpb ; 耐久力


	r=rnd(4) ; 出現方向
	 if r=0 : exs=wx1+rnd(wx-wx1)-e2o2 : eys=0-e2o2		; 上
	 if r=1 : exs=wx1+rnd(wx-wx1)-e2o2 : eys=wy+e2o2	; 下
	 if r=2 : exs=wx1-e2o2 : eys=rnd(wy)-e2o2	; 左
	 if r=3 : exs=wx+e2o2  : eys=rnd(wy)-e2o2	; 右

	ex(en)=double(exs)	; 初期位置x
	ey(en)=double(eys)	; 初期位置y

	xn=double(jx-exs)	; 敵と自機の距離x
	yn=double(jy-eys)	; 敵と自機の距離y

	rad=atan(xn,yn) 	; 距離xyから角度を求める

	edx(en)=sin(rad)*e2sp	; 角度とスピードから移動量xを求める
	edy(en)=cos(rad)*e2sp	; 角度とスピードから移動量yを求める

	er(en)=-rad+pai	; 向き

	return


#deffunc e3_set ; 出現

	if e3c>0 : e3c- : return ; ウエイト中

	 e3c=e3cb ; 出現ウエイトリセット


	f=0 ; 空きフラグ確認 ----------
	repeat eb : en=cnt ; 敵No.
	 if ef(en)=0 : ef(en)=3 : f=1 : break ; 使用フラグon
	loop
	if f=0 : return ; 空きが無い


	ehp(en)=e3hpb ; 耐久力


	r=rnd(4) ; 出現方向
	 if r=0 : exs=wx1+rnd(wx-wx1)-e3o2 : eys=0-e3o2		; 上
	 if r=1 : exs=wx1+rnd(wx-wx1)-e3o2 : eys=wy+e3o2	; 下
	 if r=2 : exs=wx1-e3o2 : eys=rnd(wy)-e3o2	; 左
	 if r=3 : exs=wx+e3o2  : eys=rnd(wy)-e3o2	; 右

	ex(en)=double(exs)	; 初期位置x
	ey(en)=double(eys)	; 初期位置y

	xn=double(jx-exs)	; 敵と自機の距離x
	yn=double(jy-eys)	; 敵と自機の距離y

	rad=atan(xn,yn) 	; 距離xyから角度を求める

	edx(en)=sin(rad)*e3sp	; 角度とスピードから移動量xを求める
	edy(en)=cos(rad)*e3sp	; 角度とスピードから移動量yを求める

	er(en)=-rad+pai	; 向き

	return


#deffunc e1_syo ; 敵1移動処理

	ex(en)+=edx(en) : ey(en)+=edy(en) ; 移動

	ex1=int(ex(en))-e1o2 ; 敵左座標
	ex2=int(ex(en))+e1o2 ; 敵右座標
	ey1=int(ey(en))-e1o2 ; 敵上座標
	ey2=int(ey(en))+e1o2 ; 敵下座標

	if jx1<ex2 and ex1<jx2 and jy1<ey2 and ey1<jy2 {
	 mainf=2 : return ; 自機と当たりで GAME OVER
	}

	if ex2<0 or wx<ex1 or ey2<0 or wy<ey1 : ef(en)=0 ; 枠外でフラグ off

	return


#deffunc e2_syo ; 敵2移動処理

	ex(en)+=edx(en) : ey(en)+=edy(en) ; 移動

	ex1=int(ex(en))-e2o2 ; 敵左座標
	ex2=int(ex(en))+e2o2 ; 敵右座標
	ey1=int(ey(en))-e2o2 ; 敵上座標
	ey2=int(ey(en))+e2o2 ; 敵下座標

	if jx1<ex2 and ex1<jx2 and jy1<ey2 and ey1<jy2 {
	 mainf=2 : return ; 自機と当たりで GAME OVER
	}

	if ex2<0 or wx<ex1 or ey2<0 or wy<ey1 : ef(en)=0 ; 枠外でフラグ off

	return


#deffunc e3_syo ; 敵3移動処理

	ex(en)+=edx(en) : ey(en)+=edy(en) ; 移動

	ex1=int(ex(en))-e3o2 ; 敵左座標
	ex2=int(ex(en))+e3o2 ; 敵右座標
	ey1=int(ey(en))-e3o2 ; 敵上座標
	ey2=int(ey(en))+e3o2 ; 敵下座標

	if jx1<ex2 and ex1<jx2 and jy1<ey2 and ey1<jy2 {
	 mainf=2 : return ; 自機と当たりで GAME OVER
	}

	if ex2<0 or wx<ex1 or ey2<0 or wy<ey1 : ef(en)=0 ; 枠外でフラグ off

	return


#deffunc e_syo ; 敵移動処理テーブル

	repeat eb : en=cnt ; 敵No,
	 if ef(en)=0 : continue ; 無し

	 switch ef(en)
	  case 1 : e1_syo : swbreak ; 敵1移動処理
	  case 2 : e2_syo : swbreak ; 敵2移動処理
	  case 3 : e3_syo : swbreak ; 敵3移動処理
	 swend
	loop

	return


; put.hsp 表示

#deffunc clr ; 画面クリア

	color 1,1,1 : boxf : color 255,255,255

	return


#deffunc j_put ; 自機表示

	gmode 2

	pos jx,jy
	 if autof=0 : celput jw1 ; 自機、マニュアル
	 if autof=1 : celput jw2 ; 自機、オート

	return


#deffunc e_put ; 敵表示

	repeat eb ; 敵No.
	 if ef(cnt)=0 : continue ; 無い

	 pos ex(cnt),ey(cnt)
	  gmode 2
	   if ef(cnt)=1 : celput e1w,,,,er(cnt) ; 敵1
	   if ef(cnt)=2 : celput e2w,,,,er(cnt) ; 敵2
	   if ef(cnt)=3 : celput e3w,,,,er(cnt) ; 敵3


	 if eaf(cnt)=0 : continue ; 被弾してない

	 pos ex(cnt),ey(cnt)
	  gmode 5,,,255 ; 加算合成
	   if ef(cnt)=1 : celput e1w,,,,er(cnt) ; 敵1被弾
	   if ef(cnt)=2 : celput e2w,,,,er(cnt) ; 敵2被弾
	   if ef(cnt)=3 : celput e3w,,,,er(cnt) ; 敵3被弾

	 eaf(cnt)=0 ; 被弾をリセット
	loop

	return


#deffunc s_put ; ショット表示

	gmode 2

	repeat sb ; ショット
	 if sf(cnt)=0 : continue ; 無い
	 pos sx(cnt),sy(cnt)
	  if sf(cnt)=-1 : celput hw,,,,sr(cnt)+rad90 : sf(cnt)=0 : continue ; フラグリセット
	  celput sw,,,,sr(cnt)+rad90;sw ; ショット
	loop

	return


#deffunc v_put ; バルカン表示

	gmode 2

	repeat vb ; バルカン
	 if vf(cnt)=0 : continue ; 無い
	 pos vx(cnt),vy(cnt)
	  if vf(cnt)=-1 : celput hw,,,,vr(cnt) : vf(cnt)=0 : continue ; フラグリセット
	  celput vw,,,,vr(cnt)+rad90 ; バルカン
	loop

	return


#deffunc l_put ; レーザー表示

	if lf<2 or lf=5 : return ; 発射されてない


	lln=sqrt((lx2-lx1)*(lx2-lx1)+(ly2-ly1)*(ly2-ly1)) ; レーザーの長さ

	lx=lx1+cos(lr)*lln/2 ; 表示座標x、始点座標に半分の長さを進んだ中点座標
	ly=ly1+sin(lr)*lln/2 ; 表示座標y

	pos lx,ly

	gmode 5,,,255 ; 半透明加算表示
	 celput lw,,lopx,lln/lo,lr+rad90 ; レーザー

	return


#deffunc c_put ; 照準表示

	gmode 2

	pos cx,cy : celput cw ; 照準

	return


#deffunc scr_put ; スコア表示

	font "",20,1
	color 224,224,255
	pos wx-350,5 : mes "SCORE "+scr
	pos wx-190,5 : mes "HI SCORE "+hiscr

	return


#deffunc waku_put ; 枠表示

	if subf=1 : color 160,160,160 : boxf 0,120,45,240 : color 255,255,255

	repeat 2
	 gmode 2
	  pos 0,cnt*wy1 : celput ww

	 if cnt=2 or subf=0 : continue

	 gmode 5,,,96 ; 明るく表示
	  pos 0,wy1 : celput ww
	loop

; バルカン
	font "",18,0 : color 255,255,255

	pos 7,10 : mes "VULCAN"

	gmode 2

	n=vc/10
	repeat n ; バルカン残弾表示
	 pos 12+(cnt\10)*5,45+(cnt/10)*16 : celput vw
	loop

; レーザー
	pos 13,wy1+10 : mes "LASER"

	if le<leb : gmode 5,,,160 ; 充填中
	if le=leb : gmode 5,,,224 ; 満タン

	nf=(double(le)*lpf)*(1.0/double(lo)) ; 縦の表示倍率

	pos wx1/2,wy1+40+lpb/2 : celput lw,,0.8,nf ; レーザー充填表示

	return

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です