回転しているカメラに対して前後左右の移動:3Dサンプルプログラム
・ADキーでカメラを回転させています。
・十字キーでプレイヤーはカメラに対して前後左右に移動します。
#include "DxLib.h"
#include <math.h>
// 度をラジアンに変換する
#define D2R(deg) ((deg)*DX_PI_F/180.0f)
// ステージモデルハンドル
int StageHandle;
// プレイヤーモデルハンドル
int PlayerHandle;
// プレイヤーの座標
VECTOR PlayerPos;
// プレイヤーの向き
VECTOR PlayerAngle;
// カメラ座標
VECTOR CameraPos;
// 注視点座標
VECTOR CameraTarget;
// カメラをどの方向に置くかの向き
VECTOR CameraAngle;
// ==============================
// *** 初期化処理 ***
// ==============================
void Game_Init()
{
// 3Dモデルの読み込み
StageHandle = MV1LoadModel( "stage.mqo" );
PlayerHandle = MV1LoadModel( "player.mqo" );
// プレイヤー座標は原点から
PlayerPos = VGet( 0.0f, 0.0f, 0.0f );
// 回転なしの状態から開始
PlayerAngle = VGet( 0.0f, D2R( 0.0f ), 0.0f );
// カメラ座標と注視点の初期設定
CameraTarget = VGet( 0.0f, 0.0f, -5.0f );
CameraPos = VGet( 0.0f, 10.0f, -25.0f );
CameraAngle = VGet( D2R( -20.0f ), 0.0f, 0.0f );
}
// ==============================
// *** 更新処理 ***
// ==============================
void Game_Update()
{
// ADキーでカメラ回転
if( CheckHitKey( KEY_INPUT_A ) ) CameraAngle.y += D2R( 1.0f );
if( CheckHitKey( KEY_INPUT_D ) ) CameraAngle.y -= D2R( 1.0f );
// 注視点の座標はプレイヤー座標
CameraTarget = PlayerPos;
// 基準のベクトル
VECTOR Direction = VGet( 0.0f, 0.0f, 10.0f );
// X軸回転行列
MATRIX MatrixX = MGetRotX( CameraAngle.x );
// Y軸回転行列
MATRIX MatrixY = MGetRotY( CameraAngle.y );
// 行列の合成
MATRIX Matrix = MMult( MatrixX, MatrixY );
// 基準ベクトルを行列で変換
Direction = VTransform( Direction, Matrix );
// カメラ座標はプレイヤー座標から変換した座標を足したところ
CameraPos = VAdd( PlayerPos, Direction );
// 十字キーを押していないときは速度0
float Speed = 0.0f;
// 十字キーでカメラに対して前後左右に向きを変更と速度設定
if( CheckHitKey( KEY_INPUT_RIGHT ) ){
PlayerAngle.y = CameraAngle.y - D2R( 90.0f );
Speed = 0.1f;
}
if( CheckHitKey( KEY_INPUT_LEFT ) ){
PlayerAngle.y = CameraAngle.y + D2R( 90.0f );
Speed = 0.1f;
}
if( CheckHitKey( KEY_INPUT_UP ) ){
PlayerAngle.y = CameraAngle.y + D2R( 180.0f );
Speed = 0.1f;
}
if( CheckHitKey( KEY_INPUT_DOWN ) ){
PlayerAngle.y = CameraAngle.y;
Speed = 0.1f;
}
// 速度が設定されていたら移動
PlayerPos.x += Speed * sinf( PlayerAngle.y );
PlayerPos.z += Speed * cosf( PlayerAngle.y );
}
// ==============================
// *** 描画処理 ***
// ==============================
void Game_Draw()
{
// カメラの位置と注視点をセット
SetCameraPositionAndTarget_UpVecY( CameraPos, CameraTarget );
// ステージモデルの描画
MV1DrawModel( StageHandle );
// プレイヤーモデルの座標をセットする
MV1SetPosition( PlayerHandle, PlayerPos );
// プレイヤーモデルの回転値をセットする
MV1SetRotationXYZ( PlayerHandle, PlayerAngle );
// プレイヤーモデルを描画する
MV1DrawModel( PlayerHandle );
}
// ==============================
// *** 終了処理 ***
// ==============================
void Game_End()
{
MV1DeleteModel( StageHandle );
MV1DeleteModel( PlayerHandle );
}
サンプルプログラムで記述している描画や操作関係はDXライブラリを使っていますが、DXライブラリを使わない開発でも処理としては同じような実装で動作すると思います。