トップページ > 記事閲覧
ホーミング弾がカクカクする
名前:あららさん 日時: 2017/07/09 14:36

atan2を用いてホーミング弾を作成したいのですが、自機を移動させると弾がぶるぶると震えてその場に止まってしまいます。 特にX軸の移動で止まってしまい、一定範囲内に入るとY軸での移動でもぶるぶると震えてその場に止まってしまいます。 for (int i = 0; i < enemy1_X.size(); i++) { if (flag1[i] == false) { if (enemy1_Y[i] < y) { minus_Y = -1; } else { minus_Y = 1; } angle1[i] = atan2((enemy1_Y[i] - y)*minus_Y, (enemy1_X[i] - x))*(180 / PI); enemy1_X[i] +=(int)(cos(angle1[i])*Speed); enemy1_Y[i] -=(int)(sin(angle1[i])*Speed); DrawGraph(enemy1_X[i], enemy1_Y[i], handle1[j], TRUE); } このようなループ文の中で実装しています。 xとyは自機の座標を1/60秒感覚で受け取っています。 θをatan2によって取得し、cosとsinに投げることでX軸とY軸の移動量を与える、といった認識で組んでいるのですが、どうもうまくいかないです。 ちなみに弾のSpeedは3、自機のSpeedは6です。 よろしくお願いします。
メンテ

Page: 1 |

Re: ホーミング弾がカクカクする ( No.1 )
名前:s8079 日時:2017/07/09 23:25

atan2関数の戻り値はラジアンです。 また,cos関数,sin関数の引数もラジアンです。 つまり, angle1[i] = atan2((enemy1_Y[i] - y) * minus_Y, (enemy1_X[i] - x)) * (180 / PI); ではなく, angle1[i] = atan2((enemy1_Y[i] - y) * minus_Y, (enemy1_X[i] - x)) が正しいかと思います。 もちろんラジアンを扱う際はdouble型を用いてください。
メンテ
Re: ホーミング弾がカクカクする ( No.2 )
名前:管理人 日時:2017/07/09 23:45

使用されている関数( atan2, cos, sin )は合っていますが、 掛けたり足したりする要素やプラス・マイナスの符号に誤りがある気がします 敵がプレイヤーを延々とホーミングするプログラムを作成してみましたので、 よろしければご覧ください #include "DxLib.h" #include <math.h> #define ENEMY_SPEED 3.0f #define PLAYER_SPEED 6.0f int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { double angle ; float EnemyX = 320.0f, EnemyY = 16.0f ; float PlayerX = 200.0f, PlayerY = 460.0f ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // メインループ(何かキーが押されたらループを抜ける) while( ProcessMessage() == 0 ) { // 画面のクリア ClearDrawScreen() ; // ホーミングの処理 angle = atan2( ( double )( PlayerY - EnemyY ), ( double )( PlayerX - EnemyX ) ) ; EnemyX += ( float )( cos( angle ) * 3.0 ) ; EnemyY += ( float )( sin( angle ) * 3.0 ) ; // プレイヤーの移動処理 int pad = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ; if( pad & PAD_INPUT_LEFT ) PlayerX -= 6.0f ; if( pad & PAD_INPUT_RIGHT ) PlayerX += 6.0f ; if( pad & PAD_INPUT_UP ) PlayerY -= 6.0f ; if( pad & PAD_INPUT_DOWN ) PlayerY += 6.0f ; // 敵の描画 DrawBox( ( int )EnemyX - 8 , ( int )EnemyY - 8 , ( int )EnemyX + 8 , ( int )EnemyY + 8 , GetColor( 255, 0, 0 ), TRUE ) ; // プレイヤーの描画 DrawBox( ( int )PlayerX - 16, ( int )PlayerY - 16, ( int )PlayerX + 16, ( int )PlayerY + 16, GetColor( 255,255,255 ), TRUE ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }
メンテ
Re: ホーミング弾がカクカクする ( No.3 )
名前:あららさん 日時:2017/07/10 00:05

ありがとうございます、ラジアンだとわかりづらいので度数に直していました。 度数に直す箇所を撤廃したところ、カクつくということはなくなり、綺麗に動作しました。 cos,atanなどの関数は任意以外の値を入れると動作がおかしくなる、という見解でよろしいでしょうか?
メンテ
Re: ホーミング弾がカクカクする ( No.4 )
名前:管理人 日時:2017/07/10 00:22

> cos,atanなどの関数は任意以外の値を入れると動作がおかしくなる、という見解でよろしいでしょうか? cos, sin, atan などの関数はラジアンにしか対応していませんので、 ラジアンではなく度数の値を渡したことで正常な戻り値が得られていなかった、ということだと思います なので変数 angle に格納されている値が度数でも cos, sin に値を渡す際に * PI / 180 を angle に 掛けてあげると正しい動作になると思います
メンテ
Re: ホーミング弾がカクカクする ( No.5 )
名前:あららさん 日時:2017/07/10 00:29

>>管理人様 わざわざご丁寧にありがとうございます!参考にさせていただきます。 しかし、問題の[カクつく]という点はどうやらラジアンから度数に勝手に変換しているところが悪さをしていたようです。 しかしその後、符号に関して管理人様のコードを参考に修正したところ、見事期待通りの動作をしていただきました。 >>s8079様 も、問題の核心を見事突いて下さり、ありがとうございました。
メンテ
Re: ホーミング弾がカクカクする ( No.6 )
名前:あららさん 日時:2017/07/10 00:31

>>管理人様 なるほど、そういうことだったのですね。 つまらないことで数時間悩んでしまっていたので本当に助かりました。 ありがとうございます
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存