|
 |
|
2019/10/11(Fri) 07:58:30|NO.88620
どうもこんにちは。
いつもどおりSTGのソースで悩んだところになります。
自機弾が敵とあたったらダメージを与えて、一定量を超えたら敵を倒せるソースを作ったのですが、
最初のてき「配列0」を倒すと他の敵を倒せなくなってしまいます。
まぁ、「配列0」を倒そうとすると色々不具合がおきるんですが・・・
1個1個、別処理するとうまくいくので、何かしら見落としていると思いますが、アドバイスなどお待ちしております。
■仕様■
・自機弾が敵とあたったらダメージを与える
・ダメージが一定量を超えたらその敵を倒せる
#include "hspdxfix.as" ;DXライブラリ使用
width ,,130,200 ;ウィンドウの位置
es_ini 640,5000,360 ;スプライトの最大数、キャラクタ定義の最大数,周の精度(180*2)
es_screen 640,480 ,0,0,1,1 ;スクリーン
es_window 0,0, 640,480 ;スプライト表示エリア設定
es_area -15,-50, 610,480 ;スプライト有効エリア設定
;---自機---
es_size 28,42, 100
es_pat 400, 0, 0
JIKI_x = 206 : JIKI_y = 390
JIKISpd = 4 ;自機のスピード(4)
;---自機弾---
es_size 11,11, 150
es_pat 51, 1,43
;---低速弾---
es_size 32,32, 100
es_pat 50, 13,43
;---敵---
es_size 50,38, 100
es_pat 70, 19,0
;自機弾
JKTM_MAX = 50 ;自機弾の最大数(50)
dim JKSO_f,JKTM_MAX ;フラグ
dim JKSO_x,JKTM_MAX ;X
dim JKSO_y,JKTM_MAX ;Y
;敵配置
TEKI_MAX = 5 ;敵の最大数
dim TEKI_f,TEKI_MAX
dim TEKI_x,TEKI_MAX
dim TEKI_y,TEKI_MAX
dim JKTM_HIT,TEKI_MAX ;敵HP
;▼▼▼▼▼▼▼敵配列▼▼▼▼▼▼▼
TEKI_x = 40,100,160,220,280 ;X
TEKI_y = 30,80,130,180,230 ;Y
;*********メインループ*********
*メイン
es_cls ;画面クリア
es_draw ;スプライト描画
pos 420,50 : es_mes "JKTM_HIT(0) " + JKTM_HIT(0)
pos 420,70 : es_mes "JKTM_HIT(1) " + JKTM_HIT(1)
pos 420,90 : es_mes "JKTM_HIT(2) " + JKTM_HIT(2)
pos 420,110 : es_mes "JKTM_HIT(3) " + JKTM_HIT(3)
pos 420,130 : es_mes "JKTM_HIT(4) " + JKTM_HIT(4)
pos 420,160 : es_mes "TEKI_f(0) " + TEKI_f(0)
pos 420,180 : es_mes "TEKI_f(1) " + TEKI_f(1)
pos 420,200 : es_mes "TEKI_f(2) " + TEKI_f(2)
pos 420,220 : es_mes "TEKI_f(3) " + TEKI_f(3)
pos 420,240 : es_mes "TEKI_f(4) " + TEKI_f(4)
pos 420,270 : es_mes "AI_SP_D " + AI_SP_D
;**************************************
gosub *自機の移動
gosub *自機弾移動
gosub *敵
es_set 400, JIKI_x,JIKI_y, 400 ;自機
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
;*************自機弾移動****************
*自機弾移動
getkey keyZ,90 ;Zキー
JK_TAMA_G_kazu = 0
if keyZ AND JKSO_f = 0 AND RENSA = 0 {
es_exnew JK_TAMA ,10,30 ;新規スプライト取得
;---弾の判断---
if JK_TAMA_c >= 1 {
JK_TAMA_dai_Kz = JK_TAMA_c \ 2
if JK_TAMA_dai_Kz = 0 : JK_TAMA_G_kazu += 1
}
JK_TAMA_c++ ;ループ内カウンター
if JK_TAMA_G_kazu = 0 : JKSO_x = JIKI_x-6 ;左側
if JK_TAMA_G_kazu = 1 : JKSO_x = JIKI_x+18 ;右側
JKSO_y = JIKI_y
es_set JK_TAMA, JKSO_x,JKSO_y, 51 ;スプライトNo, X,Y座標 ,キャラNo
es_apos JK_TAMA, 0,-15 ,100 ;↑に移動
RENSA = 2 ;弾の間隔
es_type JK_TAMA,2 ;自機弾type値(2)
}
if RENSA > 0 : RENSA -= 1 ;弾の間隔
return
;*************敵****************
*敵
repeat TEKI_MAX ;敵の最大数(5)
if TEKI_f(cnt) = 0 {
es_exnew TEKI, 250,254 ;新規スプライトNo
es_set TEKI, TEKI_x(cnt),TEKI_y(cnt), 70 ;スプライトNo, X,Y座標 ,キャラNo
es_type TEKI,4096
}
loop
;自機弾VS敵 当たり判定
TEKI_no = 250 ;敵の検索開始ナンバー
repeat TEKI_MAX ;敵の最大数(5)
es_check TEKI_VS_TAMA ,TEKI_no,2 ;自機弾スプライト10〜30
if TEKI_VS_TAMA != -1 {
TEKI_SP_D = TEKI_no - 250
JKTM_HIT(TEKI_SP_D)++
es_kill TEKI_VS_TAMA ;自機弾「削除」
if JKTM_HIT(TEKI_SP_D) >= 10 {;耐久力がなくなったら実行
es_kill TEKI_no ;敵「削除」
TEKI_f(TEKI_SP_D) = 1 ;敵のフラグを「立てる」
}
}TEKI_no++
loop
return

