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


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0818
アイドル【hspdxfix.as】「es_ini」のスプライト数を「647」以上にするとシステムエラーが発生する13解決


アイドル

リンク

2020/8/18(Tue) 09:42:12|NO.91192

hspdxfix.asプラグインで作ったSTGゲームになります。

「自機のオプションから弾を出す」っという処理を入れて実行すると「システムエラーが発生しました」と表示されてしまいます。

原因は「es_ini」のスプライト数を「647」以上に設定すると発生します。
「自機のオプションから弾を出す」機能以外入っているソースでは「es_ini」が「850」でも動いてたので、
この追加要素に原因があるかと思われますが、いまいち原因がわかりません。


■発生条件■
「es_ini」のスプライト数を「647」にして「Zキー」を押す
(パワーアップの有無は関係ない)

 ■仕様■
1.パワーアップするごとに自機オプション(クリスタル)が1個増加する
(デバッグでエンターキーを押すとパワーアップします)
2.クリスタルがある状態で「Zキー」を押すと、クリスタルから弾が発射される
3.クリスタルは最大で4個
4.クリスタルは1個につき弾数は1個

#include "hspdxfix.as" ;DXライブラリ使用 width ,,130,200 ;ウィンドウの位置 es_ini 646,500,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 28,42, 100 es_pat 400, 0,0 JIKI_x = 80 : JIKI_y = 280 es_set 400, JIKI_x,JIKI_y, 400 ;---クリスタル--- es_size 15,15, 100 es_pat 55, 0,76 ;---クリスタル弾--- es_size 17,17, 100 es_pat 60, 56,44 ;クリスタル KURI_MAX = 4 ;クリスタルの最大数(4) dim JK_KURIS_f,KURI_MAX ;フラグ dim JK_KURIS_x,KURI_MAX ;X dim JK_KURIS_y,KURI_MAX ;Y ;クリスタル弾 dim JK_KURIS_TM_f,KURI_MAX ;弾フラグ dim JK_KURIS_TM_x,KURI_MAX ;弾X dim JK_KURIS_TM_y,KURI_MAX ;弾Y ;************メインループ*************** *メイン es_cls ;画面クリア es_draw ;スプライト描画 ;************カウンター****************** pos 420,20 : es_mes "PW_KZ " + PW_KZ ;*************自機関連****************** ;自機表示 es_set 350, JIKI_x,JIKI_y, 350 ;スプライトNo, X,Y座標 ,キャラNo ;************gosub************ gosub *クリスタルの処理 gosub *クリスタル弾の処理 gosub *デバッグツール es_sync ;画面更新 await 16 goto *メイン ;*********クリスタルの処理************** *クリスタルの処理 ;---パワーが100以上--- if PW_KZ >= 100 { JK_KURIS_x(0) = JIKI_x+7 JK_KURIS_y(0) = JIKI_y+50 KURI_MAX_H = 1 ;クリスタル弾のループ回数を変更する } ;---パワーが200以上--- if PW_KZ >= 200 { ;右側 JK_KURIS_x(0) = JIKI_x+37 JK_KURIS_y(0) = JIKI_y+11 ;左側 JK_KURIS_x(1) = JIKI_x-28 JK_KURIS_y(1) = JIKI_y+11 if Skey = 1 { ;シフトキーが押されたら「実効」 JK_KURIS_x(0) = JIKI_x+21;右側 JK_KURIS_x(1) = JIKI_x-8;左側 } KURI_MAX_H = 2 ;クリスタル弾のループ回数を変更する } es_set 50, JK_KURIS_x(0),JK_KURIS_y(0), 55 ;スプライトNo, X,Y座標 ,キャラNo es_set 51, JK_KURIS_x(1),JK_KURIS_y(1), 55 ;スプライトNo, X,Y座標 ,キャラNo ;---パワーが300以上--- if PW_KZ >= 300 { JK_KURIS_x(2) = JIKI_x+7 JK_KURIS_y(2) = JIKI_y+50 KURI_MAX_H = 3 ;クリスタル弾のループ回数を変更する } es_set 52, JK_KURIS_x(2),JK_KURIS_y(2), 55 ;スプライトNo, X,Y座標 ,キャラNo ;---パワーが400以上--- if PW_KZ >= 400 { ;右側 JK_KURIS_x(2) = JIKI_x-59 JK_KURIS_y(2) = JIKI_y+16 ;左側 JK_KURIS_x(3) = JIKI_x+72 JK_KURIS_y(3) = JIKI_y+16 if Skey = 1 { ;シフトキーが押されたら「実効」 ;右側 JK_KURIS_x(2) = JIKI_x+17 JK_KURIS_y(2) = JIKI_y+21 ;左側 JK_KURIS_x(3) = JIKI_x-3 JK_KURIS_y(3) = JIKI_y+21 } KURI_MAX_H = 4 ;クリスタル弾のループ回数を変更する } es_set 52, JK_KURIS_x(2),JK_KURIS_y(2), 55 ;スプライトNo, X,Y座標 ,キャラNo es_set 53, JK_KURIS_x(3),JK_KURIS_y(3), 55 ;スプライトNo, X,Y座標 ,キャラNo return ;***********クリスタル弾の処理********** *クリスタル弾の処理 getkey keyZ,90 ;Zキー if keyZ = 1 { ;ショットが押されたら「実効」 JK_KURIS_TM_no = 50 ;クリスタルの場所検索ナンバー JK_KURIS_TM_hs = 60 ;クリスタル弾の場所検索ナンバー repeat KURI_MAX ;クリスタルの最大数(4) if cnt = 0 : JKTM_SP_s = 60 : JKTM_SP_m = 60 if cnt = 1 : JKTM_SP_s = 61 : JKTM_SP_m = 61 if cnt = 2 : JKTM_SP_s = 62 : JKTM_SP_m = 62 if cnt = 3 : JKTM_SP_s = 63 : JKTM_SP_m = 63 es_get JK_KURIS_TM_x(cnt),JK_KURIS_TM_no,3 ;X座標 es_get JK_KURIS_TM_y(cnt),JK_KURIS_TM_no,5 ;Y座標 es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定 es_apos JK_KURIS_TM_hs, 0,-5 ,100 ;↑に移動 es_type JK_KURIS_TM_hs,64;type値(64) JK_KURIS_TM_no++;クリスタルの場所検索ナンバー JK_KURIS_TM_hs++;弾の場所検索ナンバー loop } ;---画面外判定--- JK_KURIS_TM_hs = 60 ;クリスタル弾の場所検索ナンバー repeat es_find JK_KURIS_D, 64, JK_KURIS_TM_hs, 63, 1 if JK_KURIS_D < 0 : break es_get JK_KURIS_TM_y,JK_KURIS_D,5 ;クリスタル弾Y if JK_KURIS_TM_y < 0 : es_kill JK_KURIS_D ;クリスタル弾【削除】 JK_KURIS_TM_hs++ ;クリスタル弾の場所検索ナンバー loop return ;*************デバッグツール************ *デバッグツール getkey key_P,13 ;エンターキー if key_P { ;キーが押されたら実効 if K_P = 0 { PW_KZ += 100 ;自機パワー K_P = 1 } } else { K_P = 0 } return



