サンプルプログラム 方向入力によるキャラクター移動( カメラ固定 )

方向入力によるキャラクター移動( カメラ固定 )

 ゲームパッドやキーボードの方向キーの入力に従ってキャラクターモデルを移動させるサンプルです。
 キャラクターモデルの移動と同時に、移動中は走りアニメーション、移動中ではないときは待機アニメーションを
再生するようにしています。

 カメラ位置を固定して、向きやアニメーションを滑らかに切り替える処理などもしていないので、
比較的シンプルなプログラムです。

 ( プログラムの実行に必要なファイルはこちら )


// 方向入力に従ってキャラクターを移動させる

#include "DxLib.h"

// 移動速度
#define MOVESPEED		10.0f

// DxChara.x での走りアニメーションの番号
#define ANIM_RUN		1

// DxChara.x での待機アニメーションの番号
#define ANIM_NEUTRAL		4

// 斜め入力用の各軸の倍率( sin( 45°) )
#define VECTOR_SCALING		0.70710678118f

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	int    ModelHandle ;
	float  AnimTotalTime ;
	float  AnimNowTime ;
	int    AnimAttachIndex ;
	int    RunFlag ;
	int    MoveAnimFrameIndex ;
	VECTOR Position ;
	int    Input ;
	int    MoveFlag ;
	float  Angle ;

	// ウインドウモードで起動
	ChangeWindowMode( TRUE ) ;

	// DXライブラリの初期化
	if( DxLib_Init() < 0 ) return -1 ;

	// 3Dモデルの読み込み
	ModelHandle = MV1LoadModel( "DxChara.x" ) ;

	// 向きを初期化
	Angle = 0.0f ;

	// 走っているフラグを倒す
	RunFlag = FALSE ;

	// 待機アニメーションをアタッチ
	AnimAttachIndex = MV1AttachAnim( ModelHandle, ANIM_NEUTRAL ) ;

	// 待機アニメーションの総時間を取得しておく
	AnimTotalTime = MV1GetAttachAnimTotalTime( ModelHandle, AnimAttachIndex ) ;

	// アニメーション再生時間を初期化
	AnimNowTime = 0.0f ;
	MV1SetAttachAnimTime( ModelHandle, AnimAttachIndex, AnimNowTime ) ;

	// アニメーションで移動をしているフレームの番号を検索する
	MoveAnimFrameIndex = MV1SearchFrame( ModelHandle, "BasePoint" ) ;

	// アニメーションで移動をしているフレームを無効にする
	MV1SetFrameUserLocalMatrix( ModelHandle, MoveAnimFrameIndex, MGetIdent() ) ;

	// 3Dモデルの座標を初期化
	Position = VGet( 0.0f, 0.0f, 0.0f ) ;

	// 描画先を裏画面にする
	SetDrawScreen( DX_SCREEN_BACK ) ;

	// カメラの位置と向きを設定
	SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 1200.0f, -2000.0f ), VGet( 0.0f, 400.0f, 0.0f ) );

	// カメラのクリッピング距離を設定
	SetCameraNearFar( 16.0f, 5000.0f );

	// 背景の色を灰色にする
	SetBackgroundColor( 128, 128, 128 ) ;

	// メインループ(何かキーが押されたらループを抜ける)
	while( ProcessMessage() == 0 )
	{
		// 画面のクリア
		ClearDrawScreen() ;

		// ゲームパッド+キーボードの入力を取得
		Input = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;

		// 移動しているかどうかのフラグを倒す
		MoveFlag = FALSE ;

		// 方向入力に従ってキャラクターを移動
		// ( 最初に斜め入力の判定を、その後上下左右単体の入力の判定をしています )
		if( ( Input & PAD_INPUT_LEFT ) != 0 && ( Input & PAD_INPUT_UP ) != 0 )
		{
			Angle       = 135.0f ;
			MoveFlag    = TRUE ;
			Position.x -= MOVESPEED * VECTOR_SCALING ;
			Position.z += MOVESPEED * VECTOR_SCALING ;
		}
		else
		if( ( Input & PAD_INPUT_UP ) != 0 && ( Input & PAD_INPUT_RIGHT ) != 0 )
		{
			Angle       = -135.0f ;
			MoveFlag    = TRUE ;
			Position.x += MOVESPEED * VECTOR_SCALING ;
			Position.z += MOVESPEED * VECTOR_SCALING ;
		}
		else
		if( ( Input & PAD_INPUT_RIGHT ) != 0 && ( Input & PAD_INPUT_DOWN ) != 0 )
		{
			Angle       = -45.0f ;
			MoveFlag    = TRUE ;
			Position.x += MOVESPEED * VECTOR_SCALING ;
			Position.z -= MOVESPEED * VECTOR_SCALING ;
		}
		else
		if( ( Input & PAD_INPUT_DOWN ) != 0 && ( Input & PAD_INPUT_LEFT ) != 0 )
		{
			Angle       = 45.0f ;
			MoveFlag    = TRUE ;
			Position.x -= MOVESPEED * VECTOR_SCALING ;
			Position.z -= MOVESPEED * VECTOR_SCALING ;
		}
		else
		if( ( Input & PAD_INPUT_LEFT ) != 0 )
		{
			Angle       = 90.0f ;
			MoveFlag    = TRUE ;
			Position.x -= MOVESPEED ;
		}
		else
		if( ( Input & PAD_INPUT_RIGHT ) != 0 )
		{
			Angle       = -90.0f ;
			MoveFlag    = TRUE ;
			Position.x += MOVESPEED ;
		}
		else
		if( ( Input & PAD_INPUT_DOWN ) != 0 )
		{
			Angle       = 0.0f ;
			MoveFlag    = TRUE ;
			Position.z -= MOVESPEED ;
		}
		else
		if( ( Input & PAD_INPUT_UP ) != 0 )
		{
			Angle       = 180.0f ;
			MoveFlag    = TRUE ;
			Position.z += MOVESPEED ;
		}

		// 今までと状態が変化した場合はアニメーションを変更する
		if( RunFlag != MoveFlag )
		{
			// 走っているかどうかのフラグを保存
			RunFlag = MoveFlag ;

			// 今までアタッチしていたアニメーションをデタッチ
			MV1DetachAnim( ModelHandle, AnimAttachIndex ) ;

			// 新しいアニメーションをアタッチ
			if( RunFlag )
			{
				AnimAttachIndex = MV1AttachAnim( ModelHandle, ANIM_RUN ) ;
			}
			else
			{
				AnimAttachIndex = MV1AttachAnim( ModelHandle, ANIM_NEUTRAL ) ;
			}

			// アニメーションの総時間を取得しておく
			AnimTotalTime = MV1GetAttachAnimTotalTime( ModelHandle, AnimAttachIndex ) ;

			// アニメーション再生時間を初期化
			AnimNowTime = 0.0f ;
		}
		else
		{
			// アニメーション再生時間を進める
			AnimNowTime += 200.0f ;

			// アニメーション再生時間がアニメーションの総時間を越えていたらループさせる
			if( AnimNowTime >= AnimTotalTime )
			{
				// 新しいアニメーション再生時間は、アニメーション再生時間からアニメーション総時間を引いたもの
				AnimNowTime -= AnimTotalTime ;
			}
		}

		// 新しいアニメーション再生時間をセット
		MV1SetAttachAnimTime( ModelHandle, AnimAttachIndex, AnimNowTime ) ;

		// 新しい向きをセット
		MV1SetRotationXYZ( ModelHandle, VGet( 0.0f, Angle / 180.0f * DX_PI_F, 0.0f ) ) ;

		// 3Dモデルに新しい座標をセット
		MV1SetPosition( ModelHandle, Position ) ;

		// 3Dモデルの描画
		MV1DrawModel( ModelHandle ) ;

		// 裏画面の内容を表画面に反映
		ScreenFlip() ;
	}

	// DXライブラリの後始末
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}

戻る