| |
|
2019/10/11(Fri) 15:14:38|NO.88624
サブルーチン先の*敵に、敵を生成する処理がありますけど、
これって最初に1度だけやればいいのではないでしょうか?
es_exnewの後にes_setを使っていますが、TEKIに-1が入った場合の処理が書かれていません。
試しにTEKIを配列にして確認すると、配列1に250が返ってきたりしています。色々な不具合の原因かと。
以下のようにすればうまくいくと思います。
#include "hspdxfix.as" ;DXライブラリ使用
width ,,130,200 ;ウィンドウの位置
es_ini 640,5000,360 ;スプライトの最大数、キャラクタ定義の最大数,周の精度(180*2)
es_screen 640,480 ,0,0,1,1 ;スクリーン
es_window 0,0, 640,480 ;スプライト表示エリア設定
es_area -15,-50, 610,480 ;スプライト有効エリア設定
;---自機---
es_size 28,42, 100
es_pat 400, 0, 0
JIKI_x = 206 : JIKI_y = 390
JIKISpd = 4 ;自機のスピード(4)
;---自機弾---
es_size 11,11, 150
es_pat 51, 1,43
;---低速弾---
es_size 32,32, 100
es_pat 50, 13,43
;---敵---
es_size 50,38, 100
es_pat 70, 19,0
;自機弾
JKTM_MAX = 50 ;自機弾の最大数(50)
dim JKSO_f,JKTM_MAX ;フラグ
dim JKSO_x,JKTM_MAX ;X
dim JKSO_y,JKTM_MAX ;Y
;敵配置
TEKI_MAX = 5 ;敵の最大数
dim TEKI_f,TEKI_MAX
dim TEKI_x,TEKI_MAX
dim TEKI_y,TEKI_MAX
dim JKTM_HIT,TEKI_MAX ;敵HP
;▼▼▼▼▼▼▼敵配列▼▼▼▼▼▼▼
TEKI_x = 40,100,160,220,280 ;X
TEKI_y = 30,80,130,180,230 ;Y
;敵生成をここに持ってくる。
repeat TEKI_MAX ;敵の最大数(5)
es_exnew TEKI, 250,254 ;新規スプライトNo。p3は250+TEKI_MAXにしないと敵を増やしたときに不具合に繋がるかも。
es_set TEKI, TEKI_x(cnt),TEKI_y(cnt), 70 ;スプライトNo, X,Y座標 ,キャラNo
es_type TEKI,4096
loop
;*********メインループ*********
*メイン
es_cls ;画面クリア
es_draw ;スプライト描画
pos 420,50 : es_mes "JKTM_HIT(0) " + JKTM_HIT(0)
pos 420,70 : es_mes "JKTM_HIT(1) " + JKTM_HIT(1)
pos 420,90 : es_mes "JKTM_HIT(2) " + JKTM_HIT(2)
pos 420,110 : es_mes "JKTM_HIT(3) " + JKTM_HIT(3)
pos 420,130 : es_mes "JKTM_HIT(4) " + JKTM_HIT(4)
pos 420,160 : es_mes "TEKI_f(0) " + TEKI_f(0)
pos 420,180 : es_mes "TEKI_f(1) " + TEKI_f(1)
pos 420,200 : es_mes "TEKI_f(2) " + TEKI_f(2)
pos 420,220 : es_mes "TEKI_f(3) " + TEKI_f(3)
pos 420,240 : es_mes "TEKI_f(4) " + TEKI_f(4)
pos 420,270 : es_mes "AI_SP_D " + AI_SP_D
;**************************************
gosub *自機の移動
gosub *自機弾移動
gosub *敵
es_set 400, JIKI_x,JIKI_y, 400 ;自機
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
;*************自機弾移動****************
*自機弾移動
getkey keyZ,90 ;Zキー
JK_TAMA_G_kazu = 0
if keyZ AND JKSO_f = 0 AND RENSA = 0 {
es_exnew JK_TAMA ,10,30 ;新規スプライト取得
;---弾の判断---
if JK_TAMA_c >= 1 {
JK_TAMA_dai_Kz = JK_TAMA_c \ 2
if JK_TAMA_dai_Kz = 0 : JK_TAMA_G_kazu += 1
}
JK_TAMA_c++ ;ループ内カウンター
if JK_TAMA_G_kazu = 0 : JKSO_x = JIKI_x-6 ;左側
if JK_TAMA_G_kazu = 1 : JKSO_x = JIKI_x+18 ;右側
JKSO_y = JIKI_y
es_set JK_TAMA, JKSO_x,JKSO_y, 51 ;スプライトNo, X,Y座標 ,キャラNo
es_apos JK_TAMA, 0,-15 ,100 ;↑に移動
RENSA = 2 ;弾の間隔
es_type JK_TAMA,2 ;自機弾type値(2)
}
if RENSA > 0 : RENSA -= 1 ;弾の間隔
return
;*************敵****************
*敵
;自機弾VS敵 当たり判定
TEKI_no = 250 ;敵の検索開始ナンバー
repeat TEKI_MAX ;敵の最大数(5)
es_check TEKI_VS_TAMA ,TEKI_no,2 ;自機弾スプライト10〜30
if TEKI_VS_TAMA != -1 & TEKI_f(cnt)=0 {;TEKI_f(cnt)=0を加えることで敵が倒された場合は自機弾を消さない。
TEKI_SP_D = TEKI_no - 250
JKTM_HIT(TEKI_SP_D)++
es_kill TEKI_VS_TAMA ;自機弾「削除」
if JKTM_HIT(TEKI_SP_D) >= 10 {;耐久力がなくなったら実行
es_kill TEKI_no ;敵「削除」
TEKI_f(TEKI_SP_D) = 1 ;敵のフラグを「立てる」
}
}
TEKI_no++
loop
return

