1MAP_STG ver.0.010 敵弾と防衛衛星を実装


2021年 6月 27日
 
 
 ver.0.010は敵弾と、それを防衛する防衛衛星を実装してみたいと思う。


 
 

1、敵弾

 難しい事は無く、敵1からランダムに自機に向かって発射される。

#deffunc t1_syu double _t1x,double _t1y ; 敵弾1出現

	txf=_t1x ; 初期座標x
	tyf=_t1y ; 初期座標y

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

	thp(tn)=t1hpb ; 耐久力

	tx(tn)=txf	; 初期位置x
	ty(tn)=tyf	; 初期位置y

	xnf=jxf-txf	; 敵と自機の距離x
	ynf=jyf-tyf	; 敵と自機の距離y

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

	tdx(tn)=sin(rad)*t1sp ; 角度とスピードから移動量xを求める
	tdy(tn)=cos(rad)*t1sp ; 角度とスピードから移動量yを求める

	return


#deffunc t1_syo ; 弾1移動処理

	tx(tn)+=tdx(tn) : ty(tn)+=tdy(tn) ; 移動

	repeat 1 ; 防御衛星の迎撃範囲内か
	 if jx-gdrln>tx(tn) : break ; 弾左迎撃距離
	 if jx+gdrln<tx(tn) : break ; 弾右迎撃距離
	 if jy-gdrln>ty(tn) : break ; 弾上迎撃距離
	 if jy+gdrln<ty(tn) : break ; 弾下迎撃距離

	 hx=jxf-tx(tn)			; 弾と自機の距離x
	 hy=jyf-ty(tn)			; 弾と自機の距離y

	 gdtln(tn)=(hx*hx)+(hy*hy) ; 直線距離
	  if gdtln(tn)>gdrln*gdrln : break	; 射程外

	 if gdtf(tn)=2 : break	; 既に防衛衛星の標的
	 gdtf(tn)=1			; 防衛射程内フラグ
	loop


; 当たり判定

	tx1=int(tx(tn))-t1o2 ; 弾左座標
	tx2=int(tx(tn))+t1o2 ; 弾右座標
	ty1=int(ty(tn))-t1o2 ; 弾上座標
	ty2=int(ty(tn))+t1o2 ; 弾下座標

	if jx1<tx2 and tx1<jx2 and jy1<ty2 and ty1<jy2 {
	 if gdtln(tn)<jo2*jo2 { ; 直線距離内
	  tf(tn)=0
	  gdtf(tn)=0 ; 標的の解除
	  jhp-=thp(tn)
	   if jhp<=0 : jhp=0 : mainf=2 : return ; 自機と当たりで GAME OVER
	 }
	}

	return

 
 
2、防衛衛星

 結構むずかしかった。

 敵弾が自機の防衛範囲内になると、敵弾を追尾して消してくれる。

 防衛衛星には耐久度があって、一定数敵弾を消すと無くなる。

 出現要件は要塞を倒す事。
 
 
 モード 1は自機の周りを所定軌道で回る、待機モード。

 軌道は、ずっと円周を動き続ける基準 radに、円を衛星数で割った値を、各衛星円周点分足し算する。

 つまり円 1周が 6.28(3.14の倍)になってるので、基準軌道点に、衛星 2個なら 3.14を、3個なら 2.9を衛星の No.分足す。

; GUARD_bit

	gdb=20 ; 最大数
	dim gdf,gdb+1	; フラグ
	dim gdhp,gdb+1	; 耐久度
	dim gdtar,gdb+1	; 追跡tn

	ddim gdx,gdb+1	; x
	ddim gdy,gdb+1	; y

	gdpc=0			; ラジアンNo,
	ddim gdr,gdb+1	; ラジアン
	ddim gdpx,gdb+1	; 所定位置x
	ddim gdpy,gdb+1	; 所定位置y

	gdhpb=5			; 最大耐久度
	 gdhpf=155.0/double(gdhpb)

	gdsp=5.0		; スピード
	gdsln=55.0		; 衛星の距離
	gdrln=155.0		; 迎撃距離

	gdc=0			; 個数
	gdrf=0.0		; 基準rad
	gdssp=0.07		; 周回スピード
	gdxf=cos(gdrf)*gdsln ; 基準位置x
	gdyf=sin(gdrf)*gdsln ; 基準位置y
	gdx2=0.0
	gdy2=0.0


; 防衛衛星 ----------

#deffunc gd_syu

	f=0
	repeat gdb,1
	 if gdf(cnt)>0 : continue
	 gdf(cnt)=1
	  gdx(cnt)=jxf : gdy(cnt)=jyf : gdhp(cnt)=gdhpb
	 f=1 : break
	loop
	if f=0 : return

	gdc+ ; 個数
	 gdrk=pai2/double(gdc) ; 間隔

	return


#deffunc gd_syo ; 防衛衛星の移動処理

; 基準軌道

	gdrf-=gdssp ; 基準rad
	 if gdrf>pai2 : gdrf-=pai2

	repeat gdc : nf=double(cnt)
	 gdr(cnt)=gdrf+nf*gdrk ; 所定位置x
	 gdpx(cnt)=jxf+cos(gdr(cnt))*gdsln ; 所定位置x
	 gdpy(cnt)=jyf+sin(gdr(cnt))*gdsln ; 所定位置y
	loop


