|
|
|
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個にしか判定してなかったのは理解しています!
ご心配ありがとうございます!
|
|