ページ 11

移動に関して

Posted: 2011年9月04日(日) 11:42
by rink
サイトを見ながらゲームを作っている者です

以下、ソースコードです

コード:

//main.h


/*****************************************************************************
*
*プロトタイプ宣言
*
******************************************************************************/

void GameTitle(void);		//ゲームタイトル関数
void GameSetup(void);		//ゲームセットアップ関数	
void GameMain(void);		//ゲームメイン関数
void GameOver(void);		//ゲームオーバー関数
void GameCrea(void);		//ゲームクリア関数

void PlayerInit(void);		//プレイヤー初期化関数
void CameraInit(void);		//カメラ初期化関数
void DebugPrint(void);		//デバック表示



int ModelLoad(void);		//モデル読み込み関数
int SystemIni







//common.h


#ifndef __COMMON_H__
#define __COMMON_H__

#include "DxLib.h"
#include <math.h>
#include <string>

//*****************************************************************************
//	マクロ
//*****************************************************************************
//プレイヤー関係の定義
#define PLAYER_MOVE_SPEED				30.0f		// 移動速度
#define PLAYER_ANGLE_SPEED				0.2f		// 角度変化速度
#define PLAYER_JUMP_POWER				100.0f		// ジャンプ力
#define PLAYER_GRAVITY					3.0f		// 重力
#define PLAYER_MAX_HITCOLL				2048		// 処理するコリジョンポリゴンの最大数
#define PLAYER_ENUM_DEFAULT_SIZE		800.0f		// 周囲のポリゴン検出に使用する球の初期サイズ
#define PLAYER_HIT_WIDTH				200.0f		// 当たり判定カプセルの半径
#define PLAYER_HIT_HEIGHT				700.0f		// 当たり判定カプセルの高さ
#define PLAYER_HIT_TRYNUM				16			// 壁押し出し処理の最大試行回数
#define PLAYER_HIT_SLIDE_LENGTH			5.0f		// 一度の壁押し出し処理でスライドさせる距離
#define PLAYER_SHADOW_SIZE				200.0f		// 影の大きさ
#define PLAYER_SHADOW_HEIGHT			700.0f		// 影が落ちる高さ

//カメラ関係の定義
#define CAMERA_ANGLE_SPEED				0.05f		// 旋回速度
#define CAMERA_PLAYER_TARGET_HEIGHT		400.0f		// プレイヤー座標からどれだけ高い位置を注視点とするか
#define CAMERA_PLAYER_LENGTH			1600.0f		// プレイヤーとの距離





/****************************************************************************
*
*列挙体
*
****************************************************************************/

//関数戻り値列挙体
//enum {
//	RET_OK = 0,     /* 関数戻り値:正常 */
//	RET_NG = -1    /* 関数戻り値:処理エラーあり */
//};

//ゲームシーケンス列挙体
enum GameFlow{
	GAME_TITLE,		//ゲームタイトル
	GAME_SETUP,		//ゲームセットアップ
	GAME_MAIN,		//ゲームメイン
	GAME_OVER,		//ゲームオーバー
	GAME_CREA,		//ゲームクリア
};




//*****************************************************************************
//	構造体
//*****************************************************************************
//システム情報構造体
struct GAMESYSTEM
{
	int	win_flg;
	std::string win_name;
	int	font_handle;
};

//入力情報構造体
/*struct INPUT
{
	int	NowInput;	//現在の入力
	int	EdgeInput;	//現在のフレームで押されたボタンのみビットが立っている入力値
};*/

//プレイヤー情報構造体
struct PLAYER
{
	int		model_handle;	//モデルハンドル
	VECTOR	pos;			//位置座標
	float	rot;			//回転
	VECTOR	angle;			//向き
	int anime;
	float animecount;
};

//ステージ情報構造体
struct MAP
{
	int		model_handle;	//モデルハンドル
};

//カメラ情報構造体
struct CAMERA
{
	float	angle_h;		//水平角度
	float	angle_v;		//垂直角度
	VECTOR	pos;		//カメラ座標
	VECTOR	target_pos;	//注視点座標
	VECTOR tar_pos;
	float speed;
	int	rot_x;
};
#endif





//main.cpp



#include "main.h"
#include "common.h"

int Key[256]; // キーが押されているフレーム数を格納する

