トップページ > 過去ログ > 記事閲覧
ゲームパッドのアナログ入力
名前:PAD 日時: 2009/10/07 18:23

ゲームパッドのアナログスティックの入力によって角度を入力したいのですが、どうしてもうまくいきません。 仕様としては、 1)無入力状態では角度が0度 2)上(12時方向)を0度として、時計回りに360度の角度を返す。(右側が90度、左が270度、下が180度) としたいのですが、自分で作ってみても360度ではなくて最大180度までだったり、上・右が0度、左・下が270度など仕様どおりにうまくいきません。 どうすればよいでしょうか?

Page: 1 |

Re: ゲームパッドのアナログ入力 ( No.1 )
名前:sy(サイ) 日時:2009/10/07 21:29

ttp://homepage2.nifty.com/natupaji/DxLib/function/dxfunc_input.html#R5N24 僕は基本的に「答え」を書きたくないです。プログラミング能力が身に付きませんから。 まずは、役に立ちそうな数学の知識をつけることです♪ 進行方向なら、ただ単に単位ベクトル求めてスピードかけた方が楽な気もしますが、 ※取得できる値のy座標が上がマイナス値と言うのが気になりますね アルゴリズム的には、 1.取得したX,Y値を元に単位ベクトルを求める 2.基準となる「ベクトル(0度のベクトル)」との成す角を求める ってここまで言ったら、ライブラリの機能でスグ求まりそうですね。 全然分らなければもう一度質問ください。 ※要チェック3D機能関数。
Re: ゲームパッドのアナログ入力 ( No.2 )
名前:PAD 日時:2009/10/07 22:17

とりあえずアドバイスどおりに作ってみましたがどうでしょうか? VECTOR base=VGet(0,1,0);//基準とするベクトル //while等省略 GetJoypadAnalogInput(&InputX,&InputY,DX_INPUT_PAD1); InputY*=-1; VECTOR pad=VGet(InputX/1000,InputY/1000,0); float cosA=VDot(base,pad)/VSize(base)*VSize(pad); float angle=acos(cosA)*180/PI; この状態だと、自分の欲しい角度(27度とか,129度とかのアナログスティックの軸を中心とした角度)が出てこないのですが・・・
Re: ゲームパッドのアナログ入力 ( No.3 )
名前:sy(サイ) 日時:2009/10/08 08:51

int 型だからですよ…orz floatに直して計算してください。 後は、X軸で条件分岐すれば、180度以上の角度も出せると思います。
Re: ゲームパッドのアナログ入力 ( No.4 )
名前:PAD 日時:2009/10/08 11:49

float型キャストにしたら細かい値まで出ました。 確かにintのままやっても小数値は出ませんもんね・・・ しかし、0度±45度と180度±45度あたりになると角度が-1.#IND00となってしまいます。 調べてみても何もでないんですがこれはなんですか?
Re: ゲームパッドのアナログ入力 ( No.5 )
名前:sy(サイ) 日時:2009/10/08 13:43

ttp://docwiki.embarcadero.com/RADStudio/ja/Acos%EF%BC%8Cacosl これが原因のようですねぇ。引数が-1〜1なので…汗 ちょっと回避策模索中です。
Re: ゲームパッドのアナログ入力 ( No.6 )
名前:sy(サイ) 日時:2009/10/08 14:23

acos波を調べました。 他のsin,cos波と同じように0 1 0 -1 0 と動いて行くので、 if(cosA < -1.0f){ cosA=-2.0f-cosA; }else if(cosA > 1.0f){ cosA=2.0f-cosA; } とりあえずこれで値は取れそうです。
Re: ゲームパッドのアナログ入力 ( No.7 )
名前:PAD 日時:2009/10/09 10:59

返信遅くなってすみません。 確かに、-1.#IND00とは出なくなりました。 しかし、軸をゆっくり動かしてみると角度が40度あたりになると一度下がり、0ど近くになるとまた上がり、90度まであがるという流れになっていました。 それにより、本来45度であるべきところが20何度になっていたりとかしているのですが・・・ どうすればよいのでしょう?
Re: ゲームパッドのアナログ入力 ( No.8 )
名前:sy(サイ) 日時:2009/10/09 18:44

float cosA=VDot(base,pad)/VSize(base)*VSize(pad); どうやらこの式間違ってるようです。 ちゃんと確認するべきでした…orz float angle=VRad( base, pad ) ; と、DXlibの機能使うとすぐ出せるようですがもう一度式を確認することをお勧めしますー。
Re: ゲームパッドのアナログ入力 ( No.9 )
名前:Hima 日時:2009/10/09 19:41

atan2をやってみますか? int x, y; GetJoypadAnalogInput( &x , &y , InputService->padConstant[ controllerId ] ); float angle = atan2( (float)y, (float)x ) - PI/2; if( angle < 0 ) angle += PI2; これを使うと、アナログの角度を得ることができると思います(ラジアン指定に)。 上を0度にしたいなら float angle = atan2( (float)y, (float)x ) if( angle < 0 ) angle += PI2; だけでいいです。
Re: ゲームパッドのアナログ入力 ( No.10 )
名前:PAD 日時:2009/10/09 19:57

試しにVRad関数を使ってみるときれいに角度が出ました。 確かにこのままの式だと正しい計算結果になりませんね。すみませんでした…orz 公式でもVRad関数でもきれいに値が出たので調整に入ったのですが、なぜか180度以上の値が出ません。 float over; if(InputX==0&&InputY==0) pad=VGet(0,1,0);//無入力状態では-1.#IND00となるため else pad=VGet((float)InputX/1000.0f,(float)InputY/1000.0f,0); angle=VRad(base,pad)*180/PI; if(InputX<0) { over=180.0f-angle;//181=180+(180-179) angle=angle+over; } としてみたのですが、angle+=でもangle=angle+overでもなぜか180以上の値が入らないのですが… 次から次とすみません…
Re: ゲームパッドのアナログ入力 ( No.11 )
名前:sy(サイ) 日時:2009/10/09 20:12

初めの方にも言いましたが、パッドのX軸の値で分岐処理してみてください。 マイナス値なら180度足すだけです。 Himaさんのおっしゃる方法も有効です。
Re: ゲームパッドのアナログ入力 ( No.12 )
名前:PAD 日時:2009/10/09 20:31

今、Himaさんのおっしゃった方法もやってみました。 atan2関数はこんな使い方も出来るんですね。初めてatan2がすごいと感じました。 No.10のプログラムですが、後々考えてみるとうまくいくはずがありませんよね、不足しているものに不足している分を足しているのですから…orz やっとスッキリしました。 お二人とも本当にありがとうございました。

Page: 1 |