トップページ > 記事閲覧
移動速度について
名前:アライス 日時: 2018/05/18 16:17

毎度お世話になっております。 この度は移動速度についてお聞きしたく書き込みました。 カメラから垂直(?)に横移動はできるようになったのですが、 移動速度が1.0fで固定されてしまっているようです。 解決するにはどうすればいいでしょうか。ご教授お願いします。 以下プログラムです。 #include <math.h> #include "DxLib.h" void Input_Process( void ) ; void Player_PlayAnim( int PlayAnim ) ; void Player_AnimProcess( void ) ; struct PADINPUT { int NowInput ; // 現在の入力 int EdgeInput ; // 現在のフレームで押されたボタンのみビットが立っている入力値 } ; //プレイヤーの構造体 struct Player{ int Model; int AnimIndex; int AttachIndex; int move; int Jump; VECTOR Position; float TotalTime; float PlayTime; float AnimBledRate; int PlayAnim1; float AnimPlayCount1; int PlayAnim2; float AnimPlayCount2; float AnimBlendRate; int State; }; //ステージの構造体 struct Stage{ int Model; }; //カメラの構造体 struct Camera{ VECTOR Eye; VECTOR Target; float AngleH; float AngleV; }; Player pl; Camera ca; Stage st; PADINPUT inp; // 入力処理 void Input_Process( void ) { int Old ; // ひとつ前のフレームの入力を変数にとっておく Old = inp.NowInput ; // 現在の入力状態を取得 inp.NowInput = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ; // 今のフレームで新たに押されたボタンのビットだけ立っている値を EdgeInput に代入する inp.EdgeInput = inp.NowInput & ~Old ; } void Player_PlayAnim( int PlayAnim ) { // 再生中のモーション2が有効だったらデタッチする if( pl.PlayAnim2 != -1 ) { MV1DetachAnim(pl.Model, pl.PlayAnim2 ) ; pl.PlayAnim2 = -1 ; } // 今まで再生中のモーション1だったものの情報を2に移動する pl.PlayAnim2 = pl.PlayAnim1 ; pl.AnimPlayCount2 = pl.AnimPlayCount1 ; // 新たに指定のモーションをモデルにアタッチして、アタッチ番号を保存する pl.PlayAnim1 = MV1AttachAnim( pl.Model, PlayAnim,-1,FALSE ) ; pl.AnimPlayCount1 = 0.0f ; // ブレンド率は再生中のモーション2が有効ではない場合は1.0f( 再生中のモーション1が100%の状態 )にする pl.AnimBlendRate = pl.PlayAnim2 == -1 ? 1.0f : 0.0f ; } // プレイヤーのアニメーション処理 void Player_AnimProcess( void ) { float AnimTotalTime ; // 再生しているアニメーションの総時間 // ブレンド率が1以下の場合は1に近づける if( pl.AnimBlendRate < 1.0f ) { pl.AnimBlendRate += 0.1f ; if( pl.AnimBlendRate > 1.0f ) { pl.AnimBlendRate = 1.0f ; } } // 再生しているアニメーション1の処理 if( pl.PlayAnim1 != -1 ) { // アニメーションの総時間を取得 AnimTotalTime = MV1GetAttachAnimTotalTime( pl.Model, pl.PlayAnim1 ) ; // 再生時間を進める pl.AnimPlayCount1 += 250.0f ; // 再生時間が総時間に到達していたら再生時間をループさせる if( pl.AnimPlayCount1 >= AnimTotalTime ) { pl.AnimPlayCount1 = fmod( pl.AnimPlayCount1, AnimTotalTime ) ; } // 変更した再生時間をモデルに反映させる MV1SetAttachAnimTime( pl.Model, pl.PlayAnim1, pl.AnimPlayCount1 ) ; // アニメーション1のモデルに対する反映率をセット MV1SetAttachAnimBlendRate( pl.Model, pl.PlayAnim1, pl.AnimBlendRate ) ; } // 再生しているアニメーション2の処理 if( pl.PlayAnim2 != -1 ) { // アニメーションの総時間を取得 AnimTotalTime = MV1GetAttachAnimTotalTime( pl.Model, pl.PlayAnim2 ) ; // 再生時間を進める pl.AnimPlayCount2 += 250.0f ; // 再生時間が総時間に到達していたら再生時間をループさせる if( pl.AnimPlayCount2 > AnimTotalTime ) { pl.AnimPlayCount2 = fmod( pl.AnimPlayCount2, AnimTotalTime ) ; } // 変更した再生時間をモデルに反映させる MV1SetAttachAnimTime( pl.Model, pl.PlayAnim2, pl.AnimPlayCount2 ) ; // アニメーション2のモデルに対する反映率をセット MV1SetAttachAnimBlendRate( pl.Model, pl.PlayAnim2, 1.0f - pl.AnimBlendRate ) ; } } int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int) { // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // ライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; //プレイヤーの初期化 pl.Position = VGet(0.0f,0.0f,0.0f); pl.Model = MV1LoadModel("Lat式ミク/DxChara.x"); pl.move = 0; MV1SetPosition(pl.Model,pl.Position); MV1DrawModel(pl.Model); pl.PlayAnim1 = -1; pl.PlayAnim2 = -1; pl.State = 0; //ステージの初期化 st.Model = MV1LoadModel("Lat式ミク/ColTestStage.mqo"); //カメラの初期化 MATRIX RotZ, RotY; ca.AngleH = DX_PI_F / 2 * 3; ca.AngleV = 0.0f; //アニメーション初期化 Player_PlayAnim(4); //ESCAPEキーが押されるまでループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { { MATRIX LocalMatrix; // ユーザー行列を解除する MV1ResetFrameUserLocalMatrix(pl.Model, 2); // 現在のルートフレームの行列を取得する LocalMatrix = MV1GetFrameLocalMatrix(pl.Model, 2); // Z軸方向の平行移動成分を無効にする LocalMatrix.m[3][2] = 0.0f; // ユーザー行列として平行移動成分を無効にした行列をルートフレームにセットする MV1SetFrameUserLocalMatrix(pl.Model, 2, LocalMatrix); } VECTOR LeftMoveVec; VECTOR UpMoveVec; VECTOR MoveVec; UpMoveVec = VSub(ca.Target,ca.Eye); UpMoveVec.y = 0.0f; LeftMoveVec = VCross(UpMoveVec, VGet(0.0f, 1.0f, 0.0f)); UpMoveVec = VNorm( UpMoveVec ) ; LeftMoveVec = VNorm( LeftMoveVec ) ; MoveVec = VGet(0.0f,0.0f,0.0f); ClearDrawScreen(); Input_Process() ; pl.move = 0; //カメラの処理 if(CheckHitKey(KEY_INPUT_LEFT) == 1) { ca.AngleH -= 0.1f; if(ca.AngleH < -DX_PI_F) ca.AngleH -= DX_TWO_PI_F; } if(CheckHitKey(KEY_INPUT_RIGHT) == 1) { ca.AngleH += 0.1f; if(ca.AngleH > DX_PI_F) ca.AngleH += DX_TWO_PI_F; } if(CheckHitKey(KEY_INPUT_UP) == 1) { ca.AngleV -= 0.1f; if(ca.AngleV < -DX_PI_F / 2 + 0.1f) ca.AngleV = -DX_PI_F / 2 + 0.1f; } if(CheckHitKey(KEY_INPUT_DOWN) == 1) { ca.AngleV += 0.1f; if(ca.AngleV > DX_PI_F / 2 - 0.1f) ca.AngleV = DX_PI_F / 2 - 0.1f; } //キャラの移動 if(CheckHitKey(KEY_INPUT_A) == 1) { MoveVec = VAdd(MoveVec,LeftMoveVec); pl.Position = VAdd(pl.Position,MoveVec); pl.move = 1; } if(CheckHitKey(KEY_INPUT_S) == 1) { MoveVec = VAdd(MoveVec,VScale(LeftMoveVec, -1.0f)); pl.Position = VAdd(pl.Position,MoveVec); pl.move = 1; } if(CheckHitKey(KEY_INPUT_W) == 1) { pl.Position.z -= 20.0f; pl.move = 1; } if(CheckHitKey(KEY_INPUT_SPACE) == 1 && pl.Jump != 1 && pl.Jump != 2) { pl.Jump = 1; } if(pl.Jump == 1) { if(pl.Position.y <= 8.0f) { if(pl.Position.y >= 8.0f) { pl.Jump = 2; } pl.Position.y += 1.0f; } } if(pl.Jump == 2) { pl.Position.y -= 0.8f; if(pl.Position.y <= 0.0f) { pl.Position.y = 0.0f; pl.Jump = 0; } } if(pl.move) { if(pl.State == 0) { Player_PlayAnim(1); pl.State = 1; } } else { if(pl.State == 1) { Player_PlayAnim(4); pl.State = 0; } } //アニメーション処理 // プレイヤーに新たなアニメーションを再生する Player_AnimProcess() ; /*if(pl.State == 1) { MV1DetachAnim(pl.Model,pl.AttachIndex); pl.AttachIndex = MV1AttachAnim(pl.Model,1,-1,FALSE); pl.TotalTime = MV1GetAttachAnimTotalTime(pl.Model,pl.AttachIndex); } if(pl.State == 0) { MV1DetachAnim(pl.Model,pl.AttachIndex); pl.AttachIndex = MV1AttachAnim(pl.Model,4,-1,FALSE); pl.TotalTime = MV1GetAttachAnimTotalTime(pl.Model,pl.AttachIndex); } if(pl.Jump == 1 || pl.Jump == 2) { MV1DetachAnim(pl.Model,pl.AttachIndex); pl.AttachIndex = MV1AttachAnim(pl.Model,5,-1,FALSE); pl.TotalTime = MV1GetAttachAnimTotalTime(pl.Model,pl.AttachIndex); } MV1SetAttachAnimTime(pl.Model,pl.AttachIndex,pl.PlayTime);*/ ca.Target = VAdd(pl.Position,VGet(0.0f,400.0f,0.0f )); // 水平方向の回転はY軸回転 RotY = MGetRotY( ca.AngleH ); // 垂直方向の回転はZ軸回転 ) RotZ = MGetRotZ( ca.AngleV ); ca.Eye = VAdd(VTransform(VTransform(VGet(-1600.0f,0.0f,0.0f), RotZ), RotY),ca.Target); SetCameraPositionAndTarget_UpVecY(ca.Eye, ca.Target); MV1SetPosition(pl.Model,pl.Position); MV1DrawModel(pl.Model); MV1DrawModel(st.Model); ScreenFlip(); } //ライブラリの後始末 DxLib_End(); //ソフトの終了 return 0; }
メンテ

