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


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
1007
アイドル【hspdxfix.as】複数弾を当たり判定で、再発射すると座標がずれる6解決


アイドル

リンク

2020/10/7(Wed) 21:00:04|NO.91559

hspdxfix.asプラグインで作ったSTGゲームになります。
「経緯」「問題点」「仕様」を見るより、プログラムを実行したほうがわかりやすいと思います。
(画像が必要なのでダウンロードしてください)


 「経緯」
「複数敵弾が特定の座標に到着したとき再発射する」っていうのを作ろうとしておりますが、
座標に到着したら再発射っていう処理にしちゃうと、他の弾も「座標に到着したら」の条件に引っかかってしまうため、当たり判定で管理することにしました。

 「問題点」
敵弾が当たり判定にぶつかったときに再発射という処理で行うと、
再発射したときに敵弾の座標がずれてしまいます。
(同じ位置から発射して、同じ位置で当たり判定を行っている)

処理の仕方が悪いのか、作り方を変えたほうがいいのかアドバイスをよろしくお願いいたします。
画像で当たり判定を行っているので、画像を添付いたします。

 「画像」
https://ux.getuploader.com/UGI_55/download/53
パス:hsp

■仕様
・敵弾は以下の仕様である
 └下側:下に移動する
 └右側:右に移動する
 └上側:上に移動する
 └左側:左に移動する

・敵弾は4弾発射する
 └同じ方向に移動する弾が3グループある
 └真ん中に1グループ、真ん中と外側の間が2グループ、一番外側が3グループ

・敵弾は特定の座標に到着したら再発射する
(ソースでは、座標取得ではなく、当たり判定で行っている)

