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
