無題

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tokage

無題

#1

投稿記事 by tokage » 15年前

DXライブラリで一人称視点ゲームを作っているのですが、
カメラの向いている方向にカメラを移動させるやり方がよくわかりません。
サンプルの3Dアクション基本を見たのですがよくわかりませんでした。

環境はWindows7,VC++2008EE,DXライブラリ
プログラミング歴は4か月くらいです。

現在のプログラム

#include "DxLib.h"
#include <math.h>
//関数宣言
void CAM_Init();//カメラ初期化
void CAM_Proc();//カメラ処理
void Rend_Proc();//描画処理
void Input_Proc();//入力処理
void ST_Init();//ステージ初期化
void ST_Ter();//ステージ後始末

#define CAM_SPEED 0.1f//カメラ旋回速度
#define CAM_MSPEED 50.0f
//入力情報
struct KEYINPUT
{
int NInput;//現在
int EInput;//過去
};
KEYINPUT inp;//キー入力実態宣言
//カメラ情報構造体
struct CAM
{
float AH;//水平
float AV;//垂直
VECTOR Tt;//注視点
VECTOR ZA;//座標
};
CAM cam;//カメラ実体宣言
//-----------------------------------------------------------------------------------
void Input_Proc()//入力処理
{
int O;
O=inp.NInput;
inp.NInput=GetJoypadInputState(DX_INPUT_KEY_PAD1);
inp.EInput=inp.NInput&~O;
}
//-----------------------------------------------------------------------------------
struct ST//ステージ情報構造体
{
int MHandle;
};
ST st;
//-----------------------------------------------------------------------------------
void ST_Init()//ステージ初期化
{
st.MHandle=MV1LoadModel("s1.mqo");
MV1SetupCollInfo(st.MHandle,-1);
}
void ST_Ter()//ステージ後始末
{
MV1DeleteModel(st.MHandle);
}
//-----------------------------------------------------------------------------------
void CAM_Init()//カメラ初期化
{
cam.ZA.x=0.0f;
cam.ZA.y=0.0f;
cam.ZA.z=0.0f;
}
void CAM_Proc()//カメラ処理
{
int CS;
CS=1;//カメラ固定フラグ
int mpx,mpy;//マウス座標
float TR;
TR=0.0f;//ねじれ角度
float ms;//角度変更量
ms=0.01f;
float smx,smy,smz;//移動量
smx=0.0f;
smy=50.0f;
smz=50.0f;
float cx,cz;//
cx=0;
cz=50;
GetMousePoint(&mpx,&mpy);
//-------------------------------------
//-------------------------------------
if((GetMouseInput()&MOUSE_INPUT_RIGHT)!=0)
{
CS = 2;
}
//--------^^^^^^\\~~~~~~~~~~~~~~~~~~~~~~~
if(CS!= 2 && 200<mpy)//下----------
{
cam.AV+=ms;
}
if(CS!= 2 && 10<mpy)
{
cam.AV+=ms+0.02f;
}

if(CS!= 2 && 300>mpy)//上-----------
{
cam.AV-=ms;
}
if(CS!= 2 && 490>mpy)
{
cam.AV-=ms+0.02f;
}

if(CS!= 2 && 400<mpx)//右-----------
{
cam.AH+=ms;
}
if(CS!= 2 && 590<mpx)
{
cam.AH+=ms+0.02f;
}

if(CS!= 2 && 200>mpx)//左-----------
{
cam.AH-=ms;
}
if(CS!= 2 && 10>mpx)
{
cam.AH-=ms+0.02f;
}
//---------------------
if(CheckHitKey(KEY_INPUT_R))
{
TR+=1.57f;
}
//-----------------------
//---------------------------------
if(CheckHitKey(KEY_INPUT_W)==1)
{
cam.ZA.z+=smz;
cam.ZA.x+=smx;
}
if(CheckHitKey(KEY_INPUT_S)==1)
{
cam.ZA.z-=50.0f;
}
if(CheckHitKey(KEY_INPUT_A)==1)
{
cam.ZA.x-=50.0f;
}
if(CheckHitKey(KEY_INPUT_D)==1)
{
cam.ZA.x+=50.0f;
}
if(CheckHitKey(KEY_INPUT_SPACE)==1)
{
cam.ZA.y+=smy;
}
if(CheckHitKey(KEY_INPUT_F)==1)
{
cam.ZA.y-=smy;
}
SetCameraPositionAndAngle(VGet(cam.ZA.x,cam.ZA.y,cam.ZA.z),cam.AV,cam.AH,TR);
}
//-----------------------------------------------------------------------------------
void Rend_Proc()//描画処理
{
int x,y;
GetMousePoint(&x,&y);//照準
SetTransColor(255,255,255);//透明色
int AG;//照準
AG=LoadGraph("pred.bmp");
SetFogEnable(TRUE);//霧 オン オフ
SetFogColor(0,0,0);//霧カラー
SetFogStartEnd(0.0f,5000.0f);//霧 距離
//--------------------------------
float sms; //ステージ透明度
sms=1.0f;
if(CheckHitKey(KEY_INPUT_C)==1)//透視
{
sms-=0.8f;
}
MV1SetOpacityRate(st.MHandle,sms);//ステージ透明度
//-----------------------------
DrawBox(0,0,640,480,GetColor(0,0,0),TRUE);//背景とかの色 その他
MV1DrawModel(st.MHandle);
DrawGraph(x-24,y-24,AG,TRUE);
SetMouseDispFlag(FALSE);
}
//-----------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
ChangeWindowMode(TRUE);//ウインドウモード
if(DxLib_Init()<0)//ライブラリ初期化
return -1;
CAM_Init();//カメラ初期化
SetDrawScreen(DX_SCREEN_BACK);//描画先を裏
ST_Init();
while(ProcessMessage()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0)//ESCキーかウインドウが閉じられるまでループ
{
ClearDrawScreen();//画面クリア
Input_Proc();//入力処理
CAM_Proc();//カメラ処理
Rend_Proc();//描画処理
ScreenFlip();//裏の内容を表に出す
}
ST_Ter();
DxLib_End();//ライブラリ後始末
return 0;//終了
}
これをどう変更したらカメラの向きに進めるかおしえてください。

