HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0625
ついついSTGの「弾封じ」について5解決


ついつい

リンク

2014/6/25(Wed) 19:31:28|NO.62611

HSP3のHSPDXFIXでSTGを作っています。
STGでよくある、「敵が自機と近すぎると、敵弾を撃ってこなくなる」
いわゆる、”弾封じ”を再現したいと思っています。

「敵が敵弾を撃」、というサブルーチンとは別のところで、
自機と敵の距離を測って、近づきすぎたらフラグを立てる、ということを
しているのですが、ここで立てたフラグを、「敵が敵弾を撃つ」条件に
当てはめても、敵が1機なら正常に動くのですが、敵が複数登場すると
有効になりません。


dim tf : dim tfd ;範囲内の敵機を数えるための配列 dim tfx : dim tfy ;敵機座標の配列 dim teki_shot     ;弾封じ用の配列 ;ザコがランダムに出現する--------------------------------------- if jiki_st = 2{ ;自機が生存中なら tb = 20 ;敵スプライトの割り当て開始番号 s = 0 repeat ;くりかえし  es_find s, 0, tb, 59 ;Sに全てのtype値で検索した20から59までのスプライトNOを検索した結果を返すよ  if s < 0 : break ;0ならbreakで出る   tb = s + 1 ;次の検索をするため、Sに+1する es_get x, s, 3 ;xに検出したSのX座標を取得 es_get y, s, 5 ;yに検出したSのY座標を取得 if f \ 50 = 0 & y<600 & teki_shot = 1{ ;y座標が600以内,弾封じされてなければ es_exnew z, 2000, 3000 ;変数Z(敵弾)に1000から2000までのスプライトを設定  if z >= 0 { ;空きが在れば  es_set z, x+32, y+32, 500, 0 , 10 ;zはX,Y座標から敵弾[4]を射出  es_type z, 16 ;type値は16  es_aim z, myx+32, myy+32, rnd(50) + 110 ;zは自機座標を狙って飛んでくる動きをするよ  } } loop } return *tama_huuji;------------------ ;※敵機と自分の距離 if jiki_st >=1 { ;自機が復活中以上なら tf=0 ;変数[tf]を初期化 repeat ;繰り返し開始 es_find tf,8,tf:if tf=-1 : break;画面中の敵type値[8]の数探す if tf>=0 { ;画面内に敵がいたら es_get tfx,tf,3 ;[tfx]に、[tf]のX座標を取得する es_get tfy,tf,5 ;[tfy]に、[tf]のY座標を取得する es_dist tfd,tfx,tfy,myx+32,myy+32 ;[tfd]に固定小数で、距離が返ってくる emint tfde,tfd ;[tfde]に整数にした数字が入り if tfde <= 128 & tfde >= -128{ ;敵機と自機の距離[tfde]が[128]ドットの範囲内なら teki_shot = 0 ;敵ショットフラグを[0]撃たないにするよ } else { ;範囲外に出たら teki_shot = 1 ;敵ショットフラグを[1]撃つにするよ } tf+ ;次の敵機[tf]を探すためのtf+ loop ;repeatに戻れ } } return ;メインルーチンに戻る

コードの貼り付けはこんな感じでいいんでしょうか…?

結局、「敵スプライト」とは別に、「敵弾を発射するスプライト」、
「敵弾を発射しないスプライト」を別々に作成し、範囲内に入ったら
 es_chr で「敵弾を発射しないスプライト」に変える

といった、一見回りくどい?ような方法がベストなのかな、
と考えていますが…

なにかいい方法はありませんでしょうか?



この記事に返信する


kino

リンク

2014/6/25(Wed) 19:42:52|NO.62612

ちょっと気になったのですが
loop ;repeatに戻れ が
if tf>=0 文の{}の中にあるのですが いいんですか?



ミント

リンク

2014/6/25(Wed) 20:33:36|NO.62613

回答にならないかもしれないけど、敵の前に別の見えない物体をおいて、
その物体と自機と当たったらフラグを「1」にして、
フラグが「1」の場合、玉を出さないという処理をすればいいかな〜っと思った。

ただ、このやり方だと、敵と見えない物体で配列おかないといけないし、
当たり判定も2二重に用意しなきゃいけなかったりとよくない方法かもしれない。
今思いついたものなので。申し訳ない|彡サッ!



