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


HSPTV!掲示板


未解決 解決 停止 削除要請

2022
0108
アイドル【hspdxfix.as】es_iniを6846以上にするとエラーになる3解決


アイドル

リンク

2022/1/8(Sat) 19:07:38|NO.94931

またこの問題にぶち当たりました・・・
hspdxfix.asプラグインで作ったSTGゲームになります!


■やりたいこと
es_iniで9100ぐらいスプライトを確保できるようにしたい

■仕様
・Zキーを押している間発射され、敵が画面内に出現したらホーミングする
(エラーが出てしまうので「if TEKI_HOMIN_no != -1 {」で敵が出現しているときに発射されます)


if TEKI_HOMIN_no != -1 {でエラー回避してしまうと、
Zキーを押している間にホーミングが発射されない。
(敵が出現してから発射されるロジックになってしまう)

またこの回避方法だと当たり判定のところでエラーになってしまうので、
どっちみちこの方法はよくないので違う方法にしたい。


スプライトを6845を上限にして作成してもいいけど、
何かあったときにエラーになってしまうので、できれば原因を判明させたいので
アドバイス等お待ちしております!
(敵処理に関しては出来ればツッコミなしでお願いします・・・)

ちなみに前回はループ処理に原因がありました。
http://hsp.tv/play/pforum.php?mode=pastwch&num=91192

#include "hspogg.as" ;音のために入れる #include "hspdxfix.as" ;DXライブラリ使用 width ,,130,200 ;ウィンドウの位置 es_ini 6846,9100,4096 ;スプライトの最大数、キャラクタ定義の最大数,周の精度(180*2) es_screen 640,480 ,0,0,1,1 ;スクリーン es_window 0,-43, 640,480 ;スプライト表示エリア設定 es_area -36,-430, 600,498 ;スプライト有効エリア設定 buffer 4 picload "jiki.bmp" ; es_buffer 4,,$00ff00,,1 ;---自機--- es_size 28,42, 100 es_pat 4000, 0, 0 JIKI_x = 206 : JIKI_y = 390 ;---ホーミング--- es_size 17,19, 100 es_pat 55, 56,62 ;------ buffer 5 picload "teki.bmp" ; es_buffer 5,,$00ff00,,1 ;---敵--- es_size 18,19, 100 es_pat 80, 18*cnt, 0 ;p1=キャラクタNo. gsel 0,1 ;敵 TEKI_MAX = 5 ;最大数 TEKI_Gmax = 22 ;グループ数 TEKI_GOKEI = TEKI_MAX * TEKI_Gmax ;敵合計数 dim TEKI_f,TEKI_GOKEI ;フラグ dim TEKI_x,TEKI_MAX,TEKI_Gmax ;配置X dim TEKI_y,TEKI_MAX,TEKI_Gmax ;配置Y dim TEKI_NO_GID,TEKI_GOKEI ;敵スプライトNOを使って敵グループインデックス用 (スプライトの最大数) dim TEKI_NO_DID,TEKI_GOKEI ;敵スプライトNOを使って敵データインデックス格納用 (スプライトの最大数) dim TEKI_IDO_f,TEKI_MAX,TEKI_Gmax ;移動フラグ dim TEKI_TIM,TEKI_GOKEI ;出現する時間 ;▼▼▼▼▼▼▼敵配列▼▼▼▼▼▼▼ ;グループ1 右上 TEKI_x(0,0) = 390,390,390,390,390 TEKI_y(0,0) = -10,-50,-90,-130,-170 ;グループ2 左上 TEKI_x(0,1) = 40,40,40,40,40 TEKI_y(0,1) = -10,-50,-90,-130,-170 ;敵出現時間 TEKI_TIM = 100,300 ;■■■敵配置■■■ repeat TEKI_Gmax ;グループ数(22) TEK_G = cnt repeat TEKI_MAX ;敵の最大数(5) es_exnew TEKI ,80,190 ;新規スプライトNo es_set TEKI, TEKI_x(cnt,TEK_G),TEKI_y(cnt,TEK_G), 80 ;スプライトNo, X,Y座標 ,キャラNo es_flag TEKI,$1100 ;自動削除OFF (スプライト表示ON+ボーダー消去無効ON) es_type TEKI,8192 TEKI_Move(TEKI) = TEK_G TEKI_NO_GID(TEKI) = TEK_G ;スプライトNOをキーにグループインデックス格納 TEKI_DID = TEK_G * TEKI_MAX + cnt ;データインデックス(一次元配列とした場合のインデックス) TEKI_NO_DID(TEKI) = TEKI_DID ;スプライトNOをキーにデータインデックス格納 loop loop ;************メインループ*************** *メイン es_cls ;画面クリア es_draw ;スプライト描画 ;************カウンター****************** pos 420,250 : es_mes "TEKI_D " + TEKI_D pos 420,270 : es_mes "TEKI_HOMIN_no " + TEKI_HOMIN_no ;****************************** ;自機表示 es_set 4000, JIKI_x,JIKI_y, 4000 ;スプライトNo, X,Y座標 ,キャラNo ;************gosub************ gosub *自機ホーミング gosub *敵移動 es_sync ;画面更新 await 16 goto *メイン ;*************自機ホーミング**************** *自機ホーミング getkey keyZ,90 ;Zキー if keyZ AND JK_HMIN_f = 0 { JK_HMIN_f = 1 ;ホーミングフラグを【立てる】 JK_HMIN_x = double(JIKI_x) : JK_HMIN_y = double(JIKI_y) ;実数値に変換 } if JK_HMIN_f = 1 { ;ホーミングフラグ立ってたら実行 TEKI_no = 80 ;敵の検索開始ナンバ− kyori = 10000.0 ;自機と敵の距離を代入する変数(最も近い敵を探すために出来るだけ大きな数値を入れておく) TEKI_HOMIN_no = -1 ;敵が全員いなかった時にマイナス値を入れることによって、ホーミングが最後の敵に行かないようにする repeat es_find TEKI_D, 4096, TEKI_no,190;画面内の敵を探す if TEKI_D = -1 : break es_get JK_HMIN_TEKI_x,TEKI_D,3 ;敵X es_get JK_HMIN_TEKI_y,TEKI_D,5 ;敵Y if (JK_HMIN_TEKI_x > 30) AND (JK_HMIN_TEKI_y > 10) AND (JK_HMIN_TEKI_x < 412) AND (JK_HMIN_TEKI_y < 460) { ;自機と敵の距離 kyori_2 = sqrt((JIKI_x-JK_HMIN_TEKI_x)*(JIKI_x-JK_HMIN_TEKI_x) + (JIKI_y-JK_HMIN_TEKI_y)*(JIKI_y-JK_HMIN_TEKI_y));ルート値を返す if kyori_2 < kyori { kyori = kyori_2 ;近い敵までの距離を更新 TEKI_HOMIN_no = TEKI_D ;近い敵のスプライト發鮃洪 } }TEKI_no++ ;敵の検索開始ナンバ− loop ;「es_ini」を「6845」以上にするとスプライトエラーが出るので回避したい ;TEKI_HOMIN_no != -1で回避すると、当たり判定「es_check HMIN_VS_TEKI ,TEKI_HOMIN_no,256」でエラーが起きてしまう if TEKI_HOMIN_no != -1 { es_get JK_HMIN_TEKI_x,TEKI_HOMIN_no,3 ;敵X es_get JK_HMIN_TEKI_y,TEKI_HOMIN_no,5 ;敵Y es_set 55, JK_HMIN_x+5,JK_HMIN_y , 55 ;スプライト設定 es_chr TEKI_HOMIN_no, 80 ;初期状態 } es_type 55,256 angle = 0.0 ;角度を入れる変数 if TEKI_HOMIN_no != -1 { ;敵がいる場合 angle = atan(JK_HMIN_TEKI_y - JK_HMIN_y, JK_HMIN_TEKI_x - JK_HMIN_x-10) ;敵とホーミングとの角度を求める JK_HMIN_x += 8.0 * cos(angle) : JK_HMIN_y += 8.0 * sin(angle) ;弾速さ } else { ;敵がいない場合 JK_HMIN_x += 8.0 * cos(deg2rad(270)) : JK_HMIN_y += 8.0 * sin(deg2rad(270));正面に真っ直ぐ進む } ;当たり判定 if (JK_HMIN_TEKI_x > 30) AND (JK_HMIN_TEKI_y > 10) AND (JK_HMIN_TEKI_x < 412) AND (JK_HMIN_TEKI_y < 460) { es_check HMIN_VS_TEKI ,TEKI_HOMIN_no,256 if HMIN_VS_TEKI != -1 { JK_HMIN_f = 0 ;ホーミングフラグ【削除】 es_kill TEKI_HOMIN_no ;敵【削除】 es_kill HMIN_VS_TEKI ;ホーミング【削除】 TEKI_HIT_no = TEKI_HOMIN_no ;アイテム es_chr TEKI_HOMIN_no, 81 ;ヒットしたら赤くする TEKI_Ef_f = 1 ;敵エフェクトフラグ HMIN_HIT++ ;デバッグ用 } } } es_get JK_HMIN_TEKI_x,55,3 ;ホーミングX es_get JK_HMIN_TEKI_y,55,5 ;ホーミングY if (JK_HMIN_TEKI_x < 30-17) or (JK_HMIN_TEKI_y < 10-19) or (JK_HMIN_TEKI_x > 412+17) or (JK_HMIN_TEKI_y > 460+19) { JK_HMIN_f = 0 ;ホーミングフラグを【戻す】 } return ;*************敵移動**************** *敵移動 if TEKI_TIM_c < 2800 : TEKI_TIM_c += 1 ;敵出現カウンター dup TEKI_Move_f,TEKI_IDO_f ;枠外 (↓に移動する) TEKI_no = 80 ;敵スプライト検索開始NO repeat es_find TEKI_D, 8192, TEKI_no,190, 1 if TEKI_D < 0 : break es_get TEKI_pos_x,TEKI_D,3 ;敵X es_get TEKI_pos_y,TEKI_D,5 ;敵Y TEK_G = TEKI_NO_GID(TEKI_D) ;敵スプライトNOをキーにグループインデックス取り出し TEKI_DID = TEKI_NO_DID(TEKI_D) ;敵スプライトNOをキーに敵データインデックス取り出し if TEKI_Move_f(TEKI_DID) = 0 { TAMA_NO_DID(TEKI_IDO) = TEKI_DID;弾のスプライトNOをキーに敵データインデックス格納(これで弾と敵データとの紐付) if TEKI_f(cnt) = 0 { ;1グループ if TEKI_TIM_c >= TEKI_TIM(TEK_G) { if TEK_G = 0 { es_apos TEKI_D, 0,1, 200 ;200のスピードで↓に移動する } } ;2グループ if TEKI_TIM_c >= TEKI_TIM(TEK_G) { if TEK_G = 1 { es_apos TEKI_D, 0,1, 200 ;200のスピードで↓に移動する } } ;---枠内 (type書き換え)--- if (TEKI_pos_x > 30) AND (TEKI_pos_y > 10) AND (TEKI_pos_x < 412) AND (TEKI_pos_y < 460) { es_get TEKI_flag,TEKI_D,0 ;敵のflag値を「取得」 es_type TEKI_D,4096 ;画面内のtype値設定 } } }TEKI_no++ ;敵の検索開始ナンバ− loop return



この記事に返信する


usagi

リンク

2022/1/13(Thu) 01:52:26|NO.94989

>es_iniで9100ぐらいスプライトを確保できるようにしたい
確保が直接的な原因でなく、処理の流れを追ってみるとおそらく
es_checkの第2引数には有効なスプライトナンバーを設定しますので、
TEKI_HOMIN_noが-1の時にはエラー落ちしてしまうことが原因かと思われます。
※同様es_killなども-1は使えない。

>Zキーを押している間にホーミングが発射されない。
入れ子になったif Teki_HOMIN_no != -1 { の最初の部分で弾発射の処理がスキップされているからかと思います。

アイドルさんのスクリプトの条件下だと以下の部分を例として書き換えてみました。
引数が-1で仕様として無効な部分を回避しつつ、発射の処理はスキップしないように入れ替えました。


;「es_ini」を「6845」以上にするとスプライトエラーが出るので回避したい ;TEKI_HOMIN_no != -1で回避すると、当たり判定「es_check HMIN_VS_TEKI ,TEKI_HOMIN_no,256」でエラーが起きてしまう ;■■■■■ココから es_set 55, JK_HMIN_x+5,JK_HMIN_y , 55 ;スプライト設定 es_type 55,256 if TEKI_HOMIN_no != -1 { ;敵がいる場合 es_get JK_HMIN_TEKI_x,TEKI_HOMIN_no,3 ;敵X es_get JK_HMIN_TEKI_y,TEKI_HOMIN_no,5 ;敵Y es_chr 55, 80 ;初期状態 angle = 0.0 ;角度を入れる変数 angle = atan(JK_HMIN_TEKI_y - JK_HMIN_y, JK_HMIN_TEKI_x - JK_HMIN_x-10) ;敵とホーミングとの角度を求める JK_HMIN_x += 8.0 * cos(angle) : JK_HMIN_y += 8.0 * sin(angle) ;弾速さ } else { ;敵がいない場合 JK_HMIN_x += 8.0 * cos(deg2rad(270)) : JK_HMIN_y += 8.0 * sin(deg2rad(270));正面に真っ直ぐ進む } ;当たり判定 if (JK_HMIN_TEKI_x > 30) AND (JK_HMIN_TEKI_y > 10) AND (JK_HMIN_TEKI_x < 412) AND (JK_HMIN_TEKI_y < 460) { if TEKI_HOMIN_no != -1 { es_check HMIN_VS_TEKI ,TEKI_HOMIN_no,256 if HMIN_VS_TEKI != -1 { JK_HMIN_f = 0 ;ホーミングフラグ【削除】 es_kill TEKI_HOMIN_no ;敵【削除】 es_kill HMIN_VS_TEKI ;ホーミング【削除】 TEKI_HIT_no = TEKI_HOMIN_no ;アイテム es_chr TEKI_HOMIN_no, 81 ;ヒットしたら赤くする TEKI_Ef_f = 1 ;敵エフェクトフラグ HMIN_HIT++ ;デバッグ用 } } } } ;■■■■■ココまで

余談ですが、スプライトの数が9100は多いような気がしまして、
昔のアーケード弾幕シューティングでも128〜256程度かと思いまして
東方を例にすると、紅魔郷で256,妖々夢で512程度なので(最近は2048くらい?)
パターンはあくまで画像の管理、
スプライトは画面上で表示する管理とすると数も減らせますし、
もうすこしシンプルに管理しやすくなるかと思いました。

例)スプライトの番号帯の一例
0〜15 : 16個 自機、オプション 、 敵と敵弾とアイテムと当たりをとる
16〜80 : 64個 自機弾 、 敵と当たりをとる
81〜144 : 64個 敵 、 自機と自機弾と当たりをとる
145〜657 : 512個 敵弾 、 自機と当たりをとる
658〜722 : 64個 アイテム 、 自機と当たりをとる
723〜979 : 256個 エフェクト 、  当たりをとらない



アイドル

リンク

2022/1/13(Thu) 22:23:21|NO.95013

usagiさん回答ありがとうございます!

>es_checkの第2引数には有効なスプライトナンバーを設定しますので、
>TEKI_HOMIN_noが-1の時にはエラー落ちしてしまうことが原因かと思われます。
>※同様es_killなども-1は使えない。
しまったそんなルールが!

TEKI_HOMIN_no = -1 ;敵が全員いなかった時にマイナス値を入れることによって、ホーミングが最後の敵に行かないようにする
が入っているせいでエラー出ているんだろうなーってのはわかってました。


>入れ子になったif Teki_HOMIN_no != -1 { の最初の部分で弾発射の処理がスキップされているからかと思います。
そうなんですよねー。
if文で実行しないようになっちゃうからどうしようかなと。


>引数が-1で仕様として無効な部分を回避しつつ、発射の処理はスキップしないように入れ替えました。
あーなるほどこうすればよかったのか!
っていうかif文余計に1個ありましたねw
これなら要件も満たせるしエラーもでなくっていいですね。


>余談ですが、スプライトの数が9100は多いような気がしまして、
やっぱそうですよねー。

あくまで9100はデッドラインとしています。
実際には90スクリプト以上でない仕様にしています。

管理する上でこんな感じにしているだけですね。

 「自機」
自機:3000
低速移動:78
自機弾:10〜30
低速弾:35
低速グラフィック:65〜74
ホーミング:55
明るい立ち絵:280〜290
明るい立ち絵:610
暗い立ち絵:615

「ボス1」
ボス1:2201
スペカ名:1120
スペカ絵:1121
ボス名:310
2の名前:311
赤札:1000
3wye:1000〜1002
円形:1010〜1033
スペカ:1500〜1547
結界:1600→4100
P、点:1440
撃破点数:110
会話:420
撃破後会話:590


「ボス2」
ボス2:2200



アイドル

リンク

2022/1/15(Sat) 16:22:10|NO.95063

解決に入れるの忘れてました。
解決です!

いつもアドバイスありがとうございます!!



記事削除

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

NO.94931への返信

マスコット

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

名前

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

削除用パスワード

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

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

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