STGにおけるホーミング弾の角度について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
プラム
記事: 164
登録日時: 6年前
住所: 東海地方

STGにおけるホーミング弾の角度について

#1

投稿記事 by プラム » 3年前

C言語とDxLibを用いてシューティングゲームを作っているんですが、少し引っかかったことがあります。

STGの自機のショットに「ホーミング」というのがありますよね、
東方や、いろいろなゲームでは、説明が難しいのですが、最初はある特定の角度で発射されて、
そこから角度がプラスマイナスされて、ショットの角度が敵の位置の方向を向くようになるような演出をしてみたいんですが、

↓この動画の自機の高速のオプションのショットが例(見にくいですが)

[youtube][/youtube]

そこで、このようなコードを作ってみたのですが、

コード:

#include "main.h"
#include <math.h>

#define PI 3.141592 //円周率定義
#define AnglePlusSpeed 0.02 //回転度が変わるスピード
#define ShotSpeed 10.0

//弾に関する構造体
typedef struct{

	bool flag;     ///存在フラグ
	double Angle;    ///回転度
	double x,y;    //座標
	
}shot;
typedef struct{

        double x,y;    //座標
	
}Posion;

shot plshot; //プレイヤーショット
Posion Target;  //ターゲットの座標

void HomingShot(){             //ホーミング関数

         if(/*Zキーが押されたら(省略)*/){    //ショット発射
               plshot.flag=1;
               plshot.x=200;
               plshot.y=300;
               plshot.Angle=PI+(PI/2);
         }

         if(plshot.flag==1){
               double Angle=atan2(Target.y-plshot.y,Taeget.x-plshot.x);  //Targetの座標の方向にAngleを設定
               
               if(plshot.Angle>Angle){ //もし、ショットの回転度がAngleより大きいならば
                      plshot.Angle-=AnglePlusSpeed;  //角度をマイナスする

               }
               if(plshot.Angle<Angle){ //もし、ショットの回転度がAngleより小さいならば
                      plshot.Angle+=AnglePlusSpeed; //角度をプラスする

               }

	        plshot.x+=cos( plshot.Angle )*ShotSpeed;  //座標の移動
                plshot.y+=sin( plshot.Angle )*ShotSpeed;  //座標の移動
         }

}

このようなコードを実行してみると、いろいろと角度が荒ぶったり、一回転したりします。(説明が下手ですいません)

何故なのでしょうか。
発射時のplshot.Angleの設定が悪いんでしょうか・・・Angleの設定が悪いんでしょうか・・・・
最後に編集したユーザー プラム on 2016年2月22日(月) 21:09 [ 編集 1 回目 ]

アバター
へにっくす
記事: 628
登録日時: 7年前
住所: 東京都

Re: STGにおけるホーミング弾の角度について

#2

投稿記事 by へにっくす » 3年前

とりあえずファイル出力してどういう値になるのか見てみたら?
atan2の返す値は±π(±180度)だということを忘れずに。

上記のコードを単純にファイル出力するサンプル(VS2015 Communityで動作確認)

コード:

// ConsoleApplication1.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

#define _USE_MATH_DEFINES
#include <math.h>
#include <stdio.h>

int main()
{
	FILE *fp;
	struct {
		double x, y;
		double angle;
	} shot;

	struct {
		double x, y;
	} target;

	// ショットの初期値
	shot.x = 200;
	shot.y = 300;
	shot.angle = M_PI + M_PI / 2; // あなたのコードはPI + (DX_PI/2)でしたがPIもDX_PIも同じ3.14・・・ですよ。

	// ターゲットの初期値(とりあえず適当な値)
	target.x = 500;
	target.y = 500;

	_tfopen_s(&fp, _T("test.txt"), _T("w"));

	for (int i = 0; i < 100; i++) {
		double ang = atan2(target.y - shot.y, target.x - shot.x);
		if (shot.angle > ang) {
			shot.angle -= 0.2; // 0.02→0.2
		}
		if (shot.angle < ang) {
			shot.angle += 0.2; // 0.02→0.2
		}
		shot.x += cos(shot.angle) * 10; // これはそのまま
		shot.y += sin(shot.angle) * 10; // それはそのまま
		fprintf(fp, "%3d x=%5.1f y=%5.1f ang=%6.3f(%6.1f) [%6.3f(%6.1f)] dis=%6.1f\n",
			i, shot.x, shot.y, // ショット位置
				shot.angle, shot.angle * 180.0f/M_PI, // ショットの角度
				ang, ang * 180.0f/M_PI, // ショットから見たターゲットの方向
				sqrt(pow(target.y - shot.y, 2) + pow(target.x - shot.x, 2))); // ショットとターゲットとの距離
	}
	fclose(fp);
	return 0;
}
実行結果です。
まあこれを見てみると、距離が最小値1.8になってからの出力がおかしいですよね?
距離がどんどん離れてるところからしても。(私はこれを、180度の穴と呼んでますw)

