C++ DXライブラリ ゲーム開発 プログラミング講座

シューティングゲームを作る part3.ゲームループとキー入力


 

まとめ

  • ゲームループについて解説した
  • キー入力による自機の移動を行った

はじめに

前回の記事はこちら
自機の描画までを行っている.

今回は,ゲームループの解説と, キー入力による自機の移動を行う.

ゲームループとは

プログラムとは,上から下に進む.
そして,一番下まで進んだら終了である.

前回の完成コードも,例外なくそうなっている

include "DxLib.h"
void DrawPlayer( float x, float y )
{
// 本体の表示
DrawBox(x-16, y-16, x+16, y+16, 0xff0088ff, 0);
}
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
//int main()
{
ChangeWindowMode( true );
if( DxLib_Init() == -1 )     // DXライブラリ初期化処理
{
return -1 ;          // エラーが起きたら直ちに終了
}
DrawPlayer( 320, 340 );
WaitKey();            // キー入力を待つ
DxLib_End() ;               // DXライブラリ使用の終了処理
return 0 ;               // ソフトの終了 
}

しかし,ゲームはどうだろうか.

プログラムが上から下まで進んで終了するだろうか?
否,ゲームは,ユーザーが明示的に終了するまで実行される.

それまでどうしているかというと,
処理が繰り返されているのである.

つまり,ゲームは,

  • ユーザーからのキー入力を受け付け
  • それによってゲームの内容を処理
  • 画面に絵として出力,または音を出力

といった処理を繰り返し行うことで実現されている.

f:id:gothlab:20210805203858p:plain

これをゲームループと呼ぶ.

フレームレート(FPS)とは

フレームレートという言葉を聞いたことがないだろうか.

これは FPS(frame per second)とも呼ばれ,
1秒間で行われるゲームループの数をそう呼ぶ.

1秒間に 60 回ループすれば, 60fps である.

30fps
もしくは
60fps
が一般的.

プログラムでゲームループを実現する

プログラムでゲームループを実現するにはどうすればよいだろうか.

カンの良い方なら気づくだろうが,
while 文を用いて実現されるのである.

while でを無限に繰り返し,
ループ内で 入力,処理,出力 の処理を行えば良い.

つまり,擬似コードを書くと以下のような感じだ.

while( true )
{
入力();
処理();
出力();
}

これに,FPS 制御を加えないと,
ものすごい高速でループしてしまう.

FPS 制御はややこしいので, DXライブラリに任せてしまう.

つまり,以下のようになる.

 while( ProcessMessage() == 0)
{
// ゲームループ
ClearDrawScreen(); // 画面を消す
ScreenFlip(); //裏画面を表画面に反映
}

キー入力をする

それでは,実際に上記の入力に当たる,
キー入力をプログラミングしてみる.

DXライブラリのキー入力関数は

  • CheckHitKey

dxlib.xsrv.jp

引数にキーコードを渡し,
そのキーが押されていたら 1 が,押されていなければ 0 が返ってくる.

以下のように使う.

// もしエンターキーが押されていたら
if( CheckHitKey( KEY_INPUT_RETURN ) == 1 )
{
// なにかする
}

自機の移動を行う

キー入力を用いて,自機の移動を行ってみる.

前回は自機の位置を定数で設定したが,これを変数にする.

float playerPosX = 320.0f;
float playerPosY = 340.0f;

この値を,キー入力があった方向によって,加減算してやれば良い.

if( CheckHitKey(KEY_INPUT_RIGHT) == 1 )
{
playerPosX += 5;
}
if( CheckHitKey(KEY_INPUT_LEFT) == 1 )
{
playerPosX -= 5;
}
if( CheckHitKey(KEY_INPUT_UP) == 1 )
{
playerPosY -= 5;
}
if( CheckHitKey(KEY_INPUT_DOWN) == 1 )
{
playerPosY += 5;
}

そして出力に当たる画面出力は前回やった.

自機の位置を表す変数に変更して,
以下のようになる.

DrawPlayer(playerPosX, playerPosY);

完成コード

#include "DxLib.h"
float playerPosX = 320.0f;
float playerPosY = 340.0f;
void DrawPlayer( float x, float y )
{
// 本体の表示
DrawBox(x-16, y-16, x+16, y+16, 0xff0088ff, 0);
}
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
//int main()
{
ChangeWindowMode( true );
if( DxLib_Init() == -1 )     // DXライブラリ初期化処理
{
return -1 ;          // エラーが起きたら直ちに終了
}
// ゲームループ
while( ProcessMessage() == 0 )
{
if( CheckHitKey( KEY_INPUT_RIGHT ) == 1 )
{
playerPosX += 5;
}
if( CheckHitKey( KEY_INPUT_LEFT ) == 1 )
{
playerPosX -= 5;
}
if( CheckHitKey( KEY_INPUT_UP ) == 1 )
{
playerPosY -= 5;
}
if( CheckHitKey( KEY_INPUT_DOWN ) == 1 )
{
playerPosY += 5;
}
// 出力
ClearDrawScreen(); // 画面を消す
DrawPlayer( playerPosX, playerPosY );
ScreenFlip(); //裏画面を表画面に反映
}
WaitKey();
DxLib_End() ;               // DXライブラリ使用の終了処理
return 0 ;               // ソフトの終了 
}

おわりに

ゲームループの説明と,自機の移動まで行った.
次回は,ショットの発射あたりをやろうと思う.

次回はこちら.

  • この記事を書いた人

GOTH

鹿児島県出身,吉祥寺在住の27歳.職業はゲーム会社でプログラマー.趣味はバイク,車,キャンプ,ガジェット,読書,そしてゲーム開発. サイトのテーマはプログラミングとガジェットでライフハック.たまに趣味に関する雑感や記録を残していく備忘録.ツイッターもやってます.
自己紹介
お問い合わせ

-C++, DXライブラリ, ゲーム開発, プログラミング講座