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


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0912
アイドル【hspdxfix.as】ホーミング(追尾弾)の作り方8解決


アイドル

リンク

2020/9/12(Sat) 15:49:58|NO.91344

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


自機のホーミング弾を作ってみたのですが、2発目の発射先が1発目と同じ座標になってしまいます。
原因はさっぱりわかりません・・・・

1発目はスプライト80〜84の中から自機と近いやつに発射します。
2発目も同じサイクルになっていると思うんですが、何故かうまくいかず・・・
アドバイス等あればよろしくおねがいします!


 ■仕様■
1.ホーミングは1発しか打てない
2.敵 or 画面外に行ったら、ホーミング弾を消して再発射
3.ホーミングは自機から近い敵に移動する


#include "hspdxfix.as" ;DXライブラリ使用 width ,,130,200 ;ウィンドウの位置 es_ini 640,5000,360 ;スプライトの最大数、キャラクタ定義の最大数,周の精度(180*2) es_screen 640,480 ,0,0,1,1 ;スクリーン es_window 30,10, 412,460 ;スプライト表示エリア設定 es_area 10,-10, 432,480 ;スプライト有効エリア設定 ;---自機--- es_size 28,42, 100 es_pat 350, 0,0 JIKI_x = 256 : JIKI_y = 390 JIKISpd = 4 ;移動スピード ;---ホーミング--- es_size 17,19, 100 es_pat 55, 56,62 ;---敵--- es_size 18,19, 50 es_pat 60, 0,0 ;敵配置 TEKI_MAX = 5 ;敵の最大数 dim TEKI_f,TEKI_MAX dim TEKI_x,TEKI_MAX dim TEKI_y,TEKI_MAX ;▼▼▼▼▼▼▼敵配列▼▼▼▼▼▼▼ TEKI_x = 50,100,150,200,250 TEKI_y = 190,150,110,70,30 ;■■■敵配置■■■ repeat TEKI_MAX ;敵の最大数(5) es_exnew TEKI ,80,84 ;新規スプライトNo es_set TEKI, TEKI_x(cnt),TEKI_y(cnt), 60 ;スプライトNo, X,Y座標 ,キャラNo es_type TEKI,4096 loop ;*********メインループ********* *メイン es_cls ;画面クリア es_draw ;スプライト描画 ;***********カウンター*************** pos 400,280 : es_mes "ヒットした回数 " + HMIN_HIT pos 400,300 : es_mes "ホーミングF " + JK_HMIN_f ;*************メインループ**************** gosub *自機の移動 gosub *自機ホーミング gosub *敵移動 es_set 350, JIKI_x,JIKI_y, 350 ;自機 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キー ;弾が出る場所 if keyZ AND JK_HMIN_f = 0 { JK_HMIN_f = 1 ;ホーミングフラグを【立てる】 JK_HMIN_x = double(JIKI_x) : JK_HMIN_y = double(JIKI_y) ;実数値に変換 } TEKI_no = 80 ;敵の検索開始ナンバ− repeat TEKI_MAX ;敵の最大数(5) es_get JK_HMIN_TEKI_x,TEKI_no,3 ;敵X es_get JK_HMIN_TEKI_y,TEKI_no,5 ;敵Y if JK_HMIN_f = 1 { ;ホーミングフラグ立ってたら実行 es_set 55, JK_HMIN_x,JK_HMIN_y , 55 ;スプライト設定 es_type 55,2 angle = 0.0 ;角度を入れる変数 angle = atan(JK_HMIN_TEKI_x - JK_HMIN_x-10, JK_HMIN_TEKI_y - JK_HMIN_y) ;敵とホーミングとの角度を求める JK_HMIN_x += 1.0 * sin(angle) : JK_HMIN_y += 1.0 * cos(angle) ;弾速さ TEKI_no++ ;敵の検索開始ナンバ− } loop ;画面外 es_get JK_HMIN_TEKI_x,55,3 ;ホーミングX es_get JK_HMIN_TEKI_y,55,5 ;ホーミングY if (JK_HMIN_TEKI_x < -33) or (JK_HMIN_TEKI_y < -58) or (JK_HMIN_TEKI_x > 435) or (JK_HMIN_TEKI_y > 488) { JK_HMIN_f = 0 ;ホーミングフラグを【戻す】 } ;当たり判定 TEKI_no = 80 ;敵の検索開始ナンバ− repeat TEKI_MAX ;敵の最大数(5) es_find TEKI_D, 4096, TEKI_no,84;敵を探す es_check HMIN_VS_TEKI ,TEKI_D,2 if HMIN_VS_TEKI != -1 & TEKI_f(cnt) = 0 { TEKI_f(cnt) = 1 ;敵フラグ【立てる】 JK_HMIN_f = 0 ;ホーミングフラグ【削除】 es_kill TEKI_D ;敵【削除】 es_kill HMIN_VS_TEKI;ホーミング【削除】 HMIN_HIT++ ;デバッグ用 }TEKI_no++ ;敵の検索開始ナンバ− loop /* ;・敵が動くとダメ ;・最後尾の番号が優先されるので、自機に近い敵に弾が行くようにしたい TEKI_no = 80 ;敵の検索開始ナンバ− repeat TEKI_MAX ;敵の最大数(5) es_get JK_HMIN_JIKI_x,350,3 ;自機X es_get JK_HMIN_JIKI_y,350,5 ;自機Y es_get JK_HMIN_TEKI_x,TEKI_no,3 ;敵X es_get JK_HMIN_TEKI_y,TEKI_no,5 ;敵Y es_ang JK_HMIN_JIKI_x,JK_HMIN_JIKI_y,JK_HMIN_TEKI_x-7,JK_HMIN_TEKI_y;基準点x,基準点y,目的点x,目的点y JK_HMIN_ang(cnt) = stat ;敵の方向 ;*******弾発射******* es_exnew JK_HMIN_hs, 55,55 ;新規スプライト取得 es_set JK_HMIN_hs, JK_HMIN_JIKI_x+6,JK_HMIN_JIKI_y+5, 55 ;スプライト設定 es_adir JK_HMIN_hs, JK_HMIN_ang(cnt),500 ;スプライト移動方向設定 es_type JK_HMIN,2 TEKI_no++ ;敵の検索開始ナンバ− loop */ return ;*************敵移動**************** *敵移動 TEKI_no = 80 ;敵の検索開始ナンバ− repeat TEKI_MAX ;敵の最大数(5) ; es_apos TEKI_no, 0,1, 100 ;100のスピードで↓に移動する TEKI_no++ ;敵の検索開始ナンバ− loop return