コード:

  0 x=198.0 y=290.2 ang= 4.512( 258.5) [ 0.588(  33.7)] dis= 367.7
  1 x=194.1 y=281.0 ang= 4.312( 247.1) [ 0.607(  34.8)] dis= 376.2
  2 x=188.5 y=272.7 ang= 4.112( 235.6) [ 0.621(  35.6)] dis= 385.6
  3 x=181.3 y=265.8 ang= 3.912( 224.2) [ 0.630(  36.1)] dis= 395.5
  4 x=172.9 y=260.4 ang= 3.712( 212.7) [ 0.634(  36.3)] dis= 405.5
  5 x=163.6 y=256.7 ang= 3.512( 201.2) [ 0.632(  36.2)] dis= 415.2
  6 x=153.7 y=255.0 ang= 3.312( 189.8) [ 0.626(  35.9)] dis= 424.2
  7 x=143.7 y=255.3 ang= 3.112( 178.3) [ 0.616(  35.3)] dis= 432.2
  8 x=134.0 y=257.6 ang= 2.912( 166.9) [ 0.602(  34.5)] dis= 439.0
  9 x=124.9 y=261.8 ang= 2.712( 155.4) [ 0.585(  33.5)] dis= 444.4
 10 x=116.8 y=267.7 ang= 2.512( 143.9) [ 0.566(  32.4)] dis= 448.1
 11 x=110.0 y=275.0 ang= 2.312( 132.5) [ 0.545(  31.2)] dis= 450.2
 12 x=104.9 y=283.6 ang= 2.112( 121.0) [ 0.523(  30.0)] dis= 450.5
 13 x=101.5 y=293.0 ang= 1.912( 109.6) [ 0.501(  28.7)] dis= 449.0
 14 x=100.1 y=302.9 ang= 1.712(  98.1) [ 0.479(  27.4)] dis= 445.8
 15 x=100.7 y=312.9 ang= 1.512(  86.7) [ 0.458(  26.2)] dis= 441.0
 16 x=103.3 y=322.6 ang= 1.312(  75.2) [ 0.438(  25.1)] dis= 434.6
 17 x=107.7 y=331.5 ang= 1.112(  63.7) [ 0.421(  24.1)] dis= 427.0
 18 x=113.8 y=339.4 ang= 0.912(  52.3) [ 0.406(  23.2)] dis= 418.2
 19 x=121.4 y=346.0 ang= 0.712(  40.8) [ 0.394(  22.6)] dis= 408.7
 20 x=130.1 y=350.9 ang= 0.512(  29.4) [ 0.386(  22.1)] dis= 398.8
 21 x=138.8 y=355.8 ang= 0.512(  29.4) [ 0.383(  22.0)] dis= 388.9
 22 x=147.5 y=360.7 ang= 0.512(  29.4) [ 0.380(  21.8)] dis= 379.0
 23 x=156.2 y=365.6 ang= 0.512(  29.4) [ 0.376(  21.6)] dis= 369.1
 24 x=165.0 y=370.5 ang= 0.512(  29.4) [ 0.373(  21.4)] dis= 359.2
 25 x=173.7 y=375.4 ang= 0.512(  29.4) [ 0.369(  21.1)] dis= 349.3
 26 x=182.4 y=380.3 ang= 0.512(  29.4) [ 0.365(  20.9)] dis= 339.4
 27 x=191.1 y=385.2 ang= 0.512(  29.4) [ 0.360(  20.7)] dis= 329.5
 28 x=199.8 y=390.1 ang= 0.512(  29.4) [ 0.356(  20.4)] dis= 319.7
 29 x=208.5 y=395.0 ang= 0.512(  29.4) [ 0.351(  20.1)] dis= 309.8
 30 x=217.3 y=399.9 ang= 0.512(  29.4) [ 0.346(  19.8)] dis= 299.9
 31 x=226.0 y=404.8 ang= 0.512(  29.4) [ 0.340(  19.5)] dis= 290.1
 32 x=234.7 y=409.7 ang= 0.512(  29.4) [ 0.334(  19.2)] dis= 280.3
 33 x=243.4 y=414.6 ang= 0.512(  29.4) [ 0.328(  18.8)] dis= 270.4
 34 x=252.1 y=419.5 ang= 0.512(  29.4) [ 0.321(  18.4)] dis= 260.6
 35 x=260.8 y=424.4 ang= 0.512(  29.4) [ 0.314(  18.0)] dis= 250.8
 36 x=270.3 y=427.5 ang= 0.312(  17.9) [ 0.306(  17.5)] dis= 240.8
 37 x=279.9 y=430.6 ang= 0.312(  17.9) [ 0.306(  17.5)] dis= 230.8
 38 x=289.4 y=433.6 ang= 0.312(  17.9) [ 0.306(  17.5)] dis= 220.8
 39 x=298.9 y=436.7 ang= 0.312(  17.9) [ 0.305(  17.5)] dis= 210.8
 40 x=308.4 y=439.8 ang= 0.312(  17.9) [ 0.305(  17.5)] dis= 200.8
 41 x=317.9 y=442.9 ang= 0.312(  17.9) [ 0.304(  17.4)] dis= 190.8
 42 x=327.4 y=445.9 ang= 0.312(  17.9) [ 0.304(  17.4)] dis= 180.8
 43 x=337.0 y=449.0 ang= 0.312(  17.9) [ 0.304(  17.4)] dis= 170.8
 44 x=346.5 y=452.1 ang= 0.312(  17.9) [ 0.303(  17.4)] dis= 160.8
 45 x=356.0 y=455.2 ang= 0.312(  17.9) [ 0.303(  17.3)] dis= 150.8
 46 x=365.5 y=458.2 ang= 0.312(  17.9) [ 0.302(  17.3)] dis= 140.8
 47 x=375.0 y=461.3 ang= 0.312(  17.9) [ 0.301(  17.3)] dis= 130.8
 48 x=384.5 y=464.4 ang= 0.312(  17.9) [ 0.300(  17.2)] dis= 120.8
 49 x=394.1 y=467.5 ang= 0.312(  17.9) [ 0.299(  17.1)] dis= 110.8
 50 x=403.6 y=470.5 ang= 0.312(  17.9) [ 0.298(  17.1)] dis= 100.8
 51 x=413.1 y=473.6 ang= 0.312(  17.9) [ 0.297(  17.0)] dis=  90.8
 52 x=422.6 y=476.7 ang= 0.312(  17.9) [ 0.295(  16.9)] dis=  80.8
 53 x=432.1 y=479.7 ang= 0.312(  17.9) [ 0.293(  16.8)] dis=  70.8
 54 x=441.6 y=482.8 ang= 0.312(  17.9) [ 0.290(  16.6)] dis=  60.8
 55 x=451.2 y=485.9 ang= 0.312(  17.9) [ 0.286(  16.4)] dis=  50.8
 56 x=460.7 y=489.0 ang= 0.312(  17.9) [ 0.281(  16.1)] dis=  40.9
 57 x=470.2 y=492.0 ang= 0.312(  17.9) [ 0.274(  15.7)] dis=  30.9
 58 x=479.7 y=495.1 ang= 0.312(  17.9) [ 0.261(  15.0)] dis=  20.9
 59 x=489.2 y=498.2 ang= 0.312(  17.9) [ 0.236(  13.5)] dis=  10.9
 60 x=498.7 y=501.3 ang= 0.312(  17.9) [ 0.167(   9.6)] dis=   1.8
 61 x=508.7 y=502.4 ang= 0.112(   6.4) [-0.780( -44.7)] dis=   9.0
 62 x=518.6 y=501.5 ang=-0.088(  -5.0) [-2.874(-164.7)] dis=  18.7
 63 x=528.2 y=498.7 ang=-0.288( -16.5) [-3.061(-175.4)] dis=  28.2
 64 x=538.2 y=497.8 ang=-0.088(  -5.0) [ 3.094( 177.3)] dis=  38.2
 65 x=548.1 y=498.9 ang= 0.112(   6.4) [ 3.084( 176.7)] dis=  48.1
 66 x=557.6 y=502.0 ang= 0.312(  17.9) [ 3.119( 178.7)] dis=  57.7
 67 x=567.6 y=503.1 ang= 0.112(   6.4) [-3.107(-178.0)] dis=  67.6
 68 x=577.5 y=502.2 ang=-0.088(  -5.0) [-3.096(-177.4)] dis=  77.6
 69 x=587.1 y=499.4 ang=-0.288( -16.5) [-3.113(-178.3)] dis=  87.1
 70 x=597.1 y=498.5 ang=-0.088(  -5.0) [ 3.135( 179.6)] dis=  97.1
 71 x=607.0 y=499.6 ang= 0.112(   6.4) [ 3.126( 179.1)] dis= 107.0
 72 x=616.5 y=502.7 ang= 0.312(  17.9) [ 3.138( 179.8)] dis= 116.6
 73 x=626.5 y=503.8 ang= 0.112(   6.4) [-3.118(-178.7)] dis= 126.5
 74 x=636.4 y=503.0 ang=-0.088(  -5.0) [-3.111(-178.3)] dis= 136.5
 75 x=646.0 y=500.1 ang=-0.288( -16.5) [-3.120(-178.8)] dis= 146.0
 76 x=654.9 y=495.4 ang=-0.488( -27.9) [-3.141(-180.0)] dis= 154.9
 77 x=664.4 y=492.6 ang=-0.288( -16.5) [ 3.112( 178.3)] dis= 164.6
 78 x=674.4 y=491.7 ang=-0.088(  -5.0) [ 3.097( 177.4)] dis= 174.6
 79 x=684.3 y=492.9 ang= 0.112(   6.4) [ 3.094( 177.3)] dis= 184.5
 80 x=693.9 y=495.9 ang= 0.312(  17.9) [ 3.103( 177.8)] dis= 193.9
 81 x=702.6 y=500.8 ang= 0.512(  29.4) [ 3.121( 178.8)] dis= 202.6
 82 x=712.1 y=503.9 ang= 0.312(  17.9) [-3.138(-179.8)] dis= 212.1
 83 x=722.0 y=505.0 ang= 0.112(   6.4) [-3.123(-178.9)] dis= 222.1
 84 x=732.0 y=504.1 ang=-0.088(  -5.0) [-3.119(-178.7)] dis= 232.0
 85 x=741.6 y=501.3 ang=-0.288( -16.5) [-3.124(-179.0)] dis= 241.6
 86 x=750.4 y=496.6 ang=-0.488( -27.9) [-3.136(-179.7)] dis= 250.4
 87 x=760.0 y=493.8 ang=-0.288( -16.5) [ 3.128( 179.2)] dis= 260.1
 88 x=770.0 y=492.9 ang=-0.088(  -5.0) [ 3.118( 178.6)] dis= 270.1
 89 x=779.9 y=494.0 ang= 0.112(   6.4) [ 3.115( 178.5)] dis= 280.0
 90 x=789.4 y=497.1 ang= 0.312(  17.9) [ 3.120( 178.8)] dis= 289.4
 91 x=798.1 y=502.0 ang= 0.512(  29.4) [ 3.132( 179.4)] dis= 298.1
 92 x=807.7 y=505.1 ang= 0.312(  17.9) [-3.135(-179.6)] dis= 307.7
 93 x=817.6 y=506.2 ang= 0.112(   6.4) [-3.125(-179.1)] dis= 317.6
 94 x=827.5 y=505.3 ang=-0.088(  -5.0) [-3.122(-178.9)] dis= 327.6
 95 x=837.1 y=502.5 ang=-0.288( -16.5) [-3.125(-179.1)] dis= 337.1
 96 x=846.0 y=497.8 ang=-0.488( -27.9) [-3.134(-179.6)] dis= 346.0
 97 x=855.6 y=495.0 ang=-0.288( -16.5) [ 3.135( 179.6)] dis= 355.6
 98 x=865.5 y=494.1 ang=-0.088(  -5.0) [ 3.127( 179.2)] dis= 365.6
 99 x=875.5 y=495.2 ang= 0.112(   6.4) [ 3.125( 179.1)] dis= 375.5