暇人

リンク

2014/6/25(Wed) 22:18:22|NO.62615

>if tf>=0 文の{}の中にあるのですが いいんですか?re>
後々なにか変更するときとか処理を把握するのに読み直す時に分かり難いけど
if tf=-1 : breakで先に抜けてるので
if tf>=0 {の方でloopから抜けることは無いので今は問題ないと言う・・・


本題
>敵が1機なら正常に動くのですが、敵が複数登場すると
> 有効になりません。
それは変数一つしか使ってないので当然そうなる
二つ目以降が全て結果を上書きしてるんだから

こう言う場合配列変数を使う
敵を発生させるときに
teki_shot(スプライトNo)=0
みたいにしてスプライトNoで配列を使用できるようにする

って、言うか、弾発射と距離判定の処理を別ける必要無い気がする・・・
発射時に判定すれば良いんじゃ?

repeat ;くりかえし es_find s, 0, tb, 59 ;Sに全てのtype値で検索した20から59までのスプライトNOを検索した結果を返すよ if s < 0 : break ;0ならbreakで出る tb = s + 1 ;次の検索をするため、Sに+1する es_get x, s, 3 ;xに検出したSのX座標を取得 es_get y, s, 5 ;yに検出したSのY座標を取得 if f \ 50 = 0 & y<600{ ;y座標が600以内,弾封じされてなければ es_get s,13,type if type=8 {//type値[8]なら自機との距離を確かめる es_dist tfd,x,y,myx,myy ;[tfd]に固定小数で、距離が返ってくる if tfd >= 32768 : continue //32768=128*256(距離128以上なら発射処理せずにループ) } es_exnew z, 2000, 3000 ;変数Z(敵弾)に1000から2000までのスプライトを設定 if z >= 0 { ;空きが在れば es_set z, x+32, y+32, 500, 0 , 10 ;zはX,Y座標から敵弾[4]を射出 es_type z, 16 ;type値は16 es_aim z, myx+32, myy+32, rnd(50) + 110 ;zは自機座標を狙って飛んでくる動きをするよ } } loop



暇人

リンク

2014/6/25(Wed) 22:50:23|NO.62616

あ、指定距離以内にしないとダメだった・・・
> if tfd >= 32768 : continue //32768=128*256(距離128以上なら発射処理せずにループ)
これを

if tfd <= 32768 : continue //32768=128*256(距離128以内なら発射処理せずにloop)
に修正



ついつい

リンク

2014/6/26(Thu) 00:57:52|NO.62617

みなさんお知恵ありがとうございます。

>(距離128以上なら発射処理せずにループ)

なるほど、「範囲内であるなら」という条件に囚われていました。
「範囲外なら、弾を撃つ」という事は、「範囲内なら、弾を撃たない」という
事と一緒ですものね。

continueの使い方も勉強になりました。
結局のところ、やはり弾を撃つ処理の中で簡潔させ、下記のようになりました。

*teki1_shot if jiki_st >= 0 { s = 0 ;検索開始は変数Sは0から repeat ;くりかえし es_find s, 8, s ;画面上のtype値[8](敵)を検索 if s = -1 : break ;画面内に敵が居ないならbreak es_get x, s, 3 ;xに検出した敵のX座標を取得 es_get y, s, 5 ;yに検出した敵のY座標を取得 if f \ 50 = 0 & y < 600 { ;y座標が600以内なら es_exnew z, 2000, 3000 ;変数Z(敵弾)に1000から2000までのスプライトを設定 es_dist tfd,x,y,myx,myy ;[tfd]に固定小数で、距離が返ってくる emint tfde,tfd ;[tfde]に[tfd]の固定小数を整数にした数字が入る if tfde >= 128 {;& tfde >= -128{;敵機と、自機の距離[128]ドットの範囲外なら if z >= 0 { ;空きが在れば es_set z, x+32, y+32, 500, 0 , 10;zはX,Y座標から敵弾[4]を射出 es_type z, 16 ;type値は16 es_aim z, myx+32, myy+32, rnd(50) + 110 ;zは自機座標を狙って飛んでくる動きをするよ } } } s+ loop } return

これで正常動作しました。ありがとうございました。



ONION software Copyright 1997-2018(c) All rights reserved.