// キーの入力状態を更新する
int UpdateKey(){
        char tmpKey[256]; // 現在のキーの入力状態を格納する
        GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
        for( int i=0; i<256; i++ ){ 
                if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
                        Key[i]++;     // 加算
                } else {              // 押されていなければ
                        Key[i] = 0;   // 0にする
                }
        }
        return 0;
}



/*******************************************************************

*グローバル型の宣言まとめ

*******************************************************************/

GameFlow GameMode = GAME_TITLE;			//シーケンス遷移列挙体

GAMESYSTEM gs;		//ゲームシステム構造体
PLAYER pc;			//プレイヤー構造体
MAP map;			//マップ構造体
CAMERA cam;			//カメラ構造体

float VRotate, HRotate, TRotate ;


/*******************************************************************
*メインループを含むプログラムの中核
*
*
*******************************************************************/

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){


		//初期化関数からエラーが返ってきたら
		if(SystemInit() == -1){
			return -1;		//終了させる
		}

		

		// Zバッファを有効にする
		SetUseZBuffer3D(TRUE) ;

		// Zバッファへの書き込みを有効にする
		SetWriteZBuffer3D(TRUE) ;

		//モデル読み込み
		if(ModelLoad() == -1){
			return -1;
		}

        // while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの状態更新)
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && UpdateKey()==0 ){

               switch(GameMode){
			   case GAME_TITLE:
				   GameTitle();
				   break;
			   case GAME_SETUP:
				   GameSetup();
				   break;
			   case GAME_MAIN:
				   GameMain();
				   break;
			   case GAME_OVER:
				   GameOver();
				   break;
			   case GAME_CREA:
				   GameCrea();
				   break;
			   }
        }

        DxLib_End(); // DXライブラリ終了処理
        return 0;
} 


/***************************************************************************
*モデル読み込み
*
*
****************************************************************************/
int ModelLoad(){

	if(( pc.model_handle = MV1LoadModel("Model/miku.mqo")) == -1 ){
		return -1;
	}

	if((map.model_handle = MV1LoadModel("Model/grand01.mqo")) == -1){
		return -1;
	}

	return 0;
}



/*****************************************************************************
*DXライブラリ関連の初期化
*
*
*****************************************************************************/
int SystemInit(){

	//ウィンドウモード変更
	if(ChangeWindowMode(TRUE) == -1){
		return -1;
	}

	// DXライブラリ初期化
	if (DxLib_Init() == -1) {
		return -1;				// エラーなら終了
	}

	
		
	//裏画面設定
	if(SetDrawScreen( DX_SCREEN_BACK )== -1){
		return -1; 
	}

	return 0;


}


/******************************************************************************
*プレイヤー初期化関数
*
*
******************************************************************************/
void PlayerInit(){

	//初期位置座標
	pc.pos = VGet(0.0f, 0.0f, 0.0f);

	//回転
	pc.rot = 180.0f ;

	//向き
	pc.angle = VGet(0.0f, 0.0f, 1.0f);
	



}



/******************************************************************************
*カメラ初期化関数
*
*
******************************************************************************/
void CameraInit(){
	
	//カメラ初期水平角度
	cam.angle_h = PHI_F;	//180度

	//垂直角度は0度
	cam.angle_v = 0.0f;

	cam.speed = 0.2f;

	//カメラの注視点はプレイヤー座標から規定値分高い座標
	cam.target_pos = VAdd(pc.pos, VGet( 0.0f, 100.0f, 0.0f));
	
	//カメラの座標を算出
	{
		MATRIX RotZ, RotY;
		
		//水平方向の回転はY軸回転
		RotY = MGetRotY(cam.angle_h);
		
		//垂直方向の回転はZ軸回転
		RotZ = MGetRotZ(cam.angle_v);
		
		cam.pos = VAdd(VTransform(VTransform(VGet(0.0f, 0.0f, -200.0f), RotZ), RotY), cam.target_pos);
	}
		//カメラの情報をライブラリのカメラに反映させる
	SetCameraPositionAndTarget_UpVecY(cam.pos, cam.target_pos);
}



/******************************************************************************
*ゲームタイトル
*
*
*******************************************************************************/
void GameTitle(){

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームタイトル" , 0xffffff );

	 if( Key[KEY_INPUT_SPACE] == 1 ){ 
           GameMode = GAME_SETUP;                
          }



}

