ページ 1 / 1
DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年5月26日(月) 00:47
by ptolemy
http://dixq.net/forum/viewtopic.php?f=3 ... で質問したものですが、
この質問の中での3Dゲームのプログラムの一部です。↓
コード:
if(Mouse&MOUSE_INPUT_LEFT){
rotate(&cameraX,&cameraZ,-ROTATE_SPEED,target2X,target2Z);
angle1Y-=ROTATE_SPEED;
}
if(Mouse&MOUSE_INPUT_RIGHT){
rotate(&cameraX,&cameraZ,+ROTATE_SPEED,target2X,target2Z);
angle1Y+=ROTATE_SPEED;
いきなり部分的なプログラムをみせて申し訳ないですが、ここの部分について質問があります。
このプログラムは、マウスの右or左を押すと3Dモデルとカメラが同時に回転する(向きがかわる)プログラムです。
このプログラムを変えて、minecraftやクロスファイアなどのゲームの様にマウスを動かすだけで回転させたいんですが、上手くいかず、困っています。
これは、横の動きだけですが、縦の場合は、カメラだけ回転させます。
DXライブラリを使っています。
リファレンスのURLは、一応はっておきます。
http://homepage2.nifty.com/natupaji/DxLib/dxfunc.html
説明不足なので質問がとても分かりにくいですが、ご回答お願いします。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年5月26日(月) 05:06
by h2so5
どのように上手くいかないのか書いてください。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年5月26日(月) 20:51
by ptolemy2
カーソルと回転する考え方?方法?が思い付かなくて、うまくいきませんでした。
わからない点は、
マウスカーソル位置セット→カーソルの位置を取得→
の次で悩みました。
カーソルを動かすとウインドウからはみ出すので、ウインドウのなかに納める方法がわかりませんでした。
また、回転は、カーソルが動いた座標分の回転をしたらいいのか、カーソルが動いた方向に回転させていくのかわかりません。
ということで、うまくいかないというのは、考える時点でわからないことが多すぎたということです。
まとめると、
考え方を教えてほしいです。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年5月27日(火) 10:31
by softya(ソフト屋)
マウスカーソル位置セット→カーソルの位置を取得して差分を得る→マウスカーソル位置セット→カーソルの位置を取得して差分を得る→以下繰り返し
で実現できると思いますけど。
>また、回転は、カーソルが動いた座標分の回転をしたらいいのか、カーソルが動いた方向に回転させていくのかわかりません。
それは元のゲームを知らないのでなんとも言えないですが、「カーソルが動いた座標分の回転をしたらいいのか」と「カーソルが動いた方向に回転させていくのか」は同じことを言っている気がします。、xとyのベクトルは得られるので、それをどう使うかはゲーム仕様と言って良いと思います。
いろいろ試して、さじ加減で調整してみてください。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年5月27日(火) 20:21
by ptolemy2
そうゆうことですか!!
深く考えすぎてました。
試してみてまた分からないことがあったら質問します。
あと、質問なんですが、DXライブラリの関数で
SetMouseDispFlagという関数は、ただカーソルの表示だけを扱う関数ですか?
カーソル自体は、 SetMouseDispFlagで消しても大丈夫ですよね?
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年5月27日(火) 20:24
by softya(ソフト屋)
ptolemy2 さんが書きました:
SetMouseDispFlagという関数は、ただカーソルの表示だけを扱う関数ですか?
カーソル自体は、 SetMouseDispFlagで消しても大丈夫ですよね?
それこそ試したほうが良いと言っておきましょう。心配するより試すほうがより分かると思います。
私には、カーソル位置固定の方がある意味操作不能になる恐れが有ると思いますが。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月03日(火) 20:52
by ptolemy
試してみました。
差を求めるのは、なんとなく出来たんですがその差をどうやって使えばいいのか理解出来ません。
プログラムは、(Xだけです)
コード:
int Mouse _x,Mouse _y,HX,HY;
while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
SetMousePoint (320,240);
GetMousePoint(&Mouse _x,&Mouse _y);
if(Mouse _ x>320){
HX=Mouse _ x-320;
}
if(Mouse _ x<320){
HX=320-Mouse _ x;
}
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月03日(火) 20:57
by ptolemy
元々は、あるキーを押したら一定のスピードでたし続けるもので、どうしてやったらいいか理解出来ません。
また、プログラムは、考え方が間違っているかもしれないので、おかしい点は、ご指摘お願いします。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月03日(火) 21:12
by softya(ソフト屋)
マウスの移動差分を回転角の差分とする変換式を考えるだけなのですが、色々テストして見ないと良い感触のものは出来ないと思います。
ディレイ(遅延)やダンパー(急激な変化を抑える)ことも必要かもしれません。
感覚的なものなので、ptolemyさんが詳細に言葉に出来ないものは我々にも回答しようがないとご理解ください。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月03日(火) 21:28
by kino
>差を求めるのは、なんとなく出来たんですがその差をどうやって使えばいいのか理解出来ません。
前回の座標を記憶しておいて後で差分を取るというのではだめでしょうか?
使い方はこんな感じかと
コード:
GetMousePoint(&Mouse_x,&Mouse_y);
if(cnt>0){
HX=HX+(Mouse_x2-Mouse_x);
HY=HY+(Mouse_y2-Mouse_y);
}
cnt++;
Mouse_x2=Mouse_x;
Mouse_y2=Mouse_y;
一回目は座標を記憶しておくだけです
これはシンプルに書いたものなので
調整は必要だと思います
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月03日(火) 21:30
by kino
すいません
で囲うのを忘れました
次から気をつけます
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月05日(木) 20:54
by ptolemy
返信ありがとうございます。
ソフト屋さん
わかりました。まずは、変換式を書くことから始めたいと思います。
kinoさん
サンプルプログラムありがとうございます。
私のC言語の理解力が足りないのが原因なんですが、質問がいくつかあります。
ひとつめは、
Mouse_x2=Mouse_x;
書くと、 Mouse_x2-Mouse_xが0になってしまうと私は思っているんですが、0にならないのは、何故ですか?
二つ目は、cntの役割を教えてください。
三つめは、これは、ループさせないとダメですよね?
質問が多いですが、よろしくお願いします。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月05日(木) 21:59
by softya(ソフト屋)
kinoさんが現れるかわからないので、私なりに答えておきます。
1.Mouse_x2=Mouse_x;書くと、 Mouse_x2-Mouse_xが0になってしまうと私は思っているんですが、0にならないのは、何故ですか?
GetMousePoint()しているからです。
2.cntの役割を教えてください
2フレーム目から処理しないと最初の値がとんでも無い値だからです。前回との差分ですからね。前回がないと計算できません。
3.これは、ループさせないとダメですよね?
毎フレーム1回通る必要があります。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月05日(木) 22:30
by kino
まず、このプログラムは2回以上ループさせないと
効果を発揮しません
差分をとるということは2個の数値が必要となります
ループ一回だと1個の数値しかないので差分をとれないんです
ループ 1回目 GetMousePoint(&Mouse_x,&Mouse_y)でMouse_xに1回目の数値が入る
Mouse_x2=Mouse_xでMouse_x2に一回目の数値を保存
ループ 2回目 GetMousePoint(&Mouse_x,&Mouse_y)でMouse_xに2回目の数値が入る
Mouse_x2-Mouse_xで差分をとる(1回目から2回目を引く)
差分取得が終わったらMouse_x2=Mouse_xでMouse_x2に2回目の数値を保存
ループ 3回目 GetMousePoint(&Mouse_x,&Mouse_y)でMouse_xに3回目の数値が入る
Mouse_x2-Mouse_xで差分をとる(2回目から3回目を引く)
差分取得が終わったらMouse_x2=Mouse_xでMouse_x2に3回目の数値を保存
以後続きます
1、0にならないのは、何故ですか?
マウスを動かしていれば
GetMousePoint(&Mouse_x,&Mouse_y)で更新してすぐに前回との引き算をしているので
0になりません
マウスを動かしていなければ0になります
2、cntの役割を教えてください。
一回目の差分のプログラムをパスするためです
最初cntに0を入れておきます
すると一回目は0なので差分のプログラムをパスできます
3、ループさせないとダメですよね?
2回以上ループさせないとだめですね
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月05日(木) 22:39
by ptolemy2
ソフト屋さんとkinoさんとても分かりやすい回答ありがとうございます。
納得しました。
kinoさんのサンプルを参考にプログラムを書いていきたいと思います。
また、ソフト屋さんからお教えしていただいた通り、変換式を書いて調整したいと思います。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月12日(木) 00:51
by ptolemy
kinoさんのプログラムを参考にしました。
また、あまり変換式が書けなかったので、こういう感じにしたんですが、どうでしょうか?
コード:
static const float ROTATE_SPEED=DX_PI/80;//回転スピード
void rotate(float *x,float *y,const float ang,float mx,float my){
const float ox=*x-mx,oy=*y-my;
*x=ox*cos(ang)+oy*sin(ang);
*y=-ox*sin(ang)+oy*cos(ang);
*x+=mx;
*y+=my;
}
SetMousePoint(320,240);//セット
SetMouseDispFlag(FALSE);//カーソル表示OFF
while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){ //ループ
GetMousePoint(&Mouse_x,&Mouse_y);//マウス座標取得
if(cnt>0){
if(Mouse_x>Mouse_x2){//現時点のマウス座標が前回の座標より大きかったら
rotate(&camera.X,&camera.Z,+ROTATE_SPEED,player.X,player.Z);//右にカメラを回転
rotate(&cursor_x,&cursor_z,+ROTATE_SPEED,player.X,player.Z);//右に目線の座標を回転 player.angleY+=ROTATE_SPEED;//右にモデル回転
}
if(Mouse_x<Mouse_x2){//現時点のマウス座標が前回の座標より小さかったら
rotate(&camera.X,&camera.Z,-ROTATE_SPEED,player.X,player.Z);//左にカメラを回転
rotate(&cursor_x,&cursor_z,-ROTATE_SPEED,player.X,player.Z);//左に目線の座標を回転 player.angleY-=ROTATE_SPEED;//左にモデル回転
}
}
cnt++;
Mouse_x2=Mouse_x;
}
誤字脱字があったらすいません。
このように回転スピードは、あらかじめ指定しておいて、マウスが動いた方向に回転させるようにしました。
しかし、マウスのカーソルが出て、さらに、画面の端までいって、動けなくなります。どうしたらいいでしょうか?
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月12日(木) 01:14
by kino
>しかし、マウスのカーソルが出て、さらに、画面の端までいって、動けなくなります。どうしたらいいでしょうか?
画面の端までいくとマウスカーソルは止まってしまうのでそうなりますね^^
最初に書かれている
>このプログラムは、マウスの右or左を押すと3Dモデルとカメラが同時に回転する(向きがかわる)プログラムです。
から推測すると
マウスのボタンを押した瞬間にcntを0にする
マウスのボタンを押し続けてる間はループを続ける
そしてマウスのボタンを離したらループをやめて
ボタンが押されるまで待機するっている処理が必要だと思います
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月12日(木) 08:16
by kino
if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 )
{
// 押されている
if (mouse_flg==0) { mouse_flg=1;cnt=0;}
ここにマウス座標取得のプログラム(15行から27行)を書き込む
}
else
{
// 押されていない
mouse_flg=0;
}
こんな感じです
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月12日(木) 14:39
by usao
>しかし、マウスのカーソルが出て、さらに、画面の端までいって、動けなくなります。どうしたらいいでしょうか?
こんな方法ではできないのでしょうか?
コード:
int main()
{
...
マウスカーソル座標を,ある「所定の位置X0」にセットする
...
while( ... ) //メインループ
{
...
X = マウスカーソル座標
if( X != X0 ) //所定の位置にカーソルが無いということは,カーソルが動いたということ
{
差分 X-X0 に基づく回転処理
マウスカーソル座標を,「所定の位置X0」にセットする
}
...
}
...
}
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月13日(金) 00:50
by ptolemy
kinoさん
そのボタンで回転していたものを座標だけで回転させたいということです。
usaoさん
少し参考にして、kinoさんのものと合わせました。
コード:
SetMousePoint(320,240);//セット
GetMousePoint(&Mouse_x,&Mouse_y);//取得
if(cnt>0){
if(Mouse_x>320){//座標が右方向に動いたら右回転
rotate(&camera.X,&camera.Z,+ROTATE_SPEED,player.X,player.Z);
rotate(&cursor_x,&cursor_z,+ROTATE_SPEED,player.X,player.Z);
player.angleY+=ROTATE_SPEED;
}
if(Mouse_x<320){//座標が左方向に動いたら左回転
rotate(&camera.X,&camera.Z,-ROTATE_SPEED,player.X,player.Z);
rotate(&cursor_x,&cursor_z,-ROTATE_SPEED,player.X,player.Z);
player.angleY-=ROTATE_SPEED;
}
}
cnt++;
SetMousePoint(320,240);//セット
だとどうですか?
やってみた感じ、ウィンドウからも出ないし、しっかり回転しています。
また、自分が目指していた感覚に近いです。
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月13日(金) 12:07
by kino
>だとどうですか?
人それぞれなのでこれが正解っていうのは特にないかと思います^^
>やってみた感じ、ウィンドウからも出ないし、しっかり回転しています。
>また、自分が目指していた感覚に近いです。
おめでとうございます^^
重要なのはptolemy さんが動作を理解されることだと思います
ptolemy さんが目指しているものに近ければ更にいいですねー^^
Re: DXライブラリ3D マウスカーソルでの回転について
Posted: 2014年6月15日(日) 00:30
by ptolemy
皆さん本当にありがとうございました。
おかげで成功出来ました。
次にまたつまずいたら質問します。