written by へにっくす

アバター
usao
記事: 1566
登録日時: 6年前

Re: STGにおけるホーミング弾の角度について

#3

投稿記事 by usao » 3年前

オフトピック
角度 という値をダイレクトに扱うと,
0度,180度,360度… 等といった "値の境界" (と言えばいいか?)が存在する場合の対処が色々と面倒です.

そういった悩みが少ない方法に置き換えた方が楽なように思います.
例えば
現在の弾の進行方向から見て,相手が右にいるか左にいるか という判定が必要なら外積の符号で判定するとか.

アバター
プラム
記事: 164
登録日時: 6年前
住所: 東海地方

Re: STGにおけるホーミング弾の角度について

#4

投稿記事 by プラム » 3年前

へにっくすさん、ご丁寧に出力結果までありがとうございます。
へにっくす さんが書きました:とりあえずファイル出力してどういう値になるのか見てみたら?
atan2の返す値は±π(±180度)だということを忘れずに。
atan2については、いろいろとggっていたら、atan2が出力する数が+-180°だという事が分かって、

コード:


plshot.Angle=-PI/2; //前のコードはDX_PIとPIが使われていますね。すいません

と初期化することで、初期化角度については解決したのですが。

へにっくす さんが書きました:距離が最小値1.8になってからの出力がおかしいですよね?
距離・・・???それが角度の間違いだとしたら、
角度の最小値1.8(?)になってからの出力は、画面は端に座標がずれていって、角度が0付近を前後しています。
これ180°の穴っていうんですかね。