#include "hspogg.as";音のために入れる #include "hspdxfix.as" ;DXライブラリ使用 width ,,130,200 ;ウィンドウの位置 es_ini 3100,3100,360;スプライトの最大数、キャラクタ定義の最大数,周の精度(180*2) es_screen 640,480 ,0,0,1,1 es_window -13,-43, 640,480 ;スプライト表示エリア設定 es_area -36,-430, 600,498 ;スプライト有効エリア設定 ;自機が動ける範囲 ;--上-- es_size 383,3 es_pat 10, 0,0 es_set 10, 30,11, 10 ;--左-- es_size 3,450 es_pat 11, 0,0 es_set 11, 30,11, 11 ;--下-- es_size 383,3, 100 es_pat 12, 0,0 es_set 12, 30,460, 12 ;--右-- es_size 3,450 es_pat 13, 0,0 es_set 13, 411,11, 13 ;---ボス--- buffer 6 picload "reimu_質問用.bmp" es_buffer 6,,$00ff00,,1 ;札 es_size 13,15, 50 es_pat 1000, 14,0 ;結界 es_size 252,300, 100 es_pat 1600, 64,384 es_set 1600, 95,86, 1600 ;■■■当たり判定用■■■ ;---下--- ;真ん中下 es_size 112,6, 100 es_pat 1601, 134,598 es_set 1601, 165,300, 1601 ;2段目下 es_size 112,6, 100 es_pat 1602, 134,598 es_set 1602, 165,380, 1602 ;3段目下 es_size 112,6, 100 es_pat 1603, 134,598 es_set 1603, 165,472, 1603 ;---右--- ;真ん中右 /* es_size 6,134, 100 es_pat 1604, 240,464 */ gsel 0,1 ;赤弾の数 AK_MAX = 12 ;赤弾の最大数(12) dim REI_AK_f, AK_MAX ;フラグ dim REI_AK_x, AK_MAX ;X dim REI_AK_y, AK_MAX ;Y ;****************スペカ配置*************** ;下に移動 REI_AK_x = 177,205,230,252 ,177,205,230,252 ,177,205,230,252 REI_AK_y = 227,227,227,227 ,307,307,307,307 ,386,386,386,386 ;右に移動 ; REI_AK_x = 222,222,222,222 ,.... ; REI_AK_y = 183,218,254,289 ,.... ;************メインループ*************** *メイン es_cls es_draw ;*************カウンター**************** es_get REI_SP_pos0_y,1500,5 ;Y es_get REI_SP_pos3_y,1503,5 ;Y es_get REI_SP_pos5_y,1505,5 ;Y es_get REI_SP_pos8_y,1508,5 ;Y pos 500,80 : es_mes "REI_SP_pos0_y " + REI_SP_pos0_y pos 500,100 : es_mes "REI_SP_pos3_y " + REI_SP_pos3_y pos 500,120 : es_mes "REI_SP_pos5_y " + REI_SP_pos5_y pos 500,140 : es_mes "REI_SP_pos8_y " + REI_SP_pos8_y ;************gosub************ gosub *自機の移動 gosub *ボススペカ es_sync ;画面更新 await 16 goto *メイン ;**************自機の移動************* *自機の移動 stick key,15 ;キー取得 if key & 1 : JIKI_x = JIKI_x - JIKISpd ;←の移動 if key & 2 : JIKI_y = JIKI_y - JIKISpd ;↑の移動 if key & 4 : JIKI_x = JIKI_x + JIKISpd ;→の移動 if key & 8 : JIKI_y = JIKI_y + JIKISpd ;↓の移動 return ;**************ボススペカ************* *ボススペカ if REI_AK_c <= 310 : REI_AK_c += 1 ;赤札カウント repeat AK_MAX ;弾の最大数(12) if REI_AK_f(cnt) = 0 { ;二重のフラグ REI_AK_f(cnt) = 1 ;二重のフラグ es_exnew RI_SP_D, 1500,1511 es_set RI_SP_D, REI_AK_x(cnt),REI_AK_y(cnt), 1000 es_type RI_SP_D,32 es_apos RI_SP_D, 0,1 ;↓に移動 ;if cnt >= 13 : es_apos RI_SP_D, 1,0 ;→に移動 } loop ;下に移動 RI_SP_no = 1601 ;結界スプライト検索開始ナンバー repeat 3 es_check RI_SP_VS_KEKKAI ,RI_SP_no,32 if RI_SP_VS_KEKKAI != -1 { es_kill RI_SP_VS_KEKKAI ;スペカ【削除】 REI_AK_f(RI_SP_VS_KEKKAI-1500) = 0 ;二重のフラグ }RI_SP_no++ loop ;右に移動 /* RI_SP_no = 1604 ;結界スプライト検索開始ナンバー repeat 3 es_check RI_SP_VS_KEKKAI ,RI_SP_no,32 if RI_SP_VS_KEKKAI != -1 { es_kill RI_SP_VS_KEKKAI ;スペカ【削除】 REI_AK_f(RI_SP_VS_KEKKAI-1500) = 0 ;二重のフラグ }RI_SP_no++ loop */ return



この記事に返信する


アイドル

リンク

2020/10/8(Thu) 20:58:15|NO.91569

時間を入れて時間が経過したら実行ってすると座標がずれずにすみました。
しかし、当たり判定を使うと何故ずれるのかの原因がわかりませんね・・・

追加したところは「;---追加---」とコメントします。