Tororo

Re:無題

#2

投稿記事 by Tororo » 15年前

CAM_Proc()で毎回初期化しているからではないですか?

とかげ

Re:無題

#3

投稿記事 by とかげ » 15年前

Tototoさん 回答ありがとうございます。
理解力がなくてすみませんが
どうしたら毎回初期化しなくて済むのかおしえてくれませんか。

Tororo

Re:無題

#4

投稿記事 by Tororo » 15年前

int CS;
CS=1
float TR;
TR=0.0f;//ねじれ角度
float ms;//角度変更量
ms=0.01f;
float smx,smy,smz;//移動量
smx=0.0f;
smy=50.0f;
smz=50.0f;
float cx,cz;//
cx=0;
cz=50;
ここら辺毎回読まれる所なので
毎回初期化されているんです。
グローバルにして、初期化関数を作ってみてはどうでしょうか?

tokage

Re:無題

#5

投稿記事 by tokage » 15年前

詳しい説明ありがとうございます。
とりあえず現状のプログラムですが、前に載せえたのが長かったと思うので短くしました。
#include "DxLib.h"
#include <math.h>

//関数宣言
void CAM_Init() ;/*カメラ初期化*/void CAM_Proc() ;/*カメラ処理*/
void Rend_Proc() ;/*描画処理*/
void Input_Proc();/*入力処理*/
void ST_Init() ;/*ステージ初期化*/void ST_Ter();/*ステージ後始末*/
#define CAM_SPEED 0.1f//カメラ旋回速度
#define CAM_MSPEED 50.0f//カメラ移動速度