/****************************************************************************
*ゲーム初期化
*
*
****************************************************************************/
void GameSetup(){

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームセットアップ" , 0xffffff );

	//カメラの 手前クリップ距離と 奥クリップ距離を設定する
	//SetCameraNearFar( 10.0f, 15000.0f );

	PlayerInit();

	CameraInit();

	

	/*cam.pos.x = 0.0f;
	cam.pos.y = 0.0f;
	cam.pos.z = 0.0f;


	//カメラの回転値を初期化
	VRotate = 0.0f ;
	HRotate = 0.0f ;
	TRotate = 0.0f ;
*/


	if( Key[KEY_INPUT_SPACE] == 1 ){ 
           GameMode = GAME_MAIN;                
          }
}



/*****************************************************************************
*ゲームメイン
*
*
*******************************************************************************/
void GameMain(){


	

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームメイン" , 0xffffff );

	{
			VECTOR UpMoveVec;	//方向ボタン「↑」を入力をしたときのプレイヤーの移動方向ベクトル
			VECTOR LeftMoveVec;	//方向ボタン「←」を入力をしたときのプレイヤーの移動方向ベクトル
			VECTOR MoveVec;		//このフレームの移動ベクトル
			int actflg = 0;

			// ルートフレームのZ軸方向の移動パラメータを無効にする
			{
				MATRIX LocalMatrix ;

				// ユーザー行列を解除する
				MV1ResetFrameUserLocalMatrix(pc.model_handle, 2 ) ;

				// 現在のルートフレームの行列を取得する
				LocalMatrix = MV1GetFrameLocalMatrix(pc.model_handle, 2 ) ;

				// Z軸方向の平行移動成分を無効にする
				LocalMatrix.m[ 3 ][ 2 ] = 0.0f ;

				// ユーザー行列として平行移動成分を無効にした行列をルートフレームにセットする
				MV1SetFrameUserLocalMatrix(pc.model_handle, 2, LocalMatrix ) ;
			}

			// プレイヤーの移動方向のベクトルを算出
			{
				//方向ボタン「↑」を押したときのプレイヤーの移動ベクトルはカメラの視線方向からY成分を抜いたもの
				UpMoveVec = VSub(cam.target_pos, cam.pos);
				UpMoveVec.y = 0.0f;
				
				//方向ボタン「←」を押したときのプレイヤーの移動ベクトルは上を押したときの方向ベクトルとY軸のプラス方向のベクトルに垂直な方向
				LeftMoveVec = VCross(UpMoveVec, VGet(0.0f, 1.0f, 0.0f)) ;
				
				//二つのベクトルを正規化( ベクトルの長さを1.0にすること )
				UpMoveVec = VScale(VNorm(UpMoveVec), 0.1f);
				LeftMoveVec = VScale(VNorm(LeftMoveVec), 0.1f);
			}
			
			//このフレームでの移動ベクトルを初期化
			MoveVec = VGet(0.0f, 0.0f, 0.0f);
			int move_flg = 0;
			
			// 方向ボタン「←」が入力されたらカメラの見ている方向から見て左方向に移動する
			if(Key[KEY_INPUT_LEFT] >= 1)
			{
				//移動ベクトルに「←」が入力された時の移動ベクトルを加算する
				MoveVec = VAdd(MoveVec, LeftMoveVec);
			}
			if(Key[KEY_INPUT_RIGHT] >= 1) 
			{
				//移動ベクトルに「←」が入力された時の移動ベクトルを反転したものを加算する
				MoveVec = VAdd(MoveVec, VScale(LeftMoveVec, -1.0f));
			}
			if(Key[KEY_INPUT_UP] >= 1)
			{
				//移動ベクトルに「↑」が入力された時の移動ベクトルを加算する
				MoveVec = VAdd(MoveVec, UpMoveVec);
			}
			if(Key[KEY_INPUT_DOWN] >= 1)
			{
				//移動ベクトルに「↑」が入力された時の移動ベクトルを反転したものを加算する
				MoveVec = VAdd(MoveVec, VScale(UpMoveVec, -1.0f));
			}

			if(MoveVec.x != 0.0f || MoveVec.y != 0.0f || MoveVec.z != 0.0f)
			{
				//プレイヤーが向くべき方向ベクトルをプレイヤーのスピード倍したものを移動ベクトルとする
				pc.angle = VNorm(MoveVec);
				MoveVec = VScale( pc.angle, 10.0f) ;
				cam.speed = 0.15f;
				move_flg = 1;
			}

			//画面に映る位置に3Dモデルを移動
			MV1SetPosition(pc.model_handle, VGet(pc.pos.x, pc.pos.y, pc.pos.z));

			//移動後の座標を算出
			pc.pos = VAdd(pc.pos, MoveVec);
			
			//プレイヤーのモデルの座標を更新する
			MV1SetPosition(pc.model_handle, pc.pos);
			
			//目標の方向ベクトルから角度値を算出する
			pc.rot = atan2(pc.angle.x, pc.angle.z);

			//モデルの角度を更新
			MV1SetRotationXYZ( pc.model_handle, VGet( 0.0f, pc.rot + PHI_F, 0.0f));

			cam.target_pos = VAdd(pc.pos, VGet( 0.0f, 100.0f, 0.0f));
			
			//カメラの座標を算出
			{
				MATRIX RotZ, RotY;
				
				//水平方向の回転はY軸回転
				RotY = MGetRotY(cam.angle_h);
				
				//垂直方向の回転はZ軸回転
				RotZ = MGetRotZ(cam.angle_v);
				
				cam.tar_pos = VAdd(VTransform(VTransform(VGet(0.0f, 0.0f, -200.0f), RotZ), RotY), cam.target_pos);
				//cam.pos = VAdd(VTransform(VTransform(VGet(0.0f, 0.0f, -200.0f), RotZ), RotY), cam.target_pos);
			}
			
			
			//カメラの情報をライブラリのカメラに反映させる
			cam.pos = VAdd(cam.pos, VScale(VSub(cam.tar_pos, cam.pos), 0.15f));	//X
			SetCameraPositionAndTarget_UpVecY(cam.pos, cam.target_pos);
		}

		//3Dモデルの描画
		// 標準ライトの方向
		SetLightDirection( VGet( 0.29f, -0.58f, -0.58f ) ) ;
		MV1DrawModel(map.model_handle);	//MAP

		MV1DrawModel(pc.model_handle);	//PC

		DebugPrint();
	

	if( Key[KEY_INPUT_SPACE] == 1 ){ 
           GameMode = GAME_OVER;                
          }

}