| |
|
2019/10/12(Sat) 13:36:20|NO.88631
ソラさん。回答とソースありがとうございます。
確かに1回だけでいいので、上のほうで実行するだけでよかったですね・・
長い間このやり方で指摘が一切なかったのでそのままいっちゃった感じですね(白目
>>& TEKI_f(cnt) = 0
なるほど。自機弾が消えちゃうのは敵の残骸?みたいなのが残っているせいっという考えかたでしたが間違ってました。
これなら敵が消えている配列では判定しなくなるので、弾が消えずに行えるってことですね。
ついでに移動の処理などを書いても問題なかったので無事解決です!
ありがとうございました。
|
|
2019/10/13(Sun) 13:33:18|NO.88632
書かれてた内容に返答しきれなかったので追記です
>>p3は250+TEKI_MAXにしないと敵を増やしたときに不具合に繋がるかも。
何が原因なのかわからず原因を切り分けしたかったので、必要最低数にしてました。
もちろん敵を増やすときは増やします(本命ソースではもっと大きい数字です)
とかいいつつ「es_type TEKI,4096」という意味の無いものを書いてました。
メイン処理以外で敵配置を行う場合、画面外からくる敵専用でやろうと思います(画面内から出現だと最初っから見えてしまうため)
また、時間経過してから出現する場合は、メインソースに書いて判定できるようにしようかと思います。
おかげで敵配置の処理を決めることが出来ました。
>>ついでに移動の処理などを書いても問題なかったので無事解決です!
画面外から画面内に移動して判定するとうまくいかない疑惑・・・
うまくできなかったら新しく質問します・・トホホ
「時間経過で出現する場合」
#include "hspdxfix.as" ;DXライブラリ使用
width ,,130,200 ;ウィンドウの位置
es_ini 640,5000,360 ;スプライトの最大数、キャラクタ定義の最大数,周の精度(180*2)
es_screen 640,480 ,0,0,1,1 ;スクリーン
es_window 0,0, 640,480 ;スプライト表示エリア設定
es_area -15,-50, 610,480 ;スプライト有効エリア設定
;---自機---
es_size 28,42, 100
es_pat 400, 0, 0
JIKI_x = 206 : JIKI_y = 390
JIKISpd = 4 ;自機のスピード(4)
;---自機弾---
es_size 11,11, 150
es_pat 51, 1,43
;---低速弾---
es_size 32,32, 100
es_pat 50, 13,43
;---敵---
es_size 50,38, 100
es_pat 70, 19,0
;自機弾
JKTM_MAX = 50 ;自機弾の最大数(50)
dim JKSO_f,JKTM_MAX ;フラグ
dim JKSO_x,JKTM_MAX ;X
dim JKSO_y,JKTM_MAX ;Y
;敵配置
TEKI_MAX = 5 ;敵の最大数
dim TEKI_f,TEKI_MAX
dim TEKI_x,TEKI_MAX
dim TEKI_y,TEKI_MAX
dim JKTM_HIT,TEKI_MAX ;敵HP
;▼▼▼▼▼▼▼敵配列▼▼▼▼▼▼▼
TEKI_x = 40,100,160,220,280 ;X
TEKI_y = 30,80,130,180,230 ;Y
;*********メインループ*********
*メイン
es_cls ;画面クリア
es_draw ;スプライト描画
pos 420,50 : es_mes "JKTM_HIT(0) " + JKTM_HIT(0)
pos 420,70 : es_mes "JKTM_HIT(1) " + JKTM_HIT(1)
pos 420,90 : es_mes "JKTM_HIT(2) " + JKTM_HIT(2)
pos 420,110 : es_mes "JKTM_HIT(3) " + JKTM_HIT(3)
pos 420,130 : es_mes "JKTM_HIT(4) " + JKTM_HIT(4)
pos 420,160 : es_mes "TEKI_f(0) " + TEKI_f(0)
pos 420,180 : es_mes "TEKI_f(1) " + TEKI_f(1)
pos 420,200 : es_mes "TEKI_f(2) " + TEKI_f(2)
pos 420,220 : es_mes "TEKI_f(3) " + TEKI_f(3)
pos 420,240 : es_mes "TEKI_f(4) " + TEKI_f(4)
pos 420,270 : es_mes "AI_SP_D " + AI_SP_D
pos 420,290 : es_mes "TK_TAIM " + TK_TAIM ;---追加---
;**************************************
gosub *自機の移動
gosub *自機弾移動
gosub *敵
es_set 400, JIKI_x,JIKI_y, 400 ;自機
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
;*************自機弾移動****************
*自機弾移動
getkey keyZ,90 ;Zキー
JK_TAMA_G_kazu = 0
if keyZ AND JKSO_f = 0 AND RENSA = 0 {
es_exnew JK_TAMA ,10,30 ;新規スプライト取得
;---弾の判断---
if JK_TAMA_c >= 1 {
JK_TAMA_dai_Kz = JK_TAMA_c \ 2
if JK_TAMA_dai_Kz = 0 : JK_TAMA_G_kazu += 1
}
JK_TAMA_c++ ;ループ内カウンター
if JK_TAMA_G_kazu = 0 : JKSO_x = JIKI_x-6 ;左側
if JK_TAMA_G_kazu = 1 : JKSO_x = JIKI_x+18 ;右側
JKSO_y = JIKI_y
es_set JK_TAMA, JKSO_x,JKSO_y, 51 ;スプライトNo, X,Y座標 ,キャラNo
es_apos JK_TAMA, 0,-15 ,100 ;↑に移動
RENSA = 2 ;弾の間隔
es_type JK_TAMA,2 ;自機弾type値(2)
}
if RENSA > 0 : RENSA -= 1 ;弾の間隔
return
;*************敵****************
*敵
;---追加---
;時間経過してから出現する場合か、画面内から出現はメインソースに書くしかない
if TK_TAIM < 110 : TK_TAIM += 1 ;敵が出る時間をカウントする
if TK_TAIM >= 100 { ;時間がたったら「実行」
if TEKI_STU_f = 0 { ;敵出現フラグ
repeat TEKI_MAX ;敵の最大数(5)
es_exnew TEKI, 250,254 ;新規スプライトNo
es_set TEKI, TEKI_x(cnt),TEKI_y(cnt), 70 ;スプライトNo, X,Y座標 ,キャラNo
loop
}
TEKI_STU_f = 1 ;敵出現フラグ
}
;自機弾VS敵 当たり判定
TEKI_no = 250 ;敵の検索開始ナンバー
repeat TEKI_MAX ;敵の最大数(5)
es_check TEKI_VS_TAMA ,TEKI_no,2 ;自機弾スプライト10〜30
if TEKI_VS_TAMA != -1 & TEKI_f(cnt) = 0 {;自機弾と敵があたったら実行、敵が消えた箇所は実行しない
TEKI_SP_D = TEKI_no - 250
JKTM_HIT(TEKI_SP_D)++
es_kill TEKI_VS_TAMA ;自機弾「削除」
if JKTM_HIT(TEKI_SP_D) >= 10 {;耐久力がなくなったら実行
es_kill TEKI_no ;敵「削除」
TEKI_f(TEKI_SP_D) = 1 ;敵のフラグを「立てる」
}
}
TEKI_no++
loop
return

| |
|