#include "hspogg.as";音のために入れる #include "hspdxfix.as" ;DXライブラリ使用 width ,,130,200 ;ウィンドウの位置 es_ini 3100,3100,360;スプライトの最大数、キャラクタ定義の最大数,周の精度(180*2) es_screen 640,480 ,0,0,1,1 es_window -13,-43, 640,480 ;スプライト表示エリア設定 es_area -36,-430, 600,498 ;スプライト有効エリア設定 ;自機が動ける範囲 ;--上-- es_size 383,3 es_pat 10, 0,0 es_set 10, 30,11, 10 ;--左-- es_size 3,450 es_pat 11, 0,0 es_set 11, 30,11, 11 ;--下-- es_size 383,3, 100 es_pat 12, 0,0 es_set 12, 30,460, 12 ;--右-- es_size 3,450 es_pat 13, 0,0 es_set 13, 411,11, 13 ;---ボス--- buffer 6 picload "reimu_質問用.bmp" es_buffer 6,,$00ff00,,1 ;札 es_size 13,15, 50 es_pat 1000, 14,0 ;結界 es_size 252,300, 100 es_pat 1600, 64,384 es_set 1600, 95,86, 1600 ;■■■当たり判定用■■■ ;---下--- ;真ん中下 es_size 112,6, 100 es_pat 1601, 134,598 es_set 1601, 165,300, 1601 ;2段目下 es_size 112,6, 100 es_pat 1602, 134,598 es_set 1602, 165,380, 1602 ;3段目下 es_size 112,6, 100 es_pat 1603, 134,598 es_set 1603, 165,472, 1603 ;---右--- ;真ん中右 /* es_size 6,134, 100 es_pat 1604, 240,464 */ gsel 0,1 ;赤弾の数 AK_MAX = 12 ;赤弾の最大数(12) dim REI_AK_f, AK_MAX ;フラグ dim REI_AK_x, AK_MAX ;X dim REI_AK_y, AK_MAX ;Y ;****************スペカ配置*************** ;下に移動 REI_AK_x = 177,205,230,252 ,177,205,230,252 ,177,205,230,252 REI_AK_y = 227,227,227,227 ,307,307,307,307 ,386,386,386,386 ;右に移動 ; REI_AK_x = 222,222,222,222 ,.... ; REI_AK_y = 183,218,254,289 ,.... ;************メインループ*************** *メイン es_cls es_draw ;*************カウンター**************** es_get REI_SP_pos0_y,1500,5 ;Y es_get REI_SP_pos3_y,1503,5 ;Y es_get REI_SP_pos4_y,1504,5 ;Y es_get REI_SP_pos7_y,1507,5 ;Y pos 500,80 : es_mes "REI_SP_pos0_y " + REI_SP_pos0_y pos 500,100 : es_mes "REI_SP_pos3_y " + REI_SP_pos3_y pos 500,120 : es_mes "REI_SP_pos4_y " + REI_SP_pos4_y pos 500,140 : es_mes "REI_SP_pos7_y " + REI_SP_pos7_y pos 500,170 : es_mes "BOS_c " + BOS_c pos 500,190 : es_mes "REI_AK_c " + REI_AK_c ;************gosub************ gosub *自機の移動 gosub *ボススペカ es_sync ;画面更新 await 16 goto *メイン ;**************自機の移動************* *自機の移動 stick key,15 ;キー取得 if key & 1 : JIKI_x = JIKI_x - JIKISpd ;←の移動 if key & 2 : JIKI_y = JIKI_y - JIKISpd ;↑の移動 if key & 4 : JIKI_x = JIKI_x + JIKISpd ;→の移動 if key & 8 : JIKI_y = JIKI_y + JIKISpd ;↓の移動 return ;**************ボススペカ************* *ボススペカ REI_AK_c += 1 ;赤札カウント if REI_AK_c >= 50 : REI_AK_c = 0 ;リセット ;---追加--- if REI_AK_c >= BOS_c { repeat AK_MAX ;弾の最大数(12) if REI_AK_f(cnt) = 0 { ;二重のフラグ REI_AK_f(cnt) = 1 ;二重のフラグ es_exnew RI_SP_D, 1500,1511 es_set RI_SP_D, REI_AK_x(cnt),REI_AK_y(cnt), 1000 es_type RI_SP_D,32 es_apos RI_SP_D, 0,1 ;↓に移動 ;if cnt >= 13 : es_apos RI_SP_D, 1,0 ;→に移動 } loop } ;下に移動 RI_SP_no = 1601 ;結界スプライト検索開始ナンバー repeat 3 es_check RI_SP_VS_KEKKAI ,RI_SP_no,32 if RI_SP_VS_KEKKAI != -1 { es_kill RI_SP_VS_KEKKAI ;スペカ【削除】 REI_AK_f(RI_SP_VS_KEKKAI-1500) = 0 ;二重のフラグ ;---追加--- BOS_c = 40 ;次に発射されるカウント【代入】 }RI_SP_no++ loop ;右に移動 /* RI_SP_no = 1604 ;結界スプライト検索開始ナンバー repeat 3 es_check RI_SP_VS_KEKKAI ,RI_SP_no,32 if RI_SP_VS_KEKKAI != -1 { es_kill RI_SP_VS_KEKKAI ;スペカ【削除】 REI_AK_f(RI_SP_VS_KEKKAI-1500) = 0 ;二重のフラグ }RI_SP_no++ loop */ return