usaoさんが提案してくださった、別の方法に置き換えるという事ですが、僕のショットの管理方法だと、
現在のショットを管理している部分のプログラムをすべて書き換えなければならないという事になりかねないですし、いろいろとあとから不都合が発生することが予想されるので、できれば今の角度の穴(?)の対策をして実装したいです。

わがままが多くてすいません。

アバター
へにっくす
記事: 628
登録日時: 7年前
住所: 東京都

Re: STGにおけるホーミング弾の角度について

#5

投稿記事 by へにっくす » 3年前

ノウル さんが書きました:
へにっくす さんが書きました:距離が最小値1.8になってからの出力がおかしいですよね?
距離・・・???それが角度の間違いだとしたら、
角度の最小値1.8(?)になってからの出力は、画面は端に座標がずれていって、角度が0付近を前後しています。
これ180°の穴っていうんですかね。
角度の最小値?角度ではありません。私が出した結果で、dis=とあるのは点と点との距離(distance)を示しています。
角度はang=で示しています。
最初の一行目は距離が367.7で、61行目で距離が1.8になり、目標に一番近づいた、ということです。
そこまでは想定した通りの動きですよね。
62行目以降はあなたが言われた通り、角度が目標に向かわず180度前後から動かず、しかも距離がどんどん大きくなっている。