//入力情報
struct KEYINPUT { int NInput ;/*現在*/ int EInput ;/*過去*/ } ; KEYINPUT inp;//キー入力実態宣言
struct CAM/*カメラ情報構造体*/{ float AH;/*水平*/ float AV;/*垂直*/ VECTOR Tt;/*注視点*/ VECTOR ZA;/*座標*/
float TR;/*ねじれ角度*/ float smx , smy , smz ; /*移動量*/ int CS;//カメラ固定フラグ
int mpx,mpy;//マウス座標
float ms;//角度変更量
float cx , cz ; } ; CAM cam ; //カメラ実体宣言
//-----------------------------------------------------------------------------------
void Input_Proc()//入力処理
{ int O ; O = inp.NInput ;
inp.NInput = GetJoypadInputState ( DX_INPUT_KEY_PAD1 ) ; inp.EInput = inp.NInput & ~ O ; }
//-----------------------------------------------------------------------------------
struct ST//ステージ情報構造体
{ int MHandle ; } ;
ST st;
//-----------------------------------------------------------------------------------
void ST_Init()//ステージ初期化
{ st.MHandle = MV1LoadModel ( "s1.mqo" ) ;
MV1SetupCollInfo ( st.MHandle , -1 ) ; }
void ST_Ter()//ステージ後始末
{ MV1DeleteModel ( st.MHandle ) ; }
//-----------------------------------------------------------------------------------
void CAM_Init()//カメラ初期化
{ cam.ZA.x = 0.0f ; cam.ZA.y = 0.0f ; cam.ZA.z = 0.0f ; cam.smx = 0.0f ; cam.smy = 50.0f ; cam.smz = 50.0f ;
cam.CS = 1 ; cam.TR = 0.0f ; cam.ms = 0.01f ; cam.smx = 0.0f ; cam.smy = 50.0f ; cam.smz = 50.0f ;
cam.cx = 0 ; cam.cz = 50 ; }
void CAM_Proc()//カメラ処理
{ GetMousePoint ( &cam.mpx , &cam.mpy ) ;
if( ( GetMouseInput() & MOUSE_INPUT_RIGHT ) != 0 ) { cam.CS = 2 ; }
if( cam.CS != 2 && 200 < cam.mpy ) { cam.AV += cam.ms ; }//下------------------------
if( cam.CS != 2 && 50 < cam.mpy ) { cam.AV += cam.ms + 0.02f ; }
if( cam.CS != 2 && 300 > cam.mpy ) { cam.AV -= cam.ms ; }//上------------------------
if( cam.CS != 2 && 470 > cam.mpy ) { cam.AV -= cam.ms+0.02f ; }
if( cam.CS != 2 && 400 < cam.mpx ) { cam.AH += cam.ms ; }//右------------------------
if( cam.CS != 2 && 570 < cam.mpx ) { cam.AH += cam.ms+0.02f ; }
if( cam.CS != 2 && 200 > cam.mpx ) { cam.AH -= cam.ms ; }//左------------------------
if( cam.CS != 2 && 30 > cam.mpx ) { cam.AH -= cam.ms + 0.02f ; }
//---------------------------------
if( CheckHitKey ( KEY_INPUT_W ) == 1 ) { cam.ZA.z += cam.smz ; cam.ZA.x += cam.smx ; }
if( CheckHitKey ( KEY_INPUT_S ) == 1 ) { cam.ZA.z -= 50.0f ; }
if( CheckHitKey ( KEY_INPUT_A ) == 1 ) { cam.ZA.x -= 50.0f ; }
if( CheckHitKey ( KEY_INPUT_D ) == 1 ) { cam.ZA.x += 50.0f ; }
if( CheckHitKey ( KEY_INPUT_SPACE ) == 1 ) { cam.ZA.y += cam.smy ; }
if( CheckHitKey ( KEY_INPUT_F ) == 1 ) { cam.ZA.y -= cam.smy ; }

SetCameraPositionAndAngle( VGet ( cam.ZA.x , cam.ZA.y , cam.ZA.z ) , cam.AV , cam.AH , cam.TR ) ;
}
void Rend_Proc()//描画処理-----------------------------------------
{
MV1DrawModel ( st.MHandle ) ; //ステージ
}

int WINAPIからさきは同じなので省かせていただきます。

一応こうなっているんですがこれでいいんでしょうか。

Tororo

Re:無題

#6

投稿記事 by Tororo » 15年前

まぁそんな感じです^^

MNS

Re:無題

#7

投稿記事 by MNS » 15年前

DXライブラリの3D機能、というよりは、3Dの処理全般はよく知らないのですが、
座標から注視点へのベクトルが、カメラの向きと考えてよいのでしょうか?
完全に的はずれなことを言っているかもしれませんが、
(Tt-ZA)を適当にスケーリングして、ZAに加算すれば良いと思います。

少なからず、私はCAM_Proc関数はなんら問題はなかったと思いますよ。 画像

tokage

Re:無題

#8

投稿記事 by tokage » 15年前

MNSさんありがとうございます。
とりあえずやってみますが時間がかかると思います。

tororoさん
これで毎回初期化はなくなったと思います。ありがとうございました。

関係ないですがシューティングゲームやってみました。
まだ最後までやっていませんがボス戦が好きなので楽しいです。

MNS

Re:無題

