著者:原口 莉奈
私は最近、RPG(Role-Playing Game)の戦闘シーンをC++言語で作成しました。作成には、無償で利用できるゲーム開発用ライブラリ「DXライブラリ」(https://dxlib.xsrv.jp/)を用いています。今回は、その一部であるコマンド選択画面の実装について紹介します。
シェルスクリプトマガジン Vol.93は以下のリンク先でご購入できます。![]()
![]()
図2 ビルド用のバッチファイル「build.bat」に記述する内容
g++ -c Main.cpp -DDX_GCC_COMPILE -I"DxLib"
g++ -o game.exe Main.o -L"DxLib" -lgcc -lDxLib -lDxUseCLib ^
-lDxDrawFunc -ljpeg -lpng -lzlib -ltiff -ltheora_static ^
-lvorbis_static -lvorbisfile_static -logg_static ^
-lbulletdynamics -lbulletcollision -lbulletmath -lopusfile ^
-lopus -lsilk_common -lcelt
図3 「Main.cpp」ファイルに記述するコード
#define WIN_X 256
#define WIN_Y 224
#include <DxLib.h>
int WINAPI WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR IpCmdLine,
_In_ int nShowCmd)
{
ChangeWindowMode(TRUE);
DxLib_Init();
// ウィンドウ初期化
SetWindowText("game"); // タイトル
SetGraphMode(WIN_X, WIN_Y, 32); // 解像度と色深度
SetBackgroundColor(255, 255, 255); // 背景色
WaitKey();
DxLib_End();
return 0;
}
図5 「Main.cpp」ファイルに記述するコード
#define WIN_X 256
#define WIN_Y 224
#include <DxLib.h>
#include "Status.h"
#include "Battle.h"
int WINAPI WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR IpCmdLine,
_In_ int nShowCmd)
{
ChangeWindowMode(TRUE);
DxLib_Init();
SetWindowText("game");
SetGraphMode(WIN_X, WIN_Y, 32);
SetBackgroundColor(255, 255, 255);
SetDrawScreen(DX_SCREEN_BACK); // 裏画面描画
SetWindowSize(1024, 960); // ウィンドウサイズ
Battle.materialLoad();
while (ProcessMessage() == 0)
{
SetBackgroundColor(0, 0, 0);
Battle.BattleDraw();
}
DxLib_End();
return 0;
}
図6 「Status.h」ファイルに記述するコード
class BATTLE {
public:
struct Status {
char name[50];
int HP, ATK, DEF; //体力、攻撃力、防御力
};
struct Status player = { "player",30, 10, 5 };
struct Status villain = { "villain",30, 7, 5 };
struct Status* Player = &player;
const char* str[4] = { "たたかう", "まもる",
"どうぐ", "にげる" };
const char* item[1] = { "回復" };
int firstsym = 80;
int sym = firstsym;
int sym_limit = firstsym + (4 - 1) * 17;
int symbol = -1, symnext = 0;
int pattern = 1;
int firstarrow = 80;
int arrow = firstarrow;
int limit; // firstarrow + (num - 1) * 17
int a_posi = -1;
int re = 0;
int black, white, ms;
void materialLoad();
void BattleDraw();
void one();
void two();
void Choices(int x, const char* str[], int n);
private:
};
図7 「Battle.h」ファイルに記述するコード
BATTLE Battle;
void BATTLE::materialLoad() {
black = GetColor(0, 0, 0);
white = GetColor(255, 255, 255);
ms = CreateFontToHandle("MS ゴシック", 10, 6,
DX_FONTTYPE_ANTIALIASING_4X4);
}
void BATTLE::Choices(int x, const char* str[], int n) {
int w = 0;
for (int i = 0; i < n; i++) {
DrawBox(x, firstarrow + w,
x + 80, firstarrow + 16 + w, white, TRUE);
DrawFormatStringToHandle(x + 5, firstarrow + 5 + w,
black, ms, str[i]);
w += 17;
}
}
// 初期表示
void BATTLE::one() {
sym = firstsym;
pattern = 2;
}
// 矢印の移動
void BATTLE::two() {
if (symnext == 0) {
switch (WaitKey()) {
case KEY_INPUT_DOWN:
if (sym != sym_limit) sym += 17;
break;
case KEY_INPUT_UP:
if (sym != firstsym) sym -= 17;
break;
case KEY_INPUT_ESCAPE:
DxLib_End();
break;
}
if (symbol != -1) symnext++;
}
}
void BATTLE::BattleDraw() {
SetDrawScreen(DX_SCREEN_BACK);
ClearDrawScreen();
switch(pattern):
if (pattern == 1) one();
else if (pattern == 2) two();
Choices(160, str, 4);
DrawFormatStringToHandle(144, sym, white, ms, "→");
ScreenFlip();
}
図9 「Status.h」ファイルにHpDraw()関数の記述を追加
(略)
void HpDraw();
void BattleDraw();
(略)
図10 「Battle.h」ファイルのBattleDraw()関数定義部分をこのように書き換える
(略)void BATTLE::HpDraw() {
DrawBox(180, 160, 250, 184, white, FALSE);
DrawBox(180, 186, 250, 210, white, FALSE);
DrawFormatStringToHandle(182, 162, white, ms,
"villain\nHP: %d", villain.HP);
DrawFormatStringToHandle(182, 188, white, ms,
"player\nHP:%d", player.HP);
}
void BATTLE::BattleDraw() {
SetDrawScreen(DX_SCREEN_BACK);
ClearDrawScreen();
switch(pattern):
if (pattern == 1) one();
else if (pattern == 2) two();
Choices(160, str, 4);
DrawFormatStringToHandle(144, sym, white, ms, "→");
HpDraw();
ScreenFlip();
}