ということです。
ちゃんと理解しましょう。

対策ですが私もすぐには思いつきませんので、他の識者の方にお任せします
ごめんなさいね。
written by へにっくす

アバター
usao
記事: 1566
登録日時: 6年前

Re: STGにおけるホーミング弾の角度について

#6

投稿記事 by usao » 3年前

角度でやるにしても
「x-y座標系での角度」ではなく
「弾の現在の進行方向 と それに直交する方向 の2方向を座標軸とした座標系での角度」
にすれば楽なのではないでしょうか.
("弾の進行方向にターゲットがあるときにatan2()が0度を返す世界" であれば
 atan2()の戻り値の符号だけで弾が旋回すべき方向がわかる)

x-y座標系上での角度値境界の跨ぎ方を全パターン網羅するように頑張る というのでもいいでしょうけど
より直感的に理解しやすい方法があるならそっちの方が楽だと思います.

こんな感じ?

コード:

//x-y座標系での 弾→標的 ベクトルd(dx,dy)
dy = target.y - shot.y;
dx = target.x - shot.x;

//弾の進行方向u(ux,uy) と それに直交する方向v(vx,vy). 共に単位方向ベクトル.
ux = cos( shot.angle );  uy = sin( shot.angle );
vx = -uy;  vy = ux;  //※向き的に逆だったら-1をかける側を変えて v=(uy,-ux) とされたし

