現在、東方STGを作ってます。
「食らいボム」システムを作ろうとして、その途中経過で困ったことになってしまいました。
(っというか原因がわからない)
※食らいボムとは
敵の弾に当たったとき、数秒間ボムを発動できる時間があります。
その数秒間のうちにボムを打てば死んだことになりません(残機は減らない)
逆に数秒間のうちにボムを打てなかった場合は、残機が減ります。
-------------------------------------------------------------
-----------------------------------------------------
screen 0,450,300 ;*****************情報****************** ;自機の座標 JIKI_x = 206 : JIKI_y = 230 KNI_MAX = 50 ;弾の最大数(50) dim KN_f,KNI_MAX ;弾のフラグ dim KN_x,KNI_MAX ;弾のX dim KN_y,KNI_MAX ;弾のY ;****************メインループ*********** *メイン redraw 0 : color : boxf ;****************カウンター************* color ,255 pos 20,20 : mes "弾のヒット数 " + KN_HIT pos 20,40 : mes "ミスカウント " + MISU_c pos 20,60 : mes "弾の動きを止める_F " + UG_STO_f pos 20,80 : mes "自機の動きを止める_F " + JIKI_STOP_f ;*************************************** gosub *自機の移動 gosub *弾の準備 gosub *弾VS自機 ;***************自機******************** ;自機表示 pos JIKI_x,JIKI_y : mes "□" ;低速表示 color 255,255 pos TE_x,TE_y : mes "#" ;弾表示 repeat KNI_MAX ;弾の最大数(50) color 255, pos KN_x(cnt),KN_y(cnt) : mes "●" loop ;*************低速移動****************** if JIKI_STOP_f = 0 { ;自機の動きを止めるフラグが「立ってたら実行」 JIKI_Spd = 4 ;自機スピード } redraw : await 15 goto *メイン ;****************弾の準備*************** *弾の準備 repeat KNI_MAX ;弾の最大数(50) if UG_STO_f = 0 { ;弾の動きを止めるフラグ KN_M = rnd(100) ;乱数 if KN_f(cnt) = 0 { ;フラグ KN_f(cnt) = 1 ;弾のフラグを「立てる」 KN_x(cnt) = KN_M ;乱数を入れる KN_y(cnt) = 0 ;Yの高さ } if KN_f(cnt) = 1 {;フラグが「立ってたら実行」 KN_x(cnt) += 0.02 * rnd(100);Xスピード KN_y(cnt) += 2;Yスピード } if KN_y(cnt) >= 390 { ;弾が下まで行ったら「実行」 KN_f(cnt) = 0 ;弾のフラグを「初期化」 } }loop return ;*************弾VS自機**************** *弾VS自機 repeat KNI_MAX ;弾の最大数(50) if KN_f(cnt) = 1 {;弾のフラグが「立ってたら実行」 if (TE_x < KN_x(cnt)+6) AND (TE_x+2 > KN_x(cnt)) AND (TE_y < KN_y(cnt)+6) AND (TE_y+2 > KN_y(cnt)){ // if (JIKI_x < KN_x(cnt)+6) AND (JIKI_x+2 > KN_x(cnt)) AND (JIKI_y < KN_y(cnt)+6) AND (JIKI_y+2 > KN_y(cnt)){ KN_HIT += 1 ;弾のヒット数 MISU_c++ ;ミスカウンター JIKI_Spd = 0 ;自機のスピードを「無くす」 JIKI_STOP_f = 1 ;自機の動きを止めるフラグを「立てる」 UG_STO_f = 1 ;弾の動きを止めるフラグを「立てる」 if MISU_c < 3 : await 100 ;ミスカウンターが「3未満」ならスローになる if MISU_c >= 3 { ;ミスカウンターが「3」以上だったら「実行」 MISU_c = 0 ;ミスカウンターを「初期化」 UG_STO_f = 0 ;弾の動きを止めるフラグを「初期化」 JIKI_STOP_f = 0 ;自機の動きを止めるフラグを「初期化」 JIKI_x = 256 : JIKI_y = 230 ;自機をスタート地点に「戻す」 } } }loop return ;**************自機の移動*************** *自機の移動 stick key,15 if key & 4 : JIKI_x + JIKI_Spd ;→の移動 if key & 1 : JIKI_x - JIKI_Spd ;←の移動 if key & 2 : JIKI_y - JIKI_Spd ;↑の移動 if key & 8 : JIKI_y + JIKI_Spd ;↓の移動 ;低速の位置 TE_x = JIKI_x+3 : TE_y = JIKI_y+2 return
●ソースの説明●
まずは、普通のSTG同様、弾とあたったら死にます。
大事な部分はその当たり判定の中身。
「MISU_c++」で弾に当たったカウントを数えます。
KN_HIT += 1 ;弾のヒット数 MISU_c++ ;ミスカウンター JIKI_Spd = 0 ;自機のスピードを「無くす」 JIKI_STOP_f = 1 ;自機の動きを止めるフラグを「立てる」 UG_STO_f = 1 ;弾の動きを止めるフラグを「立てる」
「JIKI_Spd = 0」は特に意味はありませんが、不具合がおきにくくするための保険です。
「JIKI_STOP_f = 1」で自機を動けなくさせます
(東方では小さい当たり判定があるので、動けると弾から抜けてしまう可能性があるため)
「UG_STO_f = 1」弾の動きを止めます。
(弾が動くと判定が2回発生するなどが考えられる)
「MISU_c」が3未満の時、ボムを打てば死なずにすむシステムにしてます。
if MISU_c < 3 : await 100 ;ミスカウンターが「3未満」ならスローになる if MISU_c >= 3 { ;ミスカウンターが「3」以上だったら「実行」 MISU_c = 0 ;ミスカウンターを「初期化」 UG_STO_f = 0 ;弾の動きを止めるフラグを「初期化」 JIKI_STOP_f = 0 ;自機の動きを止めるフラグを「初期化」 JIKI_x = 256 : JIKI_y = 230 ;自機をスタート地点に「戻す」 }
(ボム機能はこの不具合と関係ないので入れていません)
「MISU_c」が3以上の時、自機は死にます。死ぬときに情報をリセットします。
-------------------------------------------------------------------
■原因■
実行してして、左上からくる弾に何度か突っ込めば、
MISU_c = 3未満
UG_STO_f = 1
JIKI_STOP_f = 1
っという状態が発生します (このとき自機が動けなくなる)
それで、原因がわからなくって色々試した結果、
//if (JIKI_x < KN_x(cnt)+6) AND (JIKI_x+2 > KN_x(cnt)) AND (JIKI_y < KN_y(cnt)+6) AND (JIKI_y+2 > KN_y(cnt)){
↑このコメントアウトしているやつを解除して、
if (TE_x < KN_x(cnt)+6) AND (TE_x+2 > KN_x(cnt)) AND (TE_y < KN_y(cnt)+6) AND (TE_y+2 > KN_y(cnt)){
↑こっちをコメントアウトして実行すれば、何度弾にぶつかっても同じ現象は発生しませんでした。
当たり判定が原因か?というとそうでもないような気がします・・・多分。
多分どこか別のところが悪さしているような・・・う〜んこの・・・
ってなわけでちょっとわかりにくいかもしれませんが、アドバイス等あれば教えてほしいです><
ソースの改善余地もありまくると思うので、その指摘でもかまいません。
なお、私が理解出来ないソースだとしばらく返答に時間がかかってしまいますorz
それではよろしくお願いします。