この記事に返信する


あらや

リンク

2020/8/18(Tue) 19:07:50|NO.91194

なんで647という半端な数値なのかは不明ですが
es_exnewというかes_setというか、この辺が原因っぽいです。

クリスタル弾の処理でZキーを押した場合は
ループ処理で
>es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得
>es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定
これらを実行していますが、
クリスタル弾が既存の場合スプライト癲癖竸JK_KURIS_TM_hs)に-1になります。

そしてスプライト發-1でes_setを実行すると
647未満ならばエラー無し、647以上だとエラーになるようです。

試しに13行目の自機のスプライトをセットする所で
『es_set -1』としたら上記の環境でエラーの有無が確認できました。



解決案として、変数JK_KURIS_TM_hsが想定と違う値の時には
以後の処理を飛ばす等としてはいかがでしょうか?

// 例 es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 if( JK_KURIS_TM_hs < JKTM_SP_s ) : continue; // ( JK_KURIS_TM_hs != JKTM_SP_s )や( JK_KURIS_TM_hs < 0 )でも可 es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定



アイドル

リンク

2020/8/18(Tue) 21:23:17|NO.91196

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


なんで647か不明ですよね・・・あまり深く考えないほうがいいかも。

そういえばかなり前に似たようなことを言われたような気がします・・・
ループをやり直す方法だと、クリスタル1個につき弾が複数個出てしまうので、
「ループを抜ける」方法にしました。

ちょっと調整しつつ問題なさそうなら解決にチェックを入れます

es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 if JK_KURIS_TM_hs = -1 : break ;ループを抜ける es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定



アイドル

リンク

2020/8/19(Wed) 16:45:53|NO.91198

なんとか処理に問題ないところまでいったのですが、別の問題が発生しちゃいました・・・・

敵に弾を当てると、他の弾が画面外に行くまで当てた弾がすぐに発射しなくなっちゃいました。
以前はループ抜けてなかったのですぐに実行されましたが、
システムエラー対応でループを抜けるようにした結果、すぐに発射されなくなる仕様バグが発生するようになりました。

クリスタル弾の作り方を変えないとだめだと思うので、解決するまで時間かかりそうです。


色々変更箇所があるのでソースを載せます
クリスタル弾関連の追加変更はコメントの前後に「---」を書いておきます。
(例:---次の弾を装填させるために、最大は最小より1増加した数値---)