//u-v座標系での 弾→標的 ベクトル(du,dv)
//dとu, dとv の内積をとれば求まる.
du = dx*ux + dy*uy;
dv = dx*vx + dy*vy;

//u-v座標系での 弾→標的 の角度
angle_uv = atan2( dv, du );

//弾の進行方向を回転.angle_uvの正負で判定
if( angle_uv < 0 ){ ... (略)
xy_uv.png
xy_uv.png (12.75 KiB) 閲覧数: 3039 回

アバター
夢幻ノ月夜
記事: 133
登録日時: 5年前
住所: Stens;Gate世界線

Re: STGにおけるホーミング弾の角度について

#7

投稿記事 by 夢幻ノ月夜 » 3年前

レーザーの当たり判定のときに使った
三点を与えるとその三点間の角度を返してくれる関数ありますよね?
それに「ショットの進行方向の延長上の1点(ショットがこのまままっすぐ飛ぶとたどり着く点)」と
「ショットの現在位置」と「標的の現在位置」を与えると
ショットが今向いている方角と敵のいる角度の差が出ます。
あとはそれを適当な数字で割って現在のショットの角度に足してあげるといい感じの動きになります。
毎回ゲーム作ろうとするたびに壁にぶち当たる

アバター
夢幻ノ月夜
記事: 133
登録日時: 5年前
住所: Stens;Gate世界線

Re: STGにおけるホーミング弾の角度について

#8

投稿記事 by 夢幻ノ月夜 » 3年前

それを応用して分母を反比例関数+1によって決定することによって、
少しずつホーミング性能を100%に近づけることもできます
毎回ゲーム作ろうとするたびに壁にぶち当たる

アバター
夢幻ノ月夜
記事: 133
登録日時: 5年前
住所: Stens;Gate世界線

Re: STGにおけるホーミング弾の角度について

#9

投稿記事 by 夢幻ノ月夜 » 3年前

画像
2分で作った画像置いときます
毎回ゲーム作ろうとするたびに壁にぶち当たる

アバター
usao
記事: 1566
登録日時: 6年前

Re: STGにおけるホーミング弾の角度について

#10

投稿記事 by usao » 3年前

オフトピック
>レーザーの当たり判定のときに使った
>三点を与えるとその三点間の角度を返してくれる関数ありますよね?

個人間で通じる話なのかもしれませんが,
第三者にも話の内容がわかるようにして欲しいところ.

アバター
夢幻ノ月夜
記事: 133
登録日時: 5年前
住所: Stens;Gate世界線

Re: STGにおけるホーミング弾の角度について

#11

投稿記事 by 夢幻ノ月夜 » 3年前

usao さんが書きました:
オフトピック
>レーザーの当たり判定のときに使った
>三点を与えるとその三点間の角度を返してくれる関数ありますよね?

個人間で通じる話なのかもしれませんが,
第三者にも話の内容がわかるようにして欲しいところ.
すみません
http://dixq.net/rp/34.html
ここにある

コード:

//3点から角度を返す
double get_sita(pt_t pt0,pt_t pt1,pt_t rpt){
    /* ベクトル C→P と C→Q のなす角θおよび回転方向を求める.*/
    Vector2_t c, p, q; /* 入力データ */
    Vector2_t cp;      /* ベクトル C→P */
    Vector2_t cq;      /* ベクトル C→Q */
    double s;          /* 外積:(C→P) × (C→Q) */
    double t;          /* 内積:(C→P) ・ (C→Q) */
    double theta;      /* θ (ラジアン) */

    /* c,p,q を所望の値に設定する.*/
    c.x = pt0.x;    c.y = pt0.y;
    p.x = pt1.x;    p.y = pt1.y;
    q.x = rpt.x;    q.y = rpt.y;

    /* 回転方向および角度θを計算する.*/
    Vector2Diff(&cp, &p, &c);          /* cp ← p - c   */
    Vector2Diff(&cq, &q, &c);          /* cq ← q - c   */
    s = Vector2OuterProduct(&cp, &cq); /* s ← cp × cq */
    t = Vector2InnerProduct(&cp, &cq); /* t ← cp ・ cq */
    theta = atan2(s, t);
    return theta;
}
これのことです
毎回ゲーム作ろうとするたびに壁にぶち当たる

アバター
usao
記事: 1566
登録日時: 6年前

Re: STGにおけるホーミング弾の角度について

#12

投稿記事 by usao » 3年前

オフトピック
>これのことです

情報提示ありがとうございます.
内容としては私が書いたNo.6と一緒みたいですね.

アバター
プラム
記事: 164
登録日時: 6年前
住所: 東海地方

Re: STGにおけるホーミング弾の角度について

#13

投稿記事 by プラム » 3年前

>>へにっくすさん
へにっくす さんが書きました: 角度の最小値?角度ではありません。私が出した結果で、dis=とあるのは点と点との距離(distance)を示しています。
角度はang=で示しています。
最初の一行目は距離が367.7で、61行目で距離が1.8になり、目標に一番近づいた、ということです。
そこまでは想定した通りの動きですよね。
62行目以降はあなたが言われた通り、角度が目標に向かわず180度前後から動かず、しかも距離がどんどん大きくなっている。

ということです。
ちゃんと理解しましょう。
なるほど、距離というのはdisのことですね、僕が無知で馬鹿なので、しっかりと理解できていませんでした、すみません・・・
わざわざ丁寧にありがとうございます。

>>usaoさん&むげん
LINEで個人的にやっていたやり取りの内容があり、第三者のみなさんにわかりにくい表現があってすみません。
usao さんが書きました:角度でやるにしても
「x-y座標系での角度」ではなく
「弾の現在の進行方向 と それに直交する方向 の2方向を座標軸とした座標系での角度」
にすれば楽なのではないでしょうか.
("弾の進行方向にターゲットがあるときにatan2()が0度を返す世界" であれば
 atan2()の戻り値の符号だけで弾が旋回すべき方向がわかる)

x-y座標系上での角度値境界の跨ぎ方を全パターン網羅するように頑張る というのでもいいでしょうけど
より直感的に理解しやすい方法があるならそっちの方が楽だと思います
夢幻ノ月夜 さんが書きました: 三点を与えるとその三点間の角度を返してくれる関数ありますよね?
それに「ショットの進行方向の延長上の1点(ショットがこのまままっすぐ飛ぶとたどり着く点)」と
「ショットの現在位置」と「標的の現在位置」を与えると
ショットが今向いている方角と敵のいる角度の差が出ます。
あとはそれを適当な数字で割って現在のショットの角度に足してあげるといい感じの動きになります。
なるほど、そういう考え方もあるんですね。
それならいい感じにできそうです、やってみます。
わざわざわかりやすいように画像まで付けていただいてありがとうございました

アバター
プラム
記事: 164
登録日時: 6年前
住所: 東海地方

Re: STGにおけるホーミング弾の角度について

#14

投稿記事 by プラム » 3年前

むげんとusaoさんの提案してくださった方法で行った結果、無事に綺麗に回転するようになりました、回答してくださった皆さん、本当にありがとうございました

閉鎖

“C言語何でも質問掲示板” へ戻る