第1章 まずはメニューを表示しよう
実習編第一回ということで今後ゲームを
作っていく準備をします。
プロジェクトの作成
ゲームを作成するにはとりあえずプロジェクトを
作らないとね
►ゲームプログラミング講習 「0.2.プロジェクトの準備」を 参考にプロジェクトを準備しよう ファイル名は半角英数をお勧めします
必要な画像ファイルをダウンロードしよう
►Debugファイルに直接入れよう ►時間があれば、自分好みにアレンジしよう プロジェクト名─┼─Debug─┼─enemy.bmp │ ├─myCharacter.bmp │ etc ┼─プロジェクト名#include "DxLib.h"
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { ChangeWindowMode(TRUE); //ウィンドウのサイズ変更 SetGraphMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32) ; if (DxLib_Init()) return -1; SetDrawScreen(DX_SCREEN_BACK); SetTransColor(255, 0, 255); while (true) { if (ClearDrawScreen()) break; if (ScreenFlip()) break; if (ProcessMessage()) break; } DxLib_End(); return 0; }
ゲームの基盤を作る(1)
第1章 まずはメニューを表示しよう 3 main.cppに以下のコードを書こうゲームの基盤を作る(2)
このままどんどんコードを追加してっても良いけど
見にくくなりそう
メイン関数で書くことは抽象的に
じゃあメニューの表示関数、初期化関数を作ろう
メイン関数には大まかな流れだけを書く メニュー表示 ゲーム終了 ゲーム ゲームオーバー ゲームクリアーbool init(void){
ChangeWindowMode(TRUE);
SetGraphMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32) ;
if (DxLib_Init()) return false; SetDrawScreen(DX_SCREEN_BACK); SetTransColor(255, 0, 255); return true; }
ゲームの基盤を作る(3)
init関数(main.cpp)
ゲームの初期化処理を行う
bool init(void);
戻り値
初期化に成功すれば
true
失敗すれば
falseを返す
init関数は以下の通りになるよ (基本コピペでOK、WinMain関数の上に書こう)ゲームの基盤を作る(4)
init関数を作るとWinMain関数が書きなおせるね
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
if(!init()) return -1; while (true) { if (ClearDrawScreen()) break; if (ScreenFlip()) break; if (ProcessMessage()) break; } DxLib_End(); return 0; } 次はメニューを表示する関数を作ろう
ゲームの基盤を作る(4)
戻り値をどうするかです 最初は
・ゲームに進むか
・ゲームを終了するか
の2択なのでbool型(true,false)でいいかもしれません 最高スコアの表示等の新たな選択肢を作ったとき
これだと拡張しにくいですね
int型より列挙体を使ったほうがよさそう!
ゲームの基盤を作る(5)
enum startScreenMenu{ START_SCREEN_END = 1, //ゲームを終了する START_SCREEN_START = 0 //ゲームを開始する }; ということで、WinMain関数より上に列挙体を書こう これを使ってスタートメニューの表示関数を作ろうstartScreenStart関数(main.cpp)
スタートメニューの表示
startScreenMenu startScreenStart(void);
戻り値
列挙体に書いたコメントと同じ
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { if(!init()) return -1; startScreenStart(); //今はまだ戻り値は関係ない DxLib_End(); return 0; }
ゲームの基盤を作る(6)
次の関数をWinMain関数より上、さっきの列挙体より下に書こうstartScreenMenu startScreenStart(void){
//ここに関数初期化処理を書く
while (true) {
if (ClearDrawScreen()) return START_SCREEN_END;
//ここに色々処理を書く
if (ScreenFlip()) return START_SCREEN_END;
if (ProcessMessage()) return START_SCREEN_END; }
}
DrawExtendGraph関数(DxLib.h)
画像を拡大縮小しながら表示します
int DrawExtendGraph(int x1,int y1,int x2,int y2, int GrHandle,int TransFlag);
x1, y1 画像の左上の場所 x2, y2 画像の右下の座標 + 1 GrHandle LoadGraphで得られた画像のハンドル TransFlag 透明を有効にするか 戻り値 成功 : 0 エラー : -1
背景画像表示(1)
まず、以下の関数で背景画像を表示してみよう LoadGraph関数(DxLib.h) 画像を読み込み、メモリ上へ展開します int LoadGraph(char *FileName);FileName 画像のファイル名
背景画像表示(2)
startScreenMenu startScreenStart(void){
int backImageHandle = LoadGraph("title.bmp");
while (true) {
if (ClearDrawScreen()) return START_SCREEN_END;
DrawExtendGraph(0, 0, SCREEN_WIDTH,
SCREEN_HEIGHT, backImageHandle, TRUE);
if (ScreenFlip()) return START_SCREEN_END;
if (ProcessMessage()) return START_SCREEN_END; }
}
startScreenStart関数の中身を以下のように書き加えよう
選択肢画像の表示(1)
選択肢画像の表示もしていきましょう。 選択肢画像は以下のように表示したいと思います 画面 選択肢 同じ幅に、 つまり、画面の真ん中 画像の幅をwidth、画面の幅をSCREEN_WIDTHとすると 画像のx座標は SCREEN_WIDTH / 2 – width / 2 になるね 画像の真ん中であり、画面の真ん中でもある選択肢画像の表示(2)
画像の表示に少し計算が必要なので、
指定した座標を画像の真ん中として表示する関数を作ろう
drawCenterGraph関数(main.cpp)
指定した座標を画像の真ん中にし、画像表示
int DrawCenterGraph(int x, int y, int handle);
x, y 表示する座標
handle LoadGraphで得られた画像のハンドル 戻り値 成功 : 0 エラー : 1
選択肢画像の表示(3)
drawCenterGraph関数内では以下の関数を使用します
GetGraphSize関数(DxLib.h)
画像のサイズを取得します
int DrawCenterGraph(int GrHandle,
int* SizeXBuf,int* SizeYBuf);
GrHandle LoadGraphで得られた画像のハンドル SizeXBuf,SizeYBuf 幅、高さの変数のアドレス 戻り値 成功 : 0 エラー : 1 DrawGraph関数(DxLib.h) スペースの関係上省略 詳しくはゲームプログラミング講習を見てね
選択肢画像の表示(4)
では、drawCenterGraph関数の作成をしましょう 画面 指定座標(x,y) 同じ幅 画像の幅をwidth、 指定X座標をxとすると 画像の左上は x – width / 2 だねint drawCenterGraph(int x, int y, int handle){
int width, height;
GetGraphSize(handle, &width, &height);
return DrawGraph(x - width / 2, y - height / 2,
handle, TRUE); }
選択肢画像の表示(5)
これを使って選択肢画像を表示しましょう
startScreenStart関数に以下の太字部分を追加しましょう
startScreenMenu startScreenStart(void){
int backImageHandle = LoadGraph("title.bmp");
int gameStartImageHandle = LoadGraph("gamestart.bmp");
int gameEndImageHandle = LoadGraph("gameend.bmp");
while (true) {
if (ClearDrawScreen()) return START_SCREEN_END; DrawExtendGraph(0, 0, SCREEN_WIDTH,
SCREEN_HEIGHT, backImageHandle, TRUE);
drawCenterGraph(SCREEN_WIDTH / 2, 400,
gameStartImageHandle); drawCenterGraph(SCREEN_WIDTH / 2, 500,
gameEndImageHandle);
if (ScreenFlip()) return START_SCREEN_END;
if (ProcessMessage()) return START_SCREEN_END; }
選択肢画像の表示(6)
これで以下のようになりましたね
選択メニューの作成(1)
どのメニューが選択されているかを変数にする必要がありますね また、その変数によって出す画像を変えましょう
startScreenMenu startScreenStart(void){
int backImageHandle = LoadGraph("title.bmp");
int gameStartImageHandle = LoadGraph("gamestart.bmp");
int gameEndImageHandle = LoadGraph("gameend.bmp");
int gameStartImageSelectedHandle =
LoadGraph("gamestartselected.bmp");
int gameEndImageSelectedHandle =
LoadGraph("gameendselected.bmp"); startScreenMenu selected = START_SCREEN_START;
while( true ){
//ループ内は次ページ }
}
選択メニューの作成(2)
if (ClearDrawScreen()) return START_SCREEN_END; DrawExtendGraph(0, 0, SCREEN_WIDTH,
SCREEN_HEIGHT, backImageHandle, TRUE);
if(selected == START_SCREEN_START) drawCenterGraph(SCREEN_WIDTH / 2, 400, gameStartImageSelectedHandle); else drawCenterGraph(SCREEN_WIDTH / 2, 400, gameStartImageHandle); if(selected == START_SCREEN_END) drawCenterGraph(SCREEN_WIDTH / 2, 500, gameEndImageSelectedHandle); else drawCenterGraph(SCREEN_WIDTH / 2, 500, gameEndImageHandle);
if (ScreenFlip()) return START_SCREEN_END;
if (ProcessMessage()) return START_SCREEN_END;
選択メニューの作成(3)
先ほどのselected変数をキーボードが押されたら 変える必要がありますね 列挙体には ゲーム開始・・・・0 ゲーム終了・・・・1 を割り当ててあり メニューはゲーム開始が上に表示されているので 以下の処理が必要です selectedが0より大きく上が押されたら、 selectedを1引く selectedがゲーム終了より小さく下が押されたら、 selectedを1足す 以上の処理をさらに追加しましょう選択メニューの作成(4)
キーボードの情報は以下の関数で取得できます
CheckHitKey関数(DxLib.h)
引数で指定したキーが押されているかどうかを取得 int CheckHitKey(int KeyCode);
KeyCode 押されているかを取得するキー 詳細はDXライブラリのページを参照 戻り値 押されていない : 0 押されている : 1 •↑キー KEY_INPUT_UP •↓キー KEY_INPUT_DOWN •Enterキー KEY_INPUT_RETURN keyCode引数の値 他のキーはDXライブラリホームページ参照
選択メニューの作成(5)
if (ClearDrawScreen()) return START_SCREEN_END;if (CheckHitKey(KEY_INPUT_UP) && selected > 0)
selected = (startScreenMenu)(selected - 1);
if (CheckHitKey(KEY_INPUT_DOWN) && selected < START_SCREEN_END) selected = (startScreenMenu)(selected + 1);
DrawExtendGraph(0, 0, SCREEN_WIDTH,
SCREEN_HEIGHT, backImageHandle, TRUE);
if(selected == START_SCREEN_START) drawCenterGraph(SCREEN_WIDTH / 2, 400, gameStartImageSelectedHandle); else drawCenterGraph(SCREEN_WIDTH / 2, 400, gameStartImageHandle); //以下略 startScreenStart関数のループ内に以下の太字を追加しよう
選択メニューの作成(6)
Enterキーが押されたらselected変数の値を返すようにします
if (ClearDrawScreen()) return START_SCREEN_END; //さっき追加したところ
if (CheckHitKey(KEY_INPUT_UP) && selected > 0)
selected = (startScreenMenu)(selected - 1);
if (CheckHitKey(KEY_INPUT_DOWN) && selected < START_SCREEN_END) selected = (startScreenMenu)(selected + 1);
if (CheckHitKey(KEY_INPUT_RETURN))
break;
DrawExtendGraph(0, 0, SCREEN_WIDTH,
SCREEN_HEIGHT, backImageHandle, TRUE); //以下略
startScreenStart関数のループ内に以下の太字を追加しよう
そして、関数の一番最後(ループの下)に以下を追加します
選択メニューの作成(7)
よく使いそうな構造体(1)
よく使いそうな次の二つの構造体を作ろう
point構造体
座標を表すのに使用 持つべき変数 x座標(int型) y座標(int型)size構造体
四角形の大きさを表すのに使用 持つべき変数 幅(int型) 高さ(int型)よく使いそうな構造体(2)
main.cppにどんどん追加していくと見にくくなるので、 新たにファイルを作ろう
struct point{ int x,y;
point(int x,int y){
this->x = x; this->y = y; } point(void){ this->x = 0; this->y = 0; } }; struct size{ int width,height;
size(int width,int height){
this->width = width; this->height = height; } size(void){ this->width = 0; this->height = 0; } };