この記事に返信する


あらや

リンク

2020/9/21(Mon) 01:24:01|NO.91412

仕様が不明な所は作っていませんが
こんな感じではいかがでしょうか?


;*************自機ホーミング**************** *自機ホーミング 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; // 自機と敵の距離を代入する変数(最も近い敵を探すために出来るだけ大きな数値を入れておく) chikaiteki = -1; // 最も近い敵のスプライト發鯊綟する変数 repeat TEKI_MAX ;敵の最大数(5) es_find TEKI_D, 4096, TEKI_no,84;敵を探す if( TEKI_D == -1 ) : break; es_get JK_HMIN_TEKI_x,TEKI_no,3 ;敵X es_get JK_HMIN_TEKI_y,TEKI_no,5 ;敵Y // 自機と敵の距離 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; // 近い敵までの距離を更新 chikaiteki = TEKI_D // 近い敵のスプライト發鮃洪 } TEKI_no++; loop // 上のループで最も近い敵のスプライト發わかっているので、 // それを元に弾を作成するのでループは不要 ;repeat TEKI_MAX ;敵の最大数(5) es_get JK_HMIN_TEKI_x,chikaiteki,3 ;敵X es_get JK_HMIN_TEKI_y,chikaiteki,5 ;敵Y es_set 55, JK_HMIN_x,JK_HMIN_y , 55 ;スプライト設定 es_type 55,2 angle = 0.0 ;角度を入れる変数 if( chikaiteki != -1 ) { // 敵がいる場合 angle = atan(JK_HMIN_TEKI_x - JK_HMIN_x-10, JK_HMIN_TEKI_y - JK_HMIN_y) ;敵とホーミングとの角度を求める JK_HMIN_x += 5.0 * sin(angle) : JK_HMIN_y += 5.0 * cos(angle) ;弾速さ } else { // 敵がいない場合 JK_HMIN_x += 1.0 * sin(deg2rad(180)): JK_HMIN_y += 1.0 * cos(deg2rad(180)); // 正面に真っ直ぐ進む(仮) } ;TEKI_no++ ;敵の検索開始ナンバ− } ;loop