Page: 1 |

Re: 移動速度について ( No.1 )
名前:newGene 日時:2018/05/18 20:27

これは全くの推測ですが @前回のスレッドを作成する時点で、おおもとのサンプルをもとにして if(CheckHitKey(KEY_INPUT_A) == 1) { MoveVec = VAdd(MoveVec,LeftMoveVec); pl.Position = VAdd(pl.Position,MoveVec); pl.move = 1; }  としていたのだが、移動速度が遅いのでとりあえず if(CheckHitKey(KEY_INPUT_A) == 1) { pl.Position.x += 20.0f; pl.move = 1; }  とした。 A前回のスレッドが終わり、やはりおおもとのサンプルに近づけたいので if(CheckHitKey(KEY_INPUT_A) == 1) { MoveVec = VAdd(MoveVec,LeftMoveVec); pl.Position = VAdd(pl.Position,MoveVec); pl.move = 1; }  と戻してみたが、やはり移動が遅い。なぜだろう? ということでしょうか? それは元のサンプルの void Player_Process( void ) の中にある // 移動ボタンが押されたかどうかで処理を分岐 if( MoveFlag ) { // 移動ベクトルを正規化したものをプレイヤーが向くべき方向として保存 pl.TargetMoveDirection = VNorm( MoveVec ) ; // プレイヤーが向くべき方向ベクトルをプレイヤーのスピード倍したものを移動ベクトルとする MoveVec = VScale( pl.TargetMoveDirection, PLAYER_MOVE_SPEED ) ; の部分が省かれているからです。(PLAYER_MOVE_SPEED = 30.0f) MoveVecはここに来た時点で小さいベクトルなので(1くらい)、掛け算して大きくする必要があります。 そのまま足すだけではちまちま進んでしまう、ということです。つまりこんな感じ。(※plの中にTargetMoveDirectionを含めない場合) VECTOR TargetMoveDirection; if (CheckHitKey(KEY_INPUT_A) == 1) { MoveVec = VAdd(MoveVec, LeftMoveVec); TargetMoveDirection = VNorm(MoveVec); MoveVec = VScale(TargetMoveDirection, 20.0f); pl.Position = VAdd(pl.Position, MoveVec); pl.move = 1; }
メンテ
Re: 移動速度について ( No.2 )
名前:アライス(解決) 日時:2018/05/19 16:19

返信ありがとうございます。 VScaleを加えたら無事に動くようになりました。 次はキャラの回転に挑戦しようと思います。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存