#include "hspdxfix.as" ;DXライブラリ使用 width ,,130,200 ;ウィンドウの位置 es_ini 850,500,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 28,42, 100 es_pat 400, 0,0 es_set 400, JIKI_x,JIKI_y, 400 JIKI_x = 80 : JIKI_y = 350 JIKISpd = 4 ;自機のスピード ;---クリスタル--- es_size 15,15, 100 es_pat 55, 0,76 ;---クリスタル弾--- es_size 17,17, 100 es_pat 60, 56,44 ;---敵---80〜170 es_size 18,19, 50 es_pat 80, 0,0 ;敵 TEKI_MAX = 2 dim TEKI_x,TEKI_MAX ;X dim TEKI_y,TEKI_MAX ;Y ;クリスタル KURI_MAX = 4 ;クリスタルの最大数(4) dim JK_KURIS_f,KURI_MAX ;フラグ dim JK_KURIS_x,KURI_MAX ;X dim JK_KURIS_y,KURI_MAX ;Y ;クリスタル弾 dim JK_KURIS_TM_f,KURI_MAX ;弾フラグ dim JK_KURIS_TM_x,KURI_MAX ;弾X dim JK_KURIS_TM_y,KURI_MAX ;弾Y ;▼▼▼▼▼▼▼敵配列▼▼▼▼▼▼▼ TEKI_x = 50,200 TEKI_y = 300,300 ;■■■敵配置■■■ repeat TEKI_MAX ;敵の最大数(2) es_exnew TEKI, 80,81 ;新規スプライト es_set TEKI, TEKI_x(cnt),TEKI_y(cnt), 80 ;スプライトNo, X,Y座標 ,キャラNo es_type TEKI,4096 loop ;************メインループ*************** *メイン es_cls ;画面クリア es_draw ;スプライト描画 ;************カウンター****************** pos 420,20 : es_mes "PW_KZ " + PW_KZ pos 400,90 : es_mes "JK_KURIS_TM_f(0) " + JK_KURIS_TM_f(0) pos 400,110 : es_mes "JK_KURIS_TM_f(1) " + JK_KURIS_TM_f(1) pos 400,130 : es_mes "JK_KURIS_TM_f(2) " + JK_KURIS_TM_f(2) pos 400,150 : es_mes "JK_KURIS_TM_f(3) " + JK_KURIS_TM_f(3) ;*************自機関連****************** ;自機表示 es_set 350, JIKI_x,JIKI_y, 350 ;スプライトNo, X,Y座標 ,キャラNo ;************gosub************ gosub *自機の移動 gosub *クリスタルの処理 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 ;*********クリスタルの処理************** *クリスタルの処理 ;---パワーが100以上--- if PW_KZ >= 100 { JK_KURIS_x(0) = JIKI_x+7 JK_KURIS_y(0) = JIKI_y+50 } ;---パワーが200以上--- if PW_KZ >= 200 { ;右側 JK_KURIS_x(0) = JIKI_x+37 JK_KURIS_y(0) = JIKI_y+11 ;左側 JK_KURIS_x(1) = JIKI_x-28 JK_KURIS_y(1) = JIKI_y+11 if Skey = 1 { ;シフトキーが押されたら「実効」 JK_KURIS_x(0) = JIKI_x+21;右側 JK_KURIS_x(1) = JIKI_x-8;左側 } } es_set 50, JK_KURIS_x(0),JK_KURIS_y(0), 55 ;スプライトNo, X,Y座標 ,キャラNo es_set 51, JK_KURIS_x(1),JK_KURIS_y(1), 55 ;スプライトNo, X,Y座標 ,キャラNo ;---パワーが300以上--- if PW_KZ >= 300 { JK_KURIS_x(2) = JIKI_x+7 JK_KURIS_y(2) = JIKI_y+50 } es_set 52, JK_KURIS_x(2),JK_KURIS_y(2), 55 ;スプライトNo, X,Y座標 ,キャラNo ;---パワーが400以上--- if PW_KZ >= 400 { ;右側 JK_KURIS_x(2) = JIKI_x-59 JK_KURIS_y(2) = JIKI_y+16 ;左側 JK_KURIS_x(3) = JIKI_x+72 JK_KURIS_y(3) = JIKI_y+16 if Skey = 1 { ;シフトキーが押されたら「実効」 ;右側 JK_KURIS_x(2) = JIKI_x+17 JK_KURIS_y(2) = JIKI_y+21 ;左側 JK_KURIS_x(3) = JIKI_x-3 JK_KURIS_y(3) = JIKI_y+21 } } es_set 52, JK_KURIS_x(2),JK_KURIS_y(2), 55 ;スプライトNo, X,Y座標 ,キャラNo es_set 53, JK_KURIS_x(3),JK_KURIS_y(3), 55 ;スプライトNo, X,Y座標 ,キャラNo return ;***********クリスタル弾の処理********** *クリスタル弾の処理 getkey keyZ,90 ;Zキー if keyZ = 1 { ;ショットが押されたら「実効」 JK_KURIS_TM_no = 50 ;クリスタルの場所検索ナンバー JK_KURIS_TM_hs = 60 ;クリスタル弾の場所検索ナンバー repeat KURI_MAX ;クリスタルの最大数(4) if cnt = 0 : JKTM_SP_s = 60 : JKTM_SP_m = 60 if cnt = 1 : JKTM_SP_s = 61 : JKTM_SP_m = 61 if cnt = 2 : JKTM_SP_s = 62 : JKTM_SP_m = 63 ;---次の弾を装填させるために、最大は最小より1増加した数値--- if cnt = 3 : JKTM_SP_s = 64 : JKTM_SP_m = 65 ;---次の弾を装填させるために、最大は最小より1増加した数値--- es_get JK_KURIS_TM_x(cnt),JK_KURIS_TM_no,3 ;X座標 es_get JK_KURIS_TM_y(cnt),JK_KURIS_TM_no,5 ;Y座標 es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 if JK_KURIS_TM_hs = -1 : break ;---ループを抜ける--- es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定 es_apos JK_KURIS_TM_hs, 0,-5 ,100 ;↑に移動 es_type JK_KURIS_TM_hs,64;type値(64) JK_KURIS_TM_no++;クリスタルの場所検索ナンバー JK_KURIS_TM_hs++;弾の場所検索ナンバー loop } ;---画面外判定--- JK_KURIS_TM_hs = 60 ;クリスタル弾の場所検索ナンバー repeat es_find JK_KURIS_D, 64, JK_KURIS_TM_hs, 65, 1 if JK_KURIS_D < 0 : break es_get JK_KURIS_TM_y,JK_KURIS_D,5 ;クリスタル弾Y if JK_KURIS_TM_y < 0 : es_kill JK_KURIS_D ;クリスタル弾【削除】 JK_KURIS_TM_hs++ ;クリスタル弾の場所検索ナンバー loop return ;*************敵**************** *敵 ;クリスタルVS敵 当たり判定 TEKI_no = 80 ;敵の検索開始ナンバ− repeat TEKI_MAX ;敵の最大数(2) es_find TEKI_Di, 4096, TEKI_no,81 es_check TEKI_VS_TAMA ,TEKI_Di,64 if TEKI_VS_TAMA != -1 : es_kill TEKI_VS_TAMA;クリスタル弾【削除】 TEKI_no++ loop return ;*************デバッグツール************ *デバッグツール getkey key_P,13 ;エンターキー if key_P { ;キーが押されたら実効 if K_P = 0 { PW_KZ += 100 ;自機パワー K_P = 1 } } else { K_P = 0 } pos 400,370 : es_mes "(0)" pos 400,390 : es_mes "(1)" pos 400,410 : es_mes "(2)" pos 400,430 : es_mes "(3)" pos 400,450 : es_mes "(4)" JK_KURIS_TM_mes_y = 350 ;デバック用に表示させる座標 JK_KURIS_TM_hs = 60 ;弾の場所検索ナンバー repeat 5 JK_KURIS_TM_mes_y += 20 ;複数見るためにずらす es_get JK_KURIS_TM_pos_y,JK_KURIS_TM_hs,5 ;Y pos 430,JK_KURIS_TM_mes_y : es_mes "" + JK_KURIS_TM_pos_y ;Y値を見る es_get JK_KURIS_TM_type,JK_KURIS_TM_hs,13 ;type値 pos 470,JK_KURIS_TM_mes_y : es_mes "type " + JK_KURIS_TM_type ;type値を見る JK_KURIS_TM_hs++ ;弾の場所検索ナンバー loop return