あらや

リンク

2020/10/10(Sat) 15:07:26|NO.91576

単純に1フレームに1つの弾(赤札)の接触判定しかしていないため、
ズレてしまうのかと思います。

詳しく説明させていただくと、
赤札を左から順に1〜4として

1回目に接触したフレームで赤札1だけが接触判定に引っかかり削除され次のフレームへ。
2回目のフレームで赤札1が再セットされ、赤札2が接触判定で削除。
3回目のフレームで赤札2が再セット、赤札3が削除。
4回目のフレームで赤札3が再セット、赤札4が削除。

こうしてフレームがズレた分
赤札の発射もズレが発生するので、
2回目のソースのように
時間をおいて最後の赤札が削除されるまで待てば
ズレは無くなります。

まあ、1フレームで結界に接触する赤札を全て接触判定すれば良いかと思います。

;下に移動 RI_SP_no = 1601 ;結界スプライト検索開始ナンバー repeat 3 repeat 4 ;結界に接触する可能性のある赤札を全て確認する es_check RI_SP_VS_KEKKAI ,RI_SP_no,32 if RI_SP_VS_KEKKAI != -1 { es_kill RI_SP_VS_KEKKAI ;スペカ【削除】 REI_AK_f(RI_SP_VS_KEKKAI-1500) = 0 ;二重のフラグ } loop RI_SP_no++ loop



あらや

リンク

2020/10/10(Sat) 15:15:20|NO.91577

おまけとして赤札の数を固定せず、
少し効率的にしたものも書いておきます。


;下に移動 RI_SP_no = 1601 ;結界スプライト検索開始ナンバー repeat 3 repeat ;結界に接触する可能性のある赤札を全て確認する(無限ループ版) es_check RI_SP_VS_KEKKAI ,RI_SP_no,32 if RI_SP_VS_KEKKAI != -1 { es_kill RI_SP_VS_KEKKAI ;スペカ【削除】 REI_AK_f(RI_SP_VS_KEKKAI-1500) = 0 ;二重のフラグ } else { break ;接触している赤札が無ければループを抜ける } loop RI_SP_no++ loop



アイドル

リンク

2020/10/11(Sun) 12:35:49|NO.91585

あらやさん、回答ありがとうございます。


あぁ〜そういうことか!!
弾が4つあるのにたいし3回しかループしてなかったことが原因でしたか・・・
これはやらかした。

elseによって抜けるのもいいですね。
どうしてもこういうのに弱いから助かりました。

1次元配列だと、配列のところで横に伸びすぎるので2次元配列で作り直しました。

