ホームへ戻る

 3.1章 キーの入力に応じてキャラを動かす

 2章で基本的なDXライブラリの関数について勉強しましたので、3章ではゲームプログラムにこれらをどう使用するのか、具体的に学んでいきましょう。

2.9章で、キー入力を管理する関数を作りました。3.1章ではこれを利用してキャラを動かしてみましょう。

まず、

if( 上キーが押されていたら ){
  キャラを上に移動させる;
}

こんな処理を4方向に書けばよさそうです。

ではサンプルプログラムを見てみましょう。


#include "DxLib.h"

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

// キーの入力状態を更新する
int gpUpdateKey(){
	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;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

        int x=320, y=240;
        int Handle = LoadGraph("画像/キャラクタ01.png");

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

                if( Key[ KEY_INPUT_RIGHT ] >= 1 ){ // 右キーが押されていたら
			x++;                       // 右へ移動
		}
		if( Key[ KEY_INPUT_DOWN  ] >= 1 ){ // 下キーが押されていたら
			y++;                       // 下へ移動
		}
		if( Key[ KEY_INPUT_LEFT  ] >= 1 ){ // 左キーが押されていたら
			x--;                       // 左へ移動
		}
		if( Key[ KEY_INPUT_UP    ] >= 1 ){ // 上キーが押されていたら
			y--;                       // 上へ移動
		}

		DrawRotaGraph( x, y, 1.0, 0.0, Handle, TRUE ); // x,y の位置にキャラを描画

	}

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

実行結果


このようにゲームプログラムは「計算フェーズ」と「描画フェーズ」から出来ています。



まず計算フェーズで座標やキャラの状態などを計算し、出来た数値を描画フェーズで描画するというプロセスで行うのが一般的です。

ゲームでは計算だけをスキップする(一時停止実装等)とか、

描画だけをスキップする(処理落ち回避・リプレイ高速再生等)とかを行いたい事があるので、ここは明確に分けておく必要があります。

今は同じ関数内に2つの処理を書いているので大きな2つのまとまりがあるように見えないかもしれませんが、関数分けすると分かりやすくなるでしょう。



#include "DxLib.h"

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

// キーの入力状態を更新する
int gpUpdateKey(){
	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;
}

int x=320, y=240;
int Handle;

void gpCalc(){
	if( Key[ KEY_INPUT_RIGHT ] >= 1 ){
		x++;
	}
	if( Key[ KEY_INPUT_DOWN  ] >= 1 ){
		y++;
	}
	if( Key[ KEY_INPUT_LEFT  ] >= 1 ){
		x--;
	}
	if( Key[ KEY_INPUT_UP    ] >= 1 ){
		y--;
	}
}

void gpDraw(){
        DrawRotaGraph( x, y, 1.0, 0.0, Handle, TRUE );
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

        Handle = LoadGraph("画像/キャラクタ01.png");

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

                gpCalc();

                gpDraw();

	}

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


これは最初に示したサンプルと全く同じ動きをするプログラムですが、関数わけすることで、処理のまとまりが分かりやすくなったと思います。

gpCalc関数 が計算フェーズ

gpDraw関数 が描画フェーズ ですね。

プログラムが巨大になっても、この作りを維持することが大切です。

サンプルのたびに関数分けしているとコードが長くなるので、サンプルでは関数分けしませんが、サンプルを見る時も処理の区分を意識して見て下さい。

→分からないことがあれば掲示板で質問して下さい


- Remical Soft -