あらや

リンク

2020/8/19(Wed) 18:41:40|NO.91201

breakでループを抜けているので
0番のクリスタルだけは敵と接触したらすぐに発射
ほかのクリスタルは画面外に出るまで発射不可になってしまいましたね。。。

新しく管理用の配列変数を用意しても良かったのですが
変数が増えると煩雑になるので
es_getで未使用となっているプログレスカウントを利用してみました。

変更箇所は*クリスタル弾の処理の下記の箇所です
>es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得
>if JK_KURIS_TM_hs = -1 : break ;---ループを抜ける---
>es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定
>es_apos JK_KURIS_TM_hs, 0,-5 ,100 ;↑に移動
>es_type JK_KURIS_TM_hs,64;type値(64)
>JK_KURIS_TM_no++;クリスタルの場所検索ナンバー
>JK_KURIS_TM_hs++;弾の場所検索ナンバー

一度に複数の弾を発射しないように
適当ですが10カウントするまで次弾は発射しないようにしてあります。

es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 if( JK_KURIS_TM_hs >= 62 ) { // 發偶数(62か64)の時は次の癲63か65)、奇数(63か65)の時は前の癲62か64)を確認 if( (JK_KURIS_TM_hs \ 2) == 0 ) : CHECK_NO = JK_KURIS_TM_hs + 1 : else : CHECK_NO = JK_KURIS_TM_hs - 1; es_get PRG_CNT, CHECK_NO, 10; // プログレスカウントを取得 // 次の弾を発射するのを10フレーム遅らせるための処理 if( PRG_CNT < 10 ) { // プログレスカウントが10未満の時 es_setp CHECK_NO, 10, PRG_CNT+1; // プログレスカウントに1を足す JK_KURIS_TM_hs = -1; // スプライト發鯡妓にする } } // スプライト發有効値の時のみ実行 if JK_KURIS_TM_hs != -1 { es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定 es_apos JK_KURIS_TM_hs, 0,-5 ,100 ;↑に移動 es_type JK_KURIS_TM_hs,64;type値(64) if( JK_KURIS_TM_hs >= 62 ) : es_setp JK_KURIS_TM_hs, 10, 1; // プログレスカウントに1をセット } JK_KURIS_TM_no++;クリスタルの場所検索ナンバー JK_KURIS_TM_hs++;弾の場所検索ナンバー

そして削除のときにプログレスカウントを0にリセットする処理も追加してみました

;---画面外判定--- // 〜省略〜 if JK_KURIS_TM_y < 0 : es_setp JK_KURIS_D, 10, 0 : es_kill JK_KURIS_D ;クリスタル弾【削除】 // 〜省略〜 ;クリスタルVS敵 当たり判定 // 〜省略〜 if TEKI_VS_TAMA != -1 : es_setp TEKI_VS_TAMA, 10, 0 : es_kill TEKI_VS_TAMA;クリスタル弾【削除】
弾が極力重ならないように
62、64を発射するときは63、65
63、65を発射するときは62、64
をそれぞれカウントを確認するようにしましたが
そのせいで60や61と発射のタイミングがずれてしまうので
確認するのは前者の『62、64を発射するときは63、65』だけでも良いかもしれません。
ここは好みで変更してください。


それからカウントの10は適当に決めた数なので
こちらも好みに合わせて調節してください。



アイドル

リンク

2020/8/19(Wed) 21:30:10|NO.91202

あらやさん
わざわざソースまでありがとうございます!


いくつかわからないところがあります・・!

・プログレスカウント
プログラムを実行したときの時間を取得している感じなやつでしょうか
ぐぐってもヘルプを見てもなんなのかよくわからなくって、なんとなくそんな感じってやつって解釈しちゃいましたがそれで大丈夫ですかね。

・処理の流れの解釈って以下であってますかね
if JK_KURIS_TM_hs \ 2 = 0 : CHECK_NO = JK_KURIS_TM_hs + 1 {
;60 \ 2 = 0 : 60 + 1
1週目はあまりが0なのでCHECK_NOは61になる。

es_get CHECK_NO, 61, 10
if PRG_CNT < 10 {
es_setp CHECK_NO, 10, PRG_CNT+1
;61(スプライトno), l0(プログレスカウント), 0+1
61のプログレスカウントのスプライトを+1したやつにする。

JK_KURIS_TM_hs = -1
スプライト發鯡妓にする理由がよくわかってなかったり。

if JK_KURIS_TM_hs >= 62 : es_setp JK_KURIS_TM_hs, 10, 1
62, 10, 1
何故「1」なのかわからない「2」とかにしても、見た目の処理の違いがないのでわからず。



あらや

リンク

2020/8/19(Wed) 22:31:29|NO.91203

>・プログレスカウント
未使用なので常に0になっていて正確には不明ですが
名前から想像すると、
おそらくスプライトを表示してからのフレーム数をカウントしていくような機能
になる予定だったんだと思います。



>・処理の流れ

>if JK_KURIS_TM_hs \ 2 = 0 : CHECK_NO = JK_KURIS_TM_hs + 1 {
>;60 \ 2 = 0 : 60 + 1
>1週目はあまりが0なのでCHECK_NOは61になる。
ここだけ抜き出すとそうなりますが、

その前に
>if( JK_KURIS_TM_hs >= 62 ) {
この条件式を入れているので
実際はCHECK_NOは63になります。
この辺りの処理は弾を複数発射出来るクリスタル用です。



>JK_KURIS_TM_hs = -1
>スプライト發鯡妓にする理由がよくわかってなかったり。
これは上の内容と少しかぶりますが、弾を2つ発射できるクリスタルの場合
Zを押した時に最初のフレームで1発目の弾を発射し、次のフレームで2発目を即座に発射する。
という流れだと2つの弾が1フレームだけズレて
ほとんど重なって見えるので10フレームだけ待ってから2発目を発射するための処理です。

私の勝手な解釈を踏まえた上でのしょりなので
元々重なって見えるような演出にしようとしていたのならば
この辺りの処理は不要です。



>if JK_KURIS_TM_hs >= 62 : es_setp JK_KURIS_TM_hs, 10, 1
>何故「1」なのかわからない「2」とかにしても、見た目の処理の違いがないのでわからず。
1にしたのは「カウントを開始しましたよ」という合図のようなものです。
ぶっちゃけるとこの行は無しで0からスタートする形にしてもほとんど変わりません。
同じ理由で「1」を「2」にしても1フレーム変わるだけなので
見た目で判断するのは難しいと思います。

もう少し詳しく説明させていただくと
>if PRG_CNT < 10 {
この行とも関連するのですが
簡単に言えば1つ目の弾が発射されてから2つ目の弾が発射されるまでに
何フレーム待つかという内容なので
私が書いたのは
「1」からカウントを始めて、「10」になったら2発目を発射する
という意味になります。

「1」を「2」にしても
「2」からカウントを始めて、「10」になったら2発目を発射する
となるだけなので見た目ではほとんど判断できないはずです。

仮に「1」を「7」などにすれば
「7」からカウントを始めて、「10」になったら2発目を発射する
という意味になるので、
あきらかに1つ目の弾と2つ目の弾が近くなるのが見て分かると思います。



あらや

リンク

2020/8/20(Thu) 00:27:11|NO.91204

改めて考えたら
>es_setp CHECK_NO, 10, PRG_CNT+1; // プログレスカウントに1を足す
この行はZキーを押してないとカウントしませんね。。。

そこに対処するために一部修正します。

先述の変更も含めて関連する箇所のソースを全て載せておきます。

;***********クリスタル弾の処理********** *クリスタル弾の処理 // Zキーのループ外でカウント JK_KURIS_TM_hs = 62;クリスタル弾のカウント状況確認ナンバー repeat 4 // 62〜65の4つだけ確認 es_get PRG_CNT, JK_KURIS_TM_hs, 10; // プログレスカウントを取得 if( PRG_CNT > 0 ) { // プログレスカウントがカウント中の場合 es_setp JK_KURIS_TM_hs, 10, PRG_CNT+1; // プログレスカウントに1を足す } JK_KURIS_TM_hs++; loop getkey keyZ,90 ;Zキー if keyZ = 1 { ;ショットが押されたら「実効」 JK_KURIS_TM_no = 50 ;クリスタルの場所検索ナンバー JK_KURIS_TM_hs = 60 ;クリスタル弾の場所検索ナンバー repeat KURI_MAX ;クリスタルの最大数(4) if cnt = 0 : JKTM_SP_s = 60 : JKTM_SP_m = 60 if cnt = 1 : JKTM_SP_s = 61 : JKTM_SP_m = 61 if cnt = 2 : JKTM_SP_s = 62 : JKTM_SP_m = 63 ;---次の弾を装填させるために、最大は最小より1増加した数値--- if cnt = 3 : JKTM_SP_s = 64 : JKTM_SP_m = 65 ;---次の弾を装填させるために、最大は最小より1増加した数値--- es_get JK_KURIS_TM_x(cnt),JK_KURIS_TM_no,3 ;X座標 es_get JK_KURIS_TM_y(cnt),JK_KURIS_TM_no,5 ;Y座標 es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 if( JK_KURIS_TM_hs >= 62 ) { // 發偶数(62か64)の時は次の癲63か65)、奇数(63か65)の時は前の癲62か64)を確認 if( (JK_KURIS_TM_hs \ 2) == 0 ) : CHECK_NO = JK_KURIS_TM_hs + 1 : else : CHECK_NO = JK_KURIS_TM_hs - 1; es_get PRG_CNT, CHECK_NO, 10; // プログレスカウントを取得 // 次の弾を発射するのを10フレーム遅らせるための処理 if( (PRG_CNT > 0) && (PRG_CNT < 10) ) { // プログレスカウントが10未満の時 ;es_setp CHECK_NO, 10, PRG_CNT+1; // プログレスカウントに1を足す JK_KURIS_TM_hs = -1; // スプライト發鯡妓にする } } // スプライト發有効値の時のみ実行 if JK_KURIS_TM_hs != -1 { es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定 es_apos JK_KURIS_TM_hs, 0,-5 ,100 ;↑に移動 es_type JK_KURIS_TM_hs,64;type値(64) if( JK_KURIS_TM_hs >= 62 ) : es_setp JK_KURIS_TM_hs, 10, 1; // プログレスカウントに1をセット } JK_KURIS_TM_no++;クリスタルの場所検索ナンバー JK_KURIS_TM_hs++;弾の場所検索ナンバー loop } ;---画面外判定--- JK_KURIS_TM_hs = 60 ;クリスタル弾の場所検索ナンバー repeat es_find JK_KURIS_D, 64, JK_KURIS_TM_hs, 65, 1 if JK_KURIS_D < 0 : break es_get JK_KURIS_TM_y,JK_KURIS_D,5 ;クリスタル弾Y if JK_KURIS_TM_y < 0 : es_setp JK_KURIS_D, 10, 0 : es_kill JK_KURIS_D ;クリスタル弾【削除】 JK_KURIS_TM_hs++ ;クリスタル弾の場所検索ナンバー loop return ;*************敵**************** *敵 ;クリスタルVS敵 当たり判定 TEKI_no = 80 ;敵の検索開始ナンバ− repeat TEKI_MAX ;敵の最大数(2) es_find TEKI_Di, 4096, TEKI_no,81 es_check TEKI_VS_TAMA ,TEKI_Di,64 if TEKI_VS_TAMA != -1 : es_setp TEKI_VS_TAMA, 10, 0 : es_kill TEKI_VS_TAMA;クリスタル弾【削除】 TEKI_no++ loop return
前回の発言とは少々異なってしまいますが
カウント中かカウントの必要が無いかをプログレスカウンタの値で判別しているので
弾を発射した時にはカウンタの数値を「1」以上にする必要があります。

ループの中でカウントしていた
>es_setp CHECK_NO, 10, PRG_CNT+1; // プログレスカウントに1を足す
この行は不要になったのでコメントアウトしました。



アイドル

リンク

2020/8/20(Thu) 14:48:34|NO.91210

あらやさん再度返答ありがとうございます!


>>ここだけ抜き出すとそうなりますが、
>>その前に
>if( JK_KURIS_TM_hs >= 62 ) {
>>この条件式を入れているので
>>実際はCHECK_NOは63になります。
>>この辺りの処理は弾を複数発射出来るクリスタル用です。
あぁぁああしまった63やん
;62 \ 2 = 0 : 62 + 1
;64 \ 2 = 0 : 64 + 1

>JK_KURIS_TM_hs = -1
>スプライト發鯡妓にする理由がよくわかってなかったり。
>>これは上の内容と少しかぶりますが、弾を2つ発射できるクリスタルの場合
>>Zを押した時に最初のフレームで1発目の弾を発射し、次のフレームで2発目を即座に発射する。
>>という流れだと2つの弾が1フレームだけズレて
>>ほとんど重なって見えるので10フレームだけ待ってから2発目を発射するための処理です。
1発目を出した後に2発目を処理する仕様のため、1フレームずれてたんですね
1発目撃つ→10フレーム→2発目ってことですよね。
でも何故10フレーム待つとうまくいくのかよくわかってないですorz

うまく言えなくって申し訳ないです><
スプライトを-1するとそ何故ういう処理になるのかいまいちわかっておりません・・・


>>「1」からカウントを始めて、「10」になったら2発目を発射する
>>という意味になります。
なるほどだからここは1なんですね!

新しいソースがあああひぇええ。けどありがとうございます!
分解などをして理解してみますね!



あらや

リンク

2020/8/20(Thu) 19:33:48|NO.91211

>1発目撃つ→10フレーム→2発目ってことですよね。
は、その通りです。
>スプライトを-1すると何故そういう処理になるのか
-1にするのは10フレーム待つための処理です。
言い方を変えると、
10フレーム経過する前に弾が発射出来ないように(スプライトを表示しないように)
わざと無効な数字を入れてスプライトの表示処理をしないようにしています。

-1にした後の行で↓の判定をしているので、
>if JK_KURIS_TM_hs != -1 {
>es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定
その判定に合わせた形でスプライト發-1にしています。



というか、弾が画面外に出るまで次弾が発射出来ないという不具合の対処と
弾を複数発射するためのカウントを同時にやったので
無意味に混乱させてしまったみたいですね。
申し訳ないです。

いったんカウントは除外してNO.91198の不具合だけに対処するならば
たぶん1行修正するだけで済みます。

es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 ;if JK_KURIS_TM_hs = -1 : break ;---ループを抜ける--- if JK_KURIS_TM_hs = -1 : JK_KURIS_TM_no++ : JK_KURIS_TM_hs++ : continue; es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定
以前の修正案ではJK_KURIS_TM_noとJK_KURIS_TM_hsに1を足すのを忘れていたので
クリスタルから弾が複数出てしまったんだと思います。
重ね重ね失礼いたしました。


そして追加で、continueを使わずにほぼ同じ結果になる書き方です。

es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 if JK_KURIS_TM_hs != -1 { // スプライトが-1でなければ実行 es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定 es_apos JK_KURIS_TM_hs, 0,-5 ,100 ;↑に移動 es_type JK_KURIS_TM_hs,64;type値(64) } JK_KURIS_TM_no++;クリスタルの場所検索ナンバー JK_KURIS_TM_hs++;弾の場所検索ナンバー

どちらも結果は同じですが
10フレームカウントするには後者の書き方がやりやすかったので
後者のソースで書かせていただきました。

カウントは更にこれに手を加えた物です。



以下は余禄です。


>何故10フレーム待つとうまくいくのか
余計に混乱させてしまうかもしれませんが
標準命令のみで2発の弾を発射するソースを書いてみました。

自機や敵はありませんし、
アイドルさんのソースとほとんど共通点が無いので
ソース自体は参考にならないかもしれませんが
フレーム待機する意味がイメージしやすくなるかと(たぶん)

title "Zキーで弾を発射 1発目は白、2発目は赤"; count = 0; // カウント用変数 dim bullet_px, 8; // 弾座標X bullet_px = 72, 232, 392, 552, 72, 232, 392, 552; dim bullet_py, 8; // 弾座標Y dim bullet_flag, 8; // 弾描画フラグ *main redraw 0; // 背景色を黒にして、画面を4分割する線を描画 color: boxf; color 255, 255, 255: line 160, 0, 160, 480; line 320, 0, 320, 480: line 480, 0, 480, 480; // 分割した各画面の説明文 pos 10, 0: mes "1フレーム差"; pos 170, 0: mes "3フレーム差"; pos 330, 0: mes "7フレーム差"; pos 490, 0: mes "10フレーム差"; gosub *keycheck; redraw 1; await 17; goto *main; *keycheck if( count == 0 ) { // カウント中は弾を発射しない getkey z, 90; if( z = 1 ) { repeat 4 bullet_flag(cnt) = 1; // 1発目の弾の描画フラグをオンにする bullet_py(cnt) = 480; // 弾のY座標を設定 loop count = 1; // カウント開始 } } else { // カウントが始まったら弾を描画する repeat 8 if( cnt < 4 ) : color 255, 255, 255 : else : color 255, 0, 0; // 1発目は白、2発目は赤にする if( bullet_flag(cnt) == 1 ) { // 弾の描画フラグがオンの場合 boxf bullet_px(cnt), bullet_py(cnt), bullet_px(cnt)+17, bullet_py(cnt)+17; // 弾を描画 bullet_py(cnt) -= 5; // 上に5ドット動かす } loop if( count == 1 ) { // 1フレーム経過したら左端の2発目をオン bullet_flag(4) = 1; // 2発目の弾の描画フラグをオンにする bullet_py(4) = 480; // 弾のY座標を設定 } if( count == 3 ) { // 3フレーム経過したら左から2番目の2発目をオン bullet_flag(5) = 1; // 2発目の弾の描画フラグをオンにする bullet_py(5) = 480; // 弾のY座標を設定 } if( count == 7 ) { // 7フレーム経過したら左から3番目の2発目をオン bullet_flag(6) = 1; // 2発目の弾の描画フラグをオンにする bullet_py(6) = 480; // 弾のY座標を設定 } if( count == 10 ) { // 10フレーム経過したら右端の2発目をオン bullet_flag(7) = 1; // 2発目の弾の描画フラグをオンにする bullet_py(7) = 480; // 弾のY座標を設定 } count++; // カウントを1進める // 画面外判定 repeat 8 if( bullet_py(cnt) < -17 ) { bullet_py(cnt) = 0; // 座標をリセット bullet_flag(cnt) = 0; // 描画フラグを0にする // 最後の弾が画面外に出たらカウントを止める if( cnt == 7 ) { count = 0; } } loop } return;

このソースを実行した時に一番左に表示されるのが
10フレーム待機無しのアイドルさんのソースに近い描画です。



あらや

リンク

2020/8/20(Thu) 19:40:29|NO.91212

読み返したら初っ端からおかしな返事をしてますね。
>は、その通りです。
これは「はい、その通りです。」と書いたつもりでした。

いつの間にか、私はアイドルさんの家来になっていたようです。。。



アイドル

リンク

2020/8/21(Fri) 11:20:49|NO.91218

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


>わざと無効な数字を入れてスプライトの表示処理をしないようにしています。
そういう理由だったんですね!すっきりしました!

>いったんカウントは除外してNO.91198の不具合だけに対処するならば
>たぶん1行修正するだけで済みます。
まさか1行だけでいけるとは・・・もしかしてこれでもうまくいきますか?
弾スプライトが無いときに実行しようとしてエラー出ていると思うので、これでもいけそうかな

if JK_KURIS_TM_hs != -1 { es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定 es_apos JK_KURIS_TM_hs, 0,-5 ,100 ;↑に移動 }
っと思ったら先周りされてたああああ


>>フレーム待機する意味がイメージしやすくなるかと(たぶん)
あれなんかどっかれ解釈間違えたっぽい。あれ。
2発打てるときに、1発目(左側)→10フレーム待機→2発目(右側)だと2発目のとき10フレームずれちゃうのでは?
って思ってたのでなにか勘違いしている予感。


>>いつの間にか、私はアイドルさんの家来になっていたようです。。。
ななななんといつのまにそんなことに( ̄▽ ̄


とりま、問題なければ以下で処理しようかと思いまs。

repeat KURI_MAX ;クリスタルの最大数(4) if cnt = 0 : JKTM_SP_s = 60 : JKTM_SP_m = 60 if cnt = 1 : JKTM_SP_s = 61 : JKTM_SP_m = 61 if cnt = 2 : JKTM_SP_s = 62 : JKTM_SP_m = 62 if cnt = 3 : JKTM_SP_s = 63 : JKTM_SP_m = 63 es_get JK_KURIS_TM_x(cnt),JK_KURIS_TM_no,3 ;X座標 es_get JK_KURIS_TM_y(cnt),JK_KURIS_TM_no,5 ;Y座標 es_exnew JK_KURIS_TM_hs, JKTM_SP_s,JKTM_SP_m ;新規スプライト取得 if JK_KURIS_TM_hs != -1 { es_set JK_KURIS_TM_hs, JK_KURIS_TM_x(cnt),JK_KURIS_TM_y(cnt),60 ;スプライト設定 es_apos JK_KURIS_TM_hs, 0,-5 ,100 ;↑に移動 } es_type JK_KURIS_TM_hs,64;type値(64) JK_KURIS_TM_no++;クリスタルの場所検索ナンバー JK_KURIS_TM_hs++;弾の場所検索ナンバー loop



あらや

リンク

2020/8/21(Fri) 11:53:11|NO.91219

とり急ぎですが

>とりま、問題なければ以下で処理しようかと思いまs。
es_typeの行もif判定の中に入れた方が良いですよ。

外に出してると-1のスプライトにtype値64を設定するという事になりますから。

そこ以外は問題無いと思います。



アイドル

リンク

2020/8/21(Fri) 23:14:48|NO.91237

あらやさん
あ、そうですね!type値も一緒にくくっておきます。
メインソースに入れても動作に問題なさそうなので解決にチェックいれます!

色々とありがとうございます!
フレームずれのやつは時間があったときに使えるようにしておきます(多分無理



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.91192への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

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