敵が動いている場合や
ホーミング以外の要因で敵が消えた場合(画面外に出るとか他の攻撃で消滅するなど)
それらの状況は考慮していないので、
そのような状況になった場合は何らかの不具合が起きる可能性があります。

敵が動いている場合は単純にホーミング弾をロック中のフラグ変数でも用意して
別の敵に飛んでいかないようにif文で対処出来ると思います。

同様に、敵が何らかの理由で消滅した場合は
画面外に出るまでそれまでの移動を続けるなどの対処が必要になるかと思います。



あらや

リンク

2020/9/21(Mon) 16:44:16|NO.91414

すみません。弾速を勝手に調整したのを忘れていました。


JK_HMIN_x += 5.0 * sin(angle) : JK_HMIN_y += 5.0 * cos(angle) ;弾速さ

この行は5.0を1.0に修正して下さい。。。

それと、同じ行で今気がついたのですが
sinとcosが逆ではないでしょうか?



あらや

リンク

2020/9/21(Mon) 16:47:47|NO.91415

再追記

atanもXとYが逆になっています。



アイドル

リンク

2020/9/21(Mon) 19:27:24|NO.91416

あらやさん、ありがとうございます!!
「ルート値、ラジアン」のことをまったく知らなかったので返答遅れました・・・


なるほど距離を「ルート値で返す」ことによって近い敵に弾が行くようになっているんですね。
敵が全滅している場合は、まっすぐ行くようになってて助かりました。

>>// 上のループで最も近い敵のスプライト發わかっているので、
代入をうまく使えばこんなに省略できるとは・・・

>>敵が動いている場合や
動かすように変更してメインに入れても特に問題なさそうでした!

>>ホーミング以外の要因で敵が消えた場合(画面外に出るとか他の攻撃で消滅するなど)
>>それらの状況は考慮していないので、
>>そのような状況になった場合は何らかの不具合が起きる可能性があります。
自機弾を当てた場合は近くの敵を追尾してれるので大丈夫でした!


 「当たり判定問題」
メインソースでは敵配置を画面外(プレイヤー移動できない)においているせいで、
画面内に敵が存在しないとき、画面外の敵にあたってしまう問題が。

・「自機と敵の距離」を図る前に、敵が画面内にいるか見るようにしました。
・当たり判定も画面内にいる敵のみにしました。

 「追尾問題」
上記をやっても画面外にいる敵に追尾しちゃっているので手を加えます。
多分これが原因で敵がいないときに、ホーミング弾を打ってからいい感じに自機を上下に移動すると、
ホーミングも上下に移動しちゃいますね・・・まぁ、ちゃんと敵をいないってすれば解決できると思います
--------
>>すみません。弾速を勝手に調整したのを忘れていました。
問題ないです!敵に追いつけない可能性があるので少し早くするかもです。

>>sin、cos、atanのXとYが逆
ぎゃああああああああああ!
過去のソースをそのまま流用した結果です・・・よく動いてた・・・orz