#9

投稿記事 by MNS » 15年前

一応、コードを適当に弄ったら出来た(?)ので書いて置きます。

void ST_Init()//ステージ初期化
{
st.MHandle=MV1LoadModel("s1.mqo");
MV1SetupCollInfo(st.MHandle,-1);
MV1SetPosition( st.MHandle, VGet( 0.0f, 0.0f, 100.0f ) ) ;
}
座標がセットされてなかったので、試験的に(0,0,100)にします。

void CAM_Init()//カメラ初期化
{
cam.ZA.x=0.0f;
cam.ZA.y=0.0f;
cam.ZA.z=0.0f;
cam.Tt = VGet(0.0,0.0,100.0);
}
注視点を先の座標と同じところに設定します。

void CAM_Proc()//カメラ処理
{
~略~

if(CheckHitKey(KEY_INPUT_W)==1)
{
cam.ZA = VAdd(cam.ZA, VNorm(VSub(cam.Tt, cam.ZA)));
}
if(CheckHitKey(KEY_INPUT_S)==1)
{
cam.ZA = VSub(cam.ZA, VNorm(VSub(cam.Tt, cam.ZA)));
}

~略~
}
Wキーをおしたときには、
カメラの座標=カメラの座標+正規化ベクトル(カメラの注視点ーカメラの座標)
を行い、
Sキーをおしたときには減算します。

一応、これでカメラの方向に移動すると思いますが、
座標に対応させて注視点の値も変えなければならないのかもしれません。

まあ、詳しい人が解説してくれると思うので、
とりあえず動かしてみたい場合には上のようなコードで出来る…と思います。

tokage

Re:無題

#10

投稿記事 by tokage » 15年前

どうやら座標に対応して注視点を変えなければならないようです。
(ステージの中心を見たまま移動している)
注視点を変化させるためにいろいろいじってみます。

tokage

カメラの向いている方向に移動

#11

投稿記事 by tokage » 15年前

いろいろやってみましたが結局状況は変わりませんでした。
現状カメラはとりあえず動くのですが、カメラが向いている方向に移動に
移動することができません。
いろいろなサイトをみて試したりはしたのですが注視点に関する情報を
見つけることができませんでした。

注視点を変える方法が分かる人、ぜひ教えてください。
お願いします。

Justy

Re:カメラの向いている方向に移動

#12

投稿記事 by Justy » 15年前


> 現状カメラはとりあえず動くのですが、カメラが向いている方向に移動に
> 移動することができません。

 tokageさんのカメラは角度ベースで管理しており注視点ベースではないので
厳密に注視点を出すことはできませんが、カメラの向きは GetCameraTarget()で取得することが
出来ますので、カメラの座標にそれを足せばそれを注視点としてしまってもいいかと思います。


 ただ、コードを見る限りカメラの向きを基本として、前後だけでなく左右上下にも
移動するようなので、
[color=#d0d0ff" face="monospace]
VECTOR v = { 0 };
if(CheckHitKey(KEY_INPUT_W) == 1)
v.z += cam.smz;

if(CheckHitKey(KEY_INPUT_S) == 1)
v.z -= cam.smz;

if(CheckHitKey(KEY_INPUT_A) == 1)
v.x -= cam.smx;

if(CheckHitKey(KEY_INPUT_D) == 1)
v.x += cam.smx;

if(CheckHitKey(KEY_INPUT_SPACE) == 1)
v.y += cam.smy;

if(CheckHitKey(KEY_INPUT_F) == 1)
v.y -= cam.smy;

MATRIX m;
CreateIdentityMatrix(&m);
CreateRotationXYZMatrix(&m, cam.AV, cam.AH, cam.TR);
VectorTransform(&v, &v, &m);
cam.ZA = VAdd(v, cam.ZA);
[/color]

のようにカメラのローカルの姿勢をベースに移動量を決めて、後でカメラの姿勢を元に変換し、
cam.ZAに足し込めばいいんじゃないかと思います。

 どうでしょう?

tokage

Re:カメラの向いている方向に移動

#13

投稿記事 by tokage » 15年前

おかげでカメラの向きに移動することができました。
これをもとにゲームを作っていこうと思います、
本当にありがとうございました。

移動できたので解決にします。

tokage

Re:カメラの向いている方向に移動

#14

投稿記事 by tokage » 15年前

解決にし忘れたのでしておきます。

閉鎖

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