; 目標座標

	gdpc=0
	repeat gdb,1 : gdn=cnt
	 if gdf(gdn)=0 : continue

	 if gdf(gdn)=1 { ; 標的無し
	  gdx2=gdpx(gdpc) ; 目標座標x
	  gdy2=gdpy(gdpc) ; 目標座標y
	 }

	 if gdf(gdn)=2 { ; 標的有り
	  gdx2=tx(gdtar(gdn)) ; 目標座標x
	  gdy2=ty(gdtar(gdn)) ; 目標座標y
	 }

	 gdpc+ ; 所定位置


; 移動計算

	 hx=gdx2-gdx(gdn)
	 hy=gdy2-gdy(gdn)
	 if (hx*hx)+(hy*hy)<=gdsp { ; 所定軌道に近い
	  gdx(gdn)=gdx2
	  gdy(gdn)=gdy2
	  if gdf(gdn)=2 { ; 防衛衛星処理
	   tf(gdtar(gdn))=0
	   gdtf(gdtar(gdn))=0
	   gdhp(gdn)- : if gdhp(gdn)>0 : gdf(gdn)=1 : continue
	   gdf(gdn)=0
	   gdc- ; 個数
	    if gdc>0 : gdrk=pai2/double(gdc) ; 間隔
	   continue
	  }
	  continue
	 }

	 xn=gdx2-gdx(gdn)		; 目標座標-現座標x
	 yn=gdy2-gdy(gdn)		; 目標座標-現座標y

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

	 gdx(gdn)+=cos(rad)*gdsp	; 角度とスピードから移動量xを求める
	 gdy(gdn)+=sin(rad)*gdsp	; 角度とスピードから移動量yを求める

	loop

	return

 
 
 モード 2は敵弾を追尾するモード。

 まず弾の移動処理時に自機との距離を格納しておきます。

gdtln(tn)=(hx*hx)+(hy*hy) ; 直線距離

 この時に敵弾が防衛衛星の迎撃距離内ならフラグ gdtf(tn)を 1にします。

 if gdtln(tn)>gdrln*gdrln : break ; 射程外
 if gdtf(tn)=2 : break ; 既に防衛衛星の標的
 gdtf(tn)=1 ; 防衛射程内フラグ

 フラグ 2は既に防衛衛星の標的になってる状態です。

 このフラグは弾の持つデータです。
 
 
 自機と弾との距離の近い順の順列を作ります。

#deffunc tj_per ; 弾と自機との近い順

	repeat tb : gdtp(cnt)=0 : loop ; リセット

	repeat tb,1 : tn1=cnt
	 if gdtf(tn1)=0 : continue

	 c=0
	 repeat tb,1 : tn2=gdtp(c)
	  if gdtp(c)=0 : gdtp(c)=tn1 : break ; 未登録

	  if gdtln(tn1)>gdtln(tn2) : c+ : continue
	  gdtp(c)=tn1 : tn1=tn2
	  c+
	 loop
	loop

	return

 gdtp(c)がその順列です。
 
 
 順列を基に防衛衛星の標的をセットします。

#deffunc gd_set ; 防衛衛星の標的セット

	repeat tb : tn=gdtp(cnt) ; 自機に近い順
	 if tn=0 : break			; 標的無し
	 if gdtf(tn)=2 : continue	; 標的済み

	 f=0
	 gdn1=0 : nf1=100000.0
	 repeat gdb,1 : gdn2=cnt
	  if gdf(gdn2)!1 : continue
	  f=1

	  hx=tx(tn)-gdx(gdn2)	; 弾と自機の距離x
	  hy=ty(tn)-gdy(gdn2)	; 弾と自機の距離y

	  nf2=(hx*hx)+(hy*hy)	; 直線距離
	  if nf2<nf1 : gdn1=gdn2 : nf1=nf2 : continue
	 loop
	 if f=0 : break	; 衛星が無い
	 gdf(gdn1)=2	; 追跡フラグ
	 gdtar(gdn1)=tn	; 追跡ターゲット
	 gdtf(tn)=2		; 標的フラグ
	loop

	return

 この時に標的の弾に一番近い衛星を選びます。

 gdtar(gdn1)が、その衛星が追跡する弾のNo.です。

 gdf(gdn1)は衛星のモードフラグで、0=衛星が無い、1=軌道周回モード、2=敵弾追跡モードです。

 gdtf(tn)は弾の持つデータです。

 
 
 色々ややこしいのですけど、フラグ管理が煩雑で、弾や衛星が消滅した時にフラグをきちんとリセットしないと挙動がおかしくなります。
 
 
3、自機に耐久度を設定する

 

 敵弾に一発当たっただけでは難しいので、自機に HPを設ける。
 
 
 弾が当たるとエネルギーが減るような表示にしてる。

 0になるとゲームオーバー。
 
 
 
1MAP_STG_ver.0.010.zipファイル
 1MAP_STG_ver.0.010

コメントを残す

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