/*****************************************************************************
*ゲームオーバー
*
*
*****************************************************************************/
void GameOver(){

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームオーバー" , 0xffffff );

	if( Key[KEY_INPUT_SPACE] == 1 ){ 
           GameMode = GAME_CREA;                
          }

}


/********************************************************************************
*ゲームクリア
*
*
*********************************************************************************/
void GameCrea(){

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームクリア" , 0xffffff );

	if( Key[KEY_INPUT_SPACE] == 1 ){ 
           GameMode = GAME_TITLE;                
          }


}


void DebugPrint(){

	DWORD color = GetColor(255, 255, 255);

	//PCの位置を表示
	DrawFormatString(0, 0, color, "【PC】pos(%f, %f, %f)", pc.pos.x, pc.pos.y, pc.pos.z);
	DrawFormatString(0, 20, color, " rot(%f)", pc.rot);
	DrawFormatString(0, 40, color, " angle(%f, %f, %f)", pc.angle.x, pc.angle.y, pc.angle.z);
	DrawFormatString(0, 60, color, "【CAMERA】pos(%f, %f, %f)", cam.pos.x, cam.pos.y, cam.pos.z);

}
[\code]


環境は、VC++2010 windows7 DXライブラリです

問題としては、現在自キャラは上下左右の4方向に動きます

上下は問題ないのですが、左右移動関して

左右移動はX方向にベクトルを加減して動かしています

しかし、実際に移動させて見るとZ方向にも同時に移動してしまいます

真横に移動せず、少し斜めになって移動してしまいます



これについて原因が分かりません

教えていただけると幸いです

Re: 移動に関して

Posted: 2011年9月04日(日) 12:01
by softya(ソフト屋)
なぜかcodeタグがちゃんと動作していなかったので、インデントしなおして貼り付け直しました。
コード自体は、これから見ます。

コード:

//main.h


/*****************************************************************************
*
*プロトタイプ宣言
*
******************************************************************************/

void GameTitle(void);		//ゲームタイトル関数
void GameSetup(void);		//ゲームセットアップ関数	
void GameMain(void);		//ゲームメイン関数
void GameOver(void);		//ゲームオーバー関数
void GameCrea(void);		//ゲームクリア関数

void PlayerInit(void);		//プレイヤー初期化関数
void CameraInit(void);		//カメラ初期化関数
void DebugPrint(void);		//デバック表示



int ModelLoad(void);		//モデル読み込み関数
int SystemIni







//common.h


#ifndef __COMMON_H__
#define __COMMON_H__

#include "DxLib.h"
#include <math.h>
#include <string>

//*****************************************************************************
//	マクロ
//*****************************************************************************
//プレイヤー関係の定義
#define PLAYER_MOVE_SPEED				30.0f		// 移動速度
#define PLAYER_ANGLE_SPEED				0.2f		// 角度変化速度
#define PLAYER_JUMP_POWER				100.0f		// ジャンプ力
#define PLAYER_GRAVITY					3.0f		// 重力
#define PLAYER_MAX_HITCOLL				2048		// 処理するコリジョンポリゴンの最大数
#define PLAYER_ENUM_DEFAULT_SIZE		800.0f		// 周囲のポリゴン検出に使用する球の初期サイズ
#define PLAYER_HIT_WIDTH				200.0f		// 当たり判定カプセルの半径
#define PLAYER_HIT_HEIGHT				700.0f		// 当たり判定カプセルの高さ
#define PLAYER_HIT_TRYNUM				16			// 壁押し出し処理の最大試行回数
#define PLAYER_HIT_SLIDE_LENGTH			5.0f		// 一度の壁押し出し処理でスライドさせる距離
#define PLAYER_SHADOW_SIZE				200.0f		// 影の大きさ
#define PLAYER_SHADOW_HEIGHT			700.0f		// 影が落ちる高さ

//カメラ関係の定義
#define CAMERA_ANGLE_SPEED				0.05f		// 旋回速度
#define CAMERA_PLAYER_TARGET_HEIGHT		400.0f		// プレイヤー座標からどれだけ高い位置を注視点とするか
#define CAMERA_PLAYER_LENGTH			1600.0f		// プレイヤーとの距離





/****************************************************************************
*
*列挙体
*
****************************************************************************/

//関数戻り値列挙体
//enum {
//	RET_OK = 0,     /* 関数戻り値:正常 */
//	RET_NG = -1    /* 関数戻り値:処理エラーあり */
//};

//ゲームシーケンス列挙体
enum GameFlow{
	GAME_TITLE,		//ゲームタイトル
	GAME_SETUP,		//ゲームセットアップ
	GAME_MAIN,		//ゲームメイン
	GAME_OVER,		//ゲームオーバー
	GAME_CREA,		//ゲームクリア
};




//*****************************************************************************
//	構造体
//*****************************************************************************
//システム情報構造体
struct GAMESYSTEM
{
	int	win_flg;
	std::string win_name;
	int	font_handle;
};

//入力情報構造体
/*struct INPUT
{
int	NowInput;	//現在の入力
int	EdgeInput;	//現在のフレームで押されたボタンのみビットが立っている入力値
};*/

//プレイヤー情報構造体
struct PLAYER
{
	int		model_handle;	//モデルハンドル
	VECTOR	pos;			//位置座標
	float	rot;			//回転
	VECTOR	angle;			//向き
	int anime;
	float animecount;
};

//ステージ情報構造体
struct MAP
{
	int		model_handle;	//モデルハンドル
};

//カメラ情報構造体
struct CAMERA
{
	float	angle_h;		//水平角度
	float	angle_v;		//垂直角度
	VECTOR	pos;		//カメラ座標
	VECTOR	target_pos;	//注視点座標
	VECTOR tar_pos;
	float speed;
	int	rot_x;
};
#endif





//main.cpp



#include "main.h"
#include "common.h"

int Key[256]; // キーが押されているフレーム数を格納する

// キーの入力状態を更新する
int UpdateKey(){
	char tmpKey[256]; // 現在のキーの入力状態を格納する
	GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
	for( int i=0; i<256; i++ ){ 
		if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
			Key[i]++;     // 加算
		} else {              // 押されていなければ
			Key[i] = 0;   // 0にする
		}
	}
	return 0;
}



/*******************************************************************

*グローバル型の宣言まとめ

*******************************************************************/

GameFlow GameMode = GAME_TITLE;			//シーケンス遷移列挙体

GAMESYSTEM gs;		//ゲームシステム構造体
PLAYER pc;			//プレイヤー構造体
MAP map;			//マップ構造体
CAMERA cam;			//カメラ構造体