#include "hspogg.as";音のために入れる #include "hspdxfix.as" ;DXライブラリ使用 width ,,130,200 ;ウィンドウの位置 es_ini 3100,3100,360;スプライトの最大数、キャラクタ定義の最大数,周の精度(180*2) es_screen 640,480 ,0,0,1,1 es_window -13,-43, 640,480 ;スプライト表示エリア設定 es_area -36,-430, 600,498 ;スプライト有効エリア設定 ;自機が動ける範囲 ;--上-- es_size 383,3 es_pat 10, 0,0 es_set 10, 30,11, 10 ;--左-- es_size 3,450 es_pat 11, 0,0 es_set 11, 30,11, 11 ;--下-- es_size 383,3, 100 es_pat 12, 0,0 es_set 12, 30,460, 12 ;--右-- es_size 3,450 es_pat 13, 0,0 es_set 13, 411,11, 13 ;---ボス--- buffer 6 picload "reimu_質問用.bmp" es_buffer 6,,$00ff00,,1 ;札 es_size 13,15, 50 es_pat 1000, 14,0 ;結界 es_size 252,300, 100 es_pat 1600, 64,384 es_set 1600, 95,86, 1600 ;■■■当たり判定用■■■ ;---下--- ;真ん中下 es_size 112,6, 100 es_pat 1601, 134,598 es_set 1601, 165,300, 1601 ;2段目下 es_size 112,6, 100 es_pat 1602, 134,598 es_set 1602, 165,380, 1602 ;3段目下 es_size 112,6, 100 es_pat 1603, 134,598 es_set 1603, 165,472, 1603 ;---上--- ;真ん中上 es_size 112,6, 100 es_pat 1604, 134,598 es_set 1604, 165,166, 1604 ;2段目上 es_size 112,6, 100 es_pat 1605, 134,598 es_set 1605, 165,86, 1605 ;3段目上 es_size 112,6, 100 es_pat 1606, 134,598 es_set 1606, 165,-7, 1606 ;---右--- es_size 6,134, 100 es_pat 1607, 240,464 es_set 1607, 271,166, 1607 ;2段目右 es_size 6,134, 100 es_pat 1608, 240,464 es_set 1608, 341,166, 1608 ;3段目右 es_size 6,134, 100 es_pat 1609, 240,464 es_set 1609, 420,166, 1609 ;---左--- es_size 6,134, 100 es_pat 1610, 240,464 es_set 1610, 165,166, 1610 ;2段目左 es_size 6,134, 100 es_pat 1611, 240,464 es_set 1611, 95,166, 1611 ;3段目左 es_size 6,134, 100 es_pat 1612, 240,464 es_set 1612, 16,166, 1612 gsel 0,1 ;赤弾の数 AK_MAX = 4 ;赤弾の最大数(4) AK_G_MAX = 12 ;グループ数 dim REI_AK_f, AK_MAX,AK_G_MAX ;フラグ dim REI_AK_x, AK_MAX,AK_G_MAX ;X dim REI_AK_y, AK_MAX,AK_G_MAX ;Y ;****************二重配置*************** ;下 REI_AK_x(0,0) = 177,205,230,252 REI_AK_y(0,0) = 227,227,227,227 REI_AK_x(0,1) = 177,205,230,252 REI_AK_y(0,1) = 307,307,307,307 REI_AK_x(0,2) = 177,205,230,252 REI_AK_y(0,2) = 386,386,386,386 ;上 REI_AK_x(0,3) = 177,205,230,252 REI_AK_y(0,3) = 230,230,230,230 REI_AK_x(0,4) = 177,205,230,252 REI_AK_y(0,4) = 150,150,150,150 REI_AK_x(0,5) = 177,205,230,252 REI_AK_y(0,5) = 70,70,70,70 ;右 REI_AK_x(0,6) = 205,205,205,205 REI_AK_y(0,6) = 183,218,254,289 REI_AK_x(0,7) = 275,275,275,275 REI_AK_y(0,7) = 183,218,254,289 REI_AK_x(0,8) = 345,345,345,345 REI_AK_y(0,8) = 183,218,254,289 ;左 REI_AK_x(0,9) = 225,225,225,225 REI_AK_y(0,9) = 183,218,254,289 REI_AK_x(0,10) = 155,155,155,155 REI_AK_y(0,10) = 183,218,254,289 REI_AK_x(0,11) = 85,85,85,85 REI_AK_y(0,11) = 183,218,254,289 ;************メインループ*************** *メイン es_cls es_draw ;*************カウンター**************** es_get REI_SP_pos0_y,1500,5 ;Y es_get REI_SP_pos3_y,1503,5 ;Y es_get REI_SP_pos4_y,1504,5 ;Y es_get REI_SP_pos7_y,1507,5 ;Y pos 500,80 : es_mes "REI_SP_pos0_y " + REI_SP_pos0_y pos 500,100 : es_mes "REI_SP_pos3_y " + REI_SP_pos3_y pos 500,120 : es_mes "REI_SP_pos4_y " + REI_SP_pos4_y pos 500,140 : es_mes "REI_SP_pos7_y " + REI_SP_pos7_y pos 500,170 : es_mes "BOS_c " + BOS_c pos 500,190 : es_mes "REI_AK_c " + REI_AK_c ;************gosub************ gosub *自機の移動 gosub *ボススペカ es_sync ;画面更新 await 16 goto *メイン ;**************自機の移動************* *自機の移動 stick key,15 ;キー取得 if key & 1 : JIKI_x = JIKI_x - JIKISpd ;←の移動 if key & 2 : JIKI_y = JIKI_y - JIKISpd ;↑の移動 if key & 4 : JIKI_x = JIKI_x + JIKISpd ;→の移動 if key & 8 : JIKI_y = JIKI_y + JIKISpd ;↓の移動 return ;**************ボススペカ************* *ボススペカ repeat AK_G_MAX ;グループ数(2) TEK_G = cnt repeat AK_MAX ;弾の最大数(4) if REI_AK_f(cnt,TEK_G) = 0 { ;二重のフラグ REI_AK_f(cnt,TEK_G) = 1 ;二重のフラグ es_exnew RI_SP_D, 1500,1547 es_set RI_SP_D, REI_AK_x(cnt,TEK_G),REI_AK_y(cnt,TEK_G), 1000 es_type RI_SP_D,32 es_apos RI_SP_D, 0,1 ;↓に移動 if TEK_G >= 3 : es_apos RI_SP_D, 0,-1 ;↑に移動 if TEK_G >= 6 : es_apos RI_SP_D, 1,0 ;→に移動 if TEK_G >= 9 : es_apos RI_SP_D, -1,0 ;←に移動 } loop loop ;---削除判定--- RI_SP_no = 1601 ;結界プライト検索開始ナンバー repeat 12 TEK_G = cnt repeat ;結界に接触する可能性のある赤札を全て確認する(無限ループ版) es_check RI_SP_VS_KEKKAI ,RI_SP_no,32 if RI_SP_VS_KEKKAI != -1 { es_kill RI_SP_VS_KEKKAI ;スペカ【削除】 REI_AK_f(cnt,TEK_G) = 0 ;二重のフラグ(下) } else { break ;接触している赤札が無ければループを抜ける } loop RI_SP_no++ loop return



あらや

リンク

2020/10/11(Sun) 13:07:24|NO.91586

>弾が4つあるのにたいし3回しかループしてなかったことが原因でしたか・・・
ん?微妙に誤解が……
3回のループは結界の数ですよね?

細かく言わなくても理解されていると思いますが、
弾が4つあるのに結界1つにつき弾1つ分しか接触判定していないのが原因でした。

もう解決されているので問題ないと思いますが
微妙な勘違いがバグの原因になったりするのでご注意ください。



アイドル

リンク

2020/10/11(Sun) 20:38:15|NO.91593

あらやさん、たびたびありがとうございます!

誤解を招くような書き方になってすいません(´Д`)
結界1個が弾1個にしか判定してなかったのは理解しています!
ご心配ありがとうございます!



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