逆なのを修正したので「(deg2rad(180)」の180を「270」に修正しました。
--------
追加、変更したところが地味にありますが、大体は同じです。

#include "hspdxfix.as" ;DXライブラリ使用 width ,,130,200 ;ウィンドウの位置 es_ini 640,5000,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 350, 0,0 JIKI_x = 256 : JIKI_y = 390 JIKISpd = 4 ;移動スピード ;---自機弾--- es_size 11,11, 150 es_pat 51, 1,43 ;---ホーミング--- es_size 17,19, 100 es_pat 55, 56,62 ;---敵--- es_size 18,19, 50 es_pat 60, 0,0 ;自機が動ける範囲 ;--上-- 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 ;敵配置 TEKI_MAX = 6 ;敵の最大数 dim TEKI_f,TEKI_MAX dim TEKI_x,TEKI_MAX dim TEKI_y,TEKI_MAX ;▼▼▼▼▼▼▼敵配列▼▼▼▼▼▼▼ TEKI_x = 50,100,150,200,250 ,115 TEKI_y = 190,150,110,70,30 ,465 ;■■■敵配置■■■ repeat TEKI_MAX ;敵の最大数(6) es_exnew TEKI ,80,85 ;新規スプライトNo es_set TEKI, TEKI_x(cnt),TEKI_y(cnt), 60 ;スプライトNo, X,Y座標 ,キャラNo es_flag TEKI,$1100 ;自動削除OFF (スプライト表示ON+ボーダー消去無効ON) es_type TEKI,4096 loop ;*********メインループ********* *メイン es_cls ;画面クリア es_draw ;スプライト描画 ;***********カウンター*************** pos 420,200 : es_mes "ホーミングヒット " + HMIN_HIT pos 420,220 : es_mes "ホーミングF " + JK_HMIN_f pos 420,240 : es_mes "kyori_2 " + kyori_2 pos 420,260 : es_mes "kyori " + kyori pos 420,290 : es_mes "JIKI_x " + JIKI_x pos 420,310 : es_mes "JIKI_y " + JIKI_y pos 420,330 : es_mes "TEKI_HOMIN_no " + TEKI_HOMIN_no pos 420,350 : es_mes "HMIN_HIT " + HMIN_HIT ;*************メインループ**************** gosub *自機の移動 gosub *自機弾移動 gosub *自機ホーミング gosub *敵移動 es_set 350, JIKI_x,JIKI_y, 350 ;自機 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 ;弾の間隔 ;---画面外判定--- JK_TAMA_no = 10 ;自機弾の検索開始ナンバー repeat es_find JK_TAM_D, 2, JK_TAMA_no,30, 1 if JK_TAM_D < 0 : break es_get JK_TAM_D_y,JK_TAM_D,5 ;自機弾Y if JK_TAM_D_y < 0 : es_kill JK_TAM_D ;自機弾【削除】 JK_TAMA_no++ ;自機弾の検索開始ナンバー loop ;当たり判定 TEKI_no = 80 ;敵の検索開始ナンバ− repeat TEKI_MAX ;敵の最大数(5) es_find TEKI_D, 4096, TEKI_no,85;敵を探す es_check JKTM_VS_TEKI ,TEKI_D,2 if JKTM_VS_TEKI != -1 & TEKI_f(cnt) = 0 { TEKI_f(cnt) = 1 ;敵フラグ【立てる】 es_kill TEKI_D ;敵【削除】 es_kill JKTM_VS_TEKI;自機弾【削除】 JK_HIT++ ;デバッグ用 }TEKI_no++ ;敵の検索開始ナンバ− loop return ;*************自機ホーミング**************** *自機ホーミング ;弾が出る場所 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,85;敵を探す if TEKI_D = -1 : break es_get JK_HMIN_TEKI_x,TEKI_no,3 ;敵X es_get JK_HMIN_TEKI_y,TEKI_no,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));ルート値を返す ;256-50 = 42436, 390-190 = 40000 → 82436→287.116 ;256-100 = 24336, 390-150 = 57600 → 81936→286.244 ;256-150 = 11236, 390-110 = 78400 → 89636→299.392 ;256-200 = 3136, 390-70 = 102400 → 105536→324.863 ;256-250 = 16, 390-30 = 129600 → 129616→360.022 ;286.244 < 10000.0 if kyori_2 < kyori { kyori = kyori_2 ;近い敵までの距離を更新 TEKI_HOMIN_no = TEKI_D ;近い敵のスプライト發鮃洪 } } TEKI_no++ ;敵の検索開始ナンバ− loop 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,JK_HMIN_y , 55 ;スプライト設定 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 += 5.0 * cos(angle) : JK_HMIN_y += 5.0 * sin(angle) ;弾速さ } else { ;敵がいない場合 JK_HMIN_x += 5.0 * cos(deg2rad(270)) : JK_HMIN_y += 5.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;ホーミング【削除】 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) or (JK_HMIN_TEKI_y < 10) or (JK_HMIN_TEKI_x > 412) or (JK_HMIN_TEKI_y > 460) { JK_HMIN_f = 0 ;ホーミングフラグを【戻す】 } return ;*************敵移動**************** *敵移動 TEKI_no = 80 ;敵の検索開始ナンバ− repeat es_find TEKI_D, 4096, TEKI_no,85 if TEKI_D < 0 : break ; es_apos TEKI_D, 0,1, 100 ;100のスピードで↓に移動する TEKI_no++ ;敵の検索開始ナンバ− loop return



アイドル

リンク

2020/9/21(Mon) 22:47:29|NO.91418

「■■■敵配置■■■」時に画面外専用の「es_type」を宣言する(TEKI,8192)
「*敵移動」のとき、画面内にいる敵のみ実行するして「es_type」を変更する(TEKI_D,4096)
「*自機ホーミング」のとき、「es_find」で「4096」を探す

こうすることによって、画面内にいる敵にしか行かないようになったはず
過去に質問した内容がここにきて約にたった。
あのときは何となく成分が多かったけど、今になってより理解できた。

メインソースに突っ込んで問題ないか見てみます。



アイドル

リンク

2020/9/23(Wed) 13:26:43|NO.91438

ようやくメインソースに入れても問題ないことを確認できました。


「type値」を途中で変えるため、仕様変更しなきゃいけない箇所が3箇所ぐらい発生しました。
そして変更箇所を含めた動作でようやく「不具合が出ない、仕様通り」なものを作れました。

・type値8192を準備値とし、枠外での動きを決める
・動きを決めたら「type値」を画面内の4096に変更
・type値4096を検索して、枠内での動きを決めて、「当たり判定、画面外で削除」の処理をする

こういうふうに準備することによって、
敵が画面内で動いて画面外に移動しても、ホーミングが画面外に行かないようになりました。
多分これで問題ないと思いますが、「こうしたほうが良いよ」「こういう場合こういうこと起きそう」などありましたら、
アドバイスなどお願いします。

っていうのもホーミング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 -13,-43, 640,480 ;スプライト表示エリア設定 es_area -36,-430, 600,498 ;スプライト有効エリア設定 ;---自機--- es_size 28,42, 100 es_pat 350, 0,0 JIKI_x = 256 : JIKI_y = 390 JIKISpd = 4 ;移動スピード ;---自機弾--- es_size 11,11, 150 es_pat 51, 1,43 ;---ホーミング--- es_size 17,19, 100 es_pat 55, 56,62 ;---敵--- es_size 18,19, 50 es_pat 60, 0,0 ;自機が動ける範囲 ;--上-- 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 ;敵配置 TEKI_MAX = 6 ;敵の最大数 dim TEKI_f,TEKI_MAX ;フラグ dim TEKI_x,TEKI_MAX ;配置X dim TEKI_y,TEKI_MAX ;配置Y ;▼▼▼▼▼敵配列▼▼▼▼▼ TEKI_x = 50,100,150,200,250 ,115 TEKI_y = 190,150,110,70,30 ,465 ;■■■■■敵配置■■■■■ repeat TEKI_MAX ;敵の最大数(6) es_exnew TEKI ,80,85 ;新規スプライトNo es_set TEKI, TEKI_x(cnt),TEKI_y(cnt), 60 ;スプライトNo, X,Y座標 ,キャラNo es_flag TEKI,$1100 ;自動削除OFF (スプライト表示ON+ボーダー消去無効ON) es_type TEKI,8192 loop ;*********メインループ********* *メイン es_cls ;画面クリア es_draw ;スプライト描画 ;***********カウンター*************** pos 420,180 : es_mes "自機弾_ヒット " + JK_HIT pos 420,200 : es_mes "ホーミング_ヒット " + HMIN_HIT pos 420,220 : es_mes "ホーミング_フラグ " + JK_HMIN_f pos 420,250 : es_mes "kyori_2 " + kyori_2 pos 420,270 : es_mes "kyori " + kyori pos 420,290 : es_mes "TEKI_HOMIN_no " + TEKI_HOMIN_no pos 420,320 : es_mes "JIKI_x " + JIKI_x pos 420,340 : es_mes "JIKI_y " + JIKI_y ;*************メインループ**************** gosub *自機の移動 gosub *自機弾移動 gosub *敵移動 gosub *自機ホーミング es_set 350, JIKI_x,JIKI_y, 350 ;自機 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 ;弾の間隔 ;---画面外判定--- JK_TAMA_no = 10 ;自機弾の検索開始ナンバー repeat es_find JK_TAM_D, 2, JK_TAMA_no,30, 1 if JK_TAM_D < 0 : break es_get JK_TAM_D_y,JK_TAM_D,5 ;自機弾Y if JK_TAM_D_y < 0 : es_kill JK_TAM_D ;自機弾【削除】 JK_TAMA_no++ ;自機弾の検索開始ナンバー loop return ;*************敵移動**************** *敵移動 ;枠外 (↓に移動する) 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 es_apos TEKI_D, 0,1, 100 ;100のスピードで↓に移動する ;---枠内 (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 ;枠内 (途中移動) TEKI_no = 80 ;敵の検索開始ナンバ− repeat es_find TEKI_D, 4096, 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 if TEKI_pos_y >= 300 { es_apos TEKI_D, -1,0, 200 ;200のスピードで←に移動する } ;---当たり判定--- es_check JKTM_VS_TEKI ,TEKI_D,2 if JKTM_VS_TEKI != -1 & TEKI_f(cnt) = 0 { TEKI_f(cnt) = 1 ;敵フラグ【立てる】 es_kill TEKI_D ;敵【削除】 es_kill JKTM_VS_TEKI;自機弾【削除】 JK_HIT++ ;デバッグ用 } ;---画面外--- if (TEKI_pos_x < 30-18) or (TEKI_pos_y < 10-19) or (TEKI_pos_x > 412+18) or (TEKI_pos_y > 460+19) { es_kill TEKI_D ;敵【削除】 }TEKI_no++ ;敵の検索開始ナンバ− loop return ;*************自機ホーミング**************** *自機ホーミング 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_no,3 ;敵X es_get JK_HMIN_TEKI_y,TEKI_no,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_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_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;ホーミング【削除】 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



あらや

リンク

2020/9/25(Fri) 17:17:46|NO.91443

一旦全て完成させてから実行してみて初めてバグが見つかったりするので
何とも言えませんが。

ホーミングに関して
毎ループ一番自機に近い敵をターゲットにしているので
自機も敵も動いている場合には
敵が多いと不自然な動きになる可能性があります。

大げさな例:
左端と右端に敵がいて自機を左右に動かした時
最初は仮に左の敵にホーミングが飛んで行くとして、
自機を右に動かしたら左に進んでいたホーミングが突然右に動き出す
(180度進む方向が変わる)など。

こういう動きは不具合なのか仕様なのか判断しにくいのですが、
場合によってはホーミングの動きがおかしく見えるかもしれません。



アイドル

リンク

2020/9/25(Fri) 19:02:25|NO.91444

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


やはりそんな感じでしたか・・・
実はメインソースにいれて挙動が少しおかしいところがありました。
これをコントロールするのは難しそうなので仕様にしちゃいましたね・・・

ちなみにおっしゃるとおりの場面で発生します。
左右から敵が中心に向かって移動している最中にホーミングをすると、
ホーミングが左右に動くときがあります。

これは敵を倒したり、自機が動いたり、自機弾で倒せばホーミングの動作に大体戻ります。


メインソース完成がリプレイとマージのみになったので完成したらみんなにプレイしてほしいですね!
まぁボス以外を軽量化ですが!!!
メインになったら都度解決する方針で解決にしておきます。
本当にありがとうございます!



記事削除

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

NO.91344への返信

マスコット

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

名前

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

削除用パスワード

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

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

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