float VRotate, HRotate, TRotate ;


/*******************************************************************
*メインループを含むプログラムの中核
*
*
*******************************************************************/

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){


	//初期化関数からエラーが返ってきたら
	if(SystemInit() == -1){
		return -1;		//終了させる
	}



	// Zバッファを有効にする
	SetUseZBuffer3D(TRUE) ;

	// Zバッファへの書き込みを有効にする
	SetWriteZBuffer3D(TRUE) ;

	//モデル読み込み
	if(ModelLoad() == -1){
		return -1;
	}

	// while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの状態更新)
	while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && UpdateKey()==0 ){

		switch(GameMode){
			   case GAME_TITLE:
				   GameTitle();
				   break;
			   case GAME_SETUP:
				   GameSetup();
				   break;
			   case GAME_MAIN:
				   GameMain();
				   break;
			   case GAME_OVER:
				   GameOver();
				   break;
			   case GAME_CREA:
				   GameCrea();
				   break;
		}
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
} 


/***************************************************************************
*モデル読み込み
*
*
****************************************************************************/
int ModelLoad(){

	if(( pc.model_handle = MV1LoadModel("Model/miku.mqo")) == -1 ){
		return -1;
	}

	if((map.model_handle = MV1LoadModel("Model/grand01.mqo")) == -1){
		return -1;
	}

	return 0;
}



/*****************************************************************************
*DXライブラリ関連の初期化
*
*
*****************************************************************************/
int SystemInit(){

	//ウィンドウモード変更
	if(ChangeWindowMode(TRUE) == -1){
		return -1;
	}

	// DXライブラリ初期化
	if (DxLib_Init() == -1) {
		return -1;				// エラーなら終了
	}



	//裏画面設定
	if(SetDrawScreen( DX_SCREEN_BACK )== -1){
		return -1; 
	}

	return 0;


}


/******************************************************************************
*プレイヤー初期化関数
*
*
******************************************************************************/
void PlayerInit(){

	//初期位置座標
	pc.pos = VGet(0.0f, 0.0f, 0.0f);

	//回転
	pc.rot = 180.0f ;

	//向き
	pc.angle = VGet(0.0f, 0.0f, 1.0f);




}



/******************************************************************************
*カメラ初期化関数
*
*
******************************************************************************/
void CameraInit(){

	//カメラ初期水平角度
	cam.angle_h = PHI_F;	//180度

	//垂直角度は0度
	cam.angle_v = 0.0f;

	cam.speed = 0.2f;

	//カメラの注視点はプレイヤー座標から規定値分高い座標
	cam.target_pos = VAdd(pc.pos, VGet( 0.0f, 100.0f, 0.0f));

	//カメラの座標を算出
	{
		MATRIX RotZ, RotY;

		//水平方向の回転はY軸回転
		RotY = MGetRotY(cam.angle_h);

		//垂直方向の回転はZ軸回転
		RotZ = MGetRotZ(cam.angle_v);

		cam.pos = VAdd(VTransform(VTransform(VGet(0.0f, 0.0f, -200.0f), RotZ), RotY), cam.target_pos);
	}
	//カメラの情報をライブラリのカメラに反映させる
	SetCameraPositionAndTarget_UpVecY(cam.pos, cam.target_pos);
}



/******************************************************************************
*ゲームタイトル
*
*
*******************************************************************************/
void GameTitle(){

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームタイトル" , 0xffffff );

	if( Key[KEY_INPUT_SPACE] == 1 ){ 
		GameMode = GAME_SETUP;                
	}



}

/****************************************************************************
*ゲーム初期化
*
*
****************************************************************************/
void GameSetup(){

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームセットアップ" , 0xffffff );

	//カメラの 手前クリップ距離と 奥クリップ距離を設定する
	//SetCameraNearFar( 10.0f, 15000.0f );

	PlayerInit();

	CameraInit();



	/*cam.pos.x = 0.0f;
	cam.pos.y = 0.0f;
	cam.pos.z = 0.0f;


	//カメラの回転値を初期化
	VRotate = 0.0f ;
	HRotate = 0.0f ;
	TRotate = 0.0f ;
	*/


	if( Key[KEY_INPUT_SPACE] == 1 ){ 
		GameMode = GAME_MAIN;                
	}
}



