以下、ソースコードです
//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方向にも同時に移動してしまいます
真横に移動せず、少し斜めになって移動してしまいます
これについて原因が分かりません
教えていただけると幸いです