/*****************************************************************************
*ゲームメイン
*
*
*******************************************************************************/
void GameMain(){




	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームメイン" , 0xffffff );

	{
		VECTOR UpMoveVec;	//方向ボタン「↑」を入力をしたときのプレイヤーの移動方向ベクトル
		VECTOR LeftMoveVec;	//方向ボタン「←」を入力をしたときのプレイヤーの移動方向ベクトル
		VECTOR MoveVec;		//このフレームの移動ベクトル
		int actflg = 0;

		// ルートフレームのZ軸方向の移動パラメータを無効にする
		{
			MATRIX LocalMatrix ;

			// ユーザー行列を解除する
			MV1ResetFrameUserLocalMatrix(pc.model_handle, 2 ) ;

			// 現在のルートフレームの行列を取得する
			LocalMatrix = MV1GetFrameLocalMatrix(pc.model_handle, 2 ) ;

			// Z軸方向の平行移動成分を無効にする
			LocalMatrix.m[ 3 ][ 2 ] = 0.0f ;

			// ユーザー行列として平行移動成分を無効にした行列をルートフレームにセットする
			MV1SetFrameUserLocalMatrix(pc.model_handle, 2, LocalMatrix ) ;
		}

		// プレイヤーの移動方向のベクトルを算出
		{
			//方向ボタン「↑」を押したときのプレイヤーの移動ベクトルはカメラの視線方向からY成分を抜いたもの
			UpMoveVec = VSub(cam.target_pos, cam.pos);
			UpMoveVec.y = 0.0f;

			//方向ボタン「←」を押したときのプレイヤーの移動ベクトルは上を押したときの方向ベクトルとY軸のプラス方向のベクトルに垂直な方向
			LeftMoveVec = VCross(UpMoveVec, VGet(0.0f, 1.0f, 0.0f)) ;

			//二つのベクトルを正規化( ベクトルの長さを1.0にすること )
			UpMoveVec = VScale(VNorm(UpMoveVec), 0.1f);
			LeftMoveVec = VScale(VNorm(LeftMoveVec), 0.1f);
		}

		//このフレームでの移動ベクトルを初期化
		MoveVec = VGet(0.0f, 0.0f, 0.0f);
		int move_flg = 0;

		// 方向ボタン「←」が入力されたらカメラの見ている方向から見て左方向に移動する
		if(Key[KEY_INPUT_LEFT] >= 1)
		{
			//移動ベクトルに「←」が入力された時の移動ベクトルを加算する
			MoveVec = VAdd(MoveVec, LeftMoveVec);
		}
		if(Key[KEY_INPUT_RIGHT] >= 1) 
		{
			//移動ベクトルに「←」が入力された時の移動ベクトルを反転したものを加算する
			MoveVec = VAdd(MoveVec, VScale(LeftMoveVec, -1.0f));
		}
		if(Key[KEY_INPUT_UP] >= 1)
		{
			//移動ベクトルに「↑」が入力された時の移動ベクトルを加算する
			MoveVec = VAdd(MoveVec, UpMoveVec);
		}
		if(Key[KEY_INPUT_DOWN] >= 1)
		{
			//移動ベクトルに「↑」が入力された時の移動ベクトルを反転したものを加算する
			MoveVec = VAdd(MoveVec, VScale(UpMoveVec, -1.0f));
		}

		if(MoveVec.x != 0.0f || MoveVec.y != 0.0f || MoveVec.z != 0.0f)
		{
			//プレイヤーが向くべき方向ベクトルをプレイヤーのスピード倍したものを移動ベクトルとする
			pc.angle = VNorm(MoveVec);
			MoveVec = VScale( pc.angle, 10.0f) ;
			cam.speed = 0.15f;
			move_flg = 1;
		}

		//画面に映る位置に3Dモデルを移動
		MV1SetPosition(pc.model_handle, VGet(pc.pos.x, pc.pos.y, pc.pos.z));

		//移動後の座標を算出
		pc.pos = VAdd(pc.pos, MoveVec);

		//プレイヤーのモデルの座標を更新する
		MV1SetPosition(pc.model_handle, pc.pos);

		//目標の方向ベクトルから角度値を算出する
		pc.rot = atan2(pc.angle.x, pc.angle.z);

		//モデルの角度を更新
		MV1SetRotationXYZ( pc.model_handle, VGet( 0.0f, pc.rot + PHI_F, 0.0f));

		cam.target_pos = VAdd(pc.pos, VGet( 0.0f, 100.0f, 0.0f));

		//カメラの座標を算出
		{
			MATRIX RotZ, RotY;

			//水平方向の回転はY軸回転
			RotY = MGetRotY(cam.angle_h);

			//垂直方向の回転はZ軸回転
			RotZ = MGetRotZ(cam.angle_v);

			cam.tar_pos = VAdd(VTransform(VTransform(VGet(0.0f, 0.0f, -200.0f), RotZ), RotY), cam.target_pos);
			//cam.pos = VAdd(VTransform(VTransform(VGet(0.0f, 0.0f, -200.0f), RotZ), RotY), cam.target_pos);
		}


		//カメラの情報をライブラリのカメラに反映させる
		cam.pos = VAdd(cam.pos, VScale(VSub(cam.tar_pos, cam.pos), 0.15f));	//X
		SetCameraPositionAndTarget_UpVecY(cam.pos, cam.target_pos);
	}

	//3Dモデルの描画
	// 標準ライトの方向
	SetLightDirection( VGet( 0.29f, -0.58f, -0.58f ) ) ;
	MV1DrawModel(map.model_handle);	//MAP

	MV1DrawModel(pc.model_handle);	//PC

	DebugPrint();


	if( Key[KEY_INPUT_SPACE] == 1 ){ 
		GameMode = GAME_OVER;                
	}

}


/*****************************************************************************
*ゲームオーバー
*
*
*****************************************************************************/
void GameOver(){

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームオーバー" , 0xffffff );

	if( Key[KEY_INPUT_SPACE] == 1 ){ 
		GameMode = GAME_CREA;                
	}

}


/********************************************************************************
*ゲームクリア
*
*
*********************************************************************************/
void GameCrea(){

	// 文字列の描画
	DrawString( 250 , 240 - 32 , "ゲームクリア" , 0xffffff );

	if( Key[KEY_INPUT_SPACE] == 1 ){ 
		GameMode = GAME_TITLE;                
	}


}


void DebugPrint(){

	DWORD color = GetColor(255, 255, 255);

	//PCの位置を表示
	DrawFormatString(0, 0, color, "【PC】pos(%f, %f, %f)", pc.pos.x, pc.pos.y, pc.pos.z);
	DrawFormatString(0, 20, color, " rot(%f)", pc.rot);
	DrawFormatString(0, 40, color, " angle(%f, %f, %f)", pc.angle.x, pc.angle.y, pc.angle.z);
	DrawFormatString(0, 60, color, "【CAMERA】pos(%f, %f, %f)", cam.pos.x, cam.pos.y, cam.pos.z);

}

Re: 移動に関して

Posted: 2011年9月04日(日) 12:21
by softya(ソフト屋)
うーん。そうなっているからとしか言えないですね。

コード:

		// プレイヤーの移動方向のベクトルを算出
		{
			//方向ボタン「↑」を押したときのプレイヤーの移動ベクトルはカメラの視線方向からY成分を抜いたもの
			UpMoveVec = VSub(cam.target_pos, cam.pos);
			UpMoveVec.y = 0.0f;

			//方向ボタン「←」を押したときのプレイヤーの移動ベクトルは上を押したときの方向ベクトルとY軸のプラス方向のベクトルに垂直な方向
			LeftMoveVec = VCross(UpMoveVec, VGet(0.0f, 1.0f, 0.0f)) ;

			//二つのベクトルを正規化( ベクトルの長さを1.0にすること )
			UpMoveVec = VScale(VNorm(UpMoveVec), 0.1f);
			LeftMoveVec = VScale(VNorm(LeftMoveVec), 0.1f);
		}
原因は、ここの計算でZ成分が入り込むからだと思います。
どうしてこんな計算にしたんでしょうか?

Re: 移動に関して

Posted: 2011年9月05日(月) 17:54
by rink
元々のソースコードのあったサイトの管理人さんも3Dに関しては自分と同じく”新人”のようなので、
プログラムの不備の一つと思われます。

具体的にはどの部分がおかしいのでしょうか?

VScale関数のあたりでしょうか?

Re: 移動に関して

Posted: 2011年9月05日(月) 18:18
by softya(ソフト屋)
デバッガで見てもらうとわかりますが、UpMoveVec自体にZが入り込んでいます。