完成後の実行イメージ。 ゲーム本編にいままで出来たモジュールを組み込みましょう。
[gameMain.cpp]
ヘッダの変更はないので、いきなり本編です。
●ヘッダの追加
今まで説明してきたのモジュールのヘッダを追加します。
char,map,data,mapMoveですね。 ●定数と構造体の変更と変数の変更
主人公の定数を追加。
PLAYER_FILENAME、PLAYER_CHAR_XNUM、PLAYER_CHAR_YNUM
GameMainData_tに2つ追加しています。
2回初期化する必要のない処理をスキップするためのフラグと
int bFirstInit; //一回目の初期化済みのフラグ。
マップ移動に関連したデータ持つための構造体データです。
MapMoveInfo_t mapMoveData;
s_GameMainDataは、初期化が変わったので値を差し替えます。
// ゲーム本編のデータ。
static GameMainData_t s_GameMainData = {GAMEMAIN_INITTYPE_FIRSTSTART,FALSE};
// 主人公のデータ
#define PLAYER_FILENAME "data/char/player.png"
#define PLAYER_CHAR_XNUM 3 //横3パーツ(アニメ)
#define PLAYER_CHAR_YNUM 4 //縦4パーツ(方向)
// ゲーム本編のデータの構造体。
typedef struct {
GameMainInitType_t initType; //初期化タイプ
int bFirstInit; //一回目の初期化済みのフラグ。
STATEMNG_OBJECT StateObj; //ゲーム本編の状態管理オブジェクト
int beforeBattleInState; //バトル開始前の状態
// マップ移動に関連したデータ
MapMoveInfo_t mapMoveData;
} GameMainData_t;
//----------------------------------------------------------------------
// 変数
//----------------------------------------------------------------------
// ゲーム本編のデータ。
static GameMainData_t s_GameMainData = {GAMEMAIN_INITTYPE_FIRSTSTART,FALSE};
マップ処理などが増えたので初期化を書き換えます。
bFirstInitがFALSEの時のみの処理をまとめます。
StateObjは前からありましたね。
追加したのは、PlayerObjのロードと主人公の座標、map_Initでの初期化処理です。
これらは一回だけ行います。
//----------------------------------------------------------------------
// ゲーム本編の初期化
//----------------------------------------------------------------------
void GameMain_Init(GameMainInitType_t initType)
{
// モードの設定
s_GameMainData.initType = initType;
// 初回?
if( s_GameMainData.bFirstInit == FALSE ) {
s_GameMainData.bFirstInit = TRUE;
// ゲーム本編の状態管理オブジェクトの作成。
// オブジェクトと言ってもC++のクラスとは無関係です。
s_GameMainData.StateObj = STM_Init(GAMEMAIN_STATE_MAX);
// 主人公キャラオブジェクトの作成。
s_GameMainData.mapMoveData.PlayerObj = char_Load(PLAYER_FILENAME,PLAYER_CHAR_XNUM,PLAYER_CHAR_YNUM);
// 主人公キャラオブジェクトの仮の初期座標や向き
s_GameMainData.mapMoveData.player_px = ((SCREEN_X/CHAR_PIXEL_SIZEX)/2-1) * CHAR_PIXEL_SIZEX;
s_GameMainData.mapMoveData.player_py = ((SCREEN_Y/CHAR_PIXEL_SIZEY)/2+2) * CHAR_PIXEL_SIZEY;
s_GameMainData.mapMoveData.player_muki = CHAR_MUKI_DOWN;
// マップ管理の初期化
map_Init(g_MapDefDatas);
}
// ゲーム本編の状態を初期化
STM_ChangeState(s_GameMainData.StateObj,GAMEMAIN_STATE_MAPLOAD);//マップロード処理へ遷移。
}
終了時にchar_Deleteで主人公キャラの破棄、map_Endでマップ系の破棄を行います。
//----------------------------------------------------------------------
// ゲーム本編の終了
//----------------------------------------------------------------------
void GameMain_End()
{
// ゲーム本編の状態管理オブジェクトの破棄
STM_End(s_GameMainData.StateObj);
// 主人公キャラオブジェクトの破棄。
char_Delete(s_GameMainData.mapMoveData.PlayerObj);
// マップ管理の終了
map_End();
}
GameMain()先頭にある
// ゲーム本編だよって表示
CenterDrawString( "ゲーム本編です。", 28, 100, GetColor(255,255,255) );
は削除して移動させます。それぞれ次の場所に移してください。
static void GameMain_Shop()
{
// ゲーム本編だよって表示
CenterDrawString( "ゲーム本編です。", 28, 100, GetColor(255,255,255) );
static void GameMain_Menu()
{
// ゲーム本編だよって表示
CenterDrawString( "ゲーム本編です。", 28, 100, GetColor(255,255,255) );
static void GameMain_BattleIn()
{
// ゲーム本編だよって表示
CenterDrawString( "ゲーム本編です。", 28, 100, GetColor(255,255,255) );
static int GameMain_Battle()
{
// ゲーム本編だよって表示
CenterDrawString( "ゲーム本編です。", 28, 100, GetColor(255,255,255) );
static void GameMain_BattleEnd()
{
// ゲーム本編だよって表示
CenterDrawString( "ゲーム本編です。", 28, 100, GetColor(255,255,255) );
アップロード処理です。
実際のマップ処理を呼び出しています。
ロードが終わったら、そのまま状態遷移します。
//----------------------------------------------------------------------
// マップロード処理
//----------------------------------------------------------------------
static void GameMain_MapLoad()
{
// 町にマップチェンジ。仮の処理
s_GameMainData.mapMoveData.MapSize = map_Load("town");
// 次はマップロード時のイベントへ。
STM_ChangeState(s_GameMainData.StateObj,GAMEMAIN_STATE_EVENT);//イベント中へ遷移。
}
マップ移動です。
実際の主人公の移動は、mapMove_Mainで行っています。
このmapMove_Mainの結果を元に状態を遷移します。
最後に、mapMove_Drawでキャラとマップを表示しています。
//----------------------------------------------------------------------
// マップ移動中
//----------------------------------------------------------------------
static void GameMain_MapMove()
{
// 今のフレーム
int frame = STM_GetFrameCount(s_GameMainData.StateObj);
// 実際の移動処理
mapMove_Main(&s_GameMainData.mapMoveData);
// 移動の結果判定
switch( s_GameMainData.mapMoveData.rtnCode ) {
case MAPMOVE_RTNCODE_CONTINUE: //移動継続
// 何もしない。
break;
case MAPMOVE_RTNCODE_EVENT: //イベント発生
STM_ChangeState(s_GameMainData.StateObj,GAMEMAIN_STATE_EVENT);//イベント中へ遷移。
// イベントに関する情報の受け渡しとかもここでを予定。
break;
case MAPMOVE_RTNCODE_ENCOUNT: //エンカウント
STM_ChangeState(s_GameMainData.StateObj,GAMEMAIN_STATE_BATTLE_IN);//戦闘開始へ遷移。
break;
case MAPMOVE_RTNCODE_MENU: //メニュー遷移
STM_ChangeState(s_GameMainData.StateObj,GAMEMAIN_STATE_MENU);//メニューへ遷移。
break;
}
// マップとキャラクタ表示処理
mapMove_Draw(&s_GameMainData.mapMoveData,frame);
}
では、今回のプロジェクトをダウンロードして下さい。
グラフィックデータが入っている関係でダウンロードが必須です。 マップとキャラクタに関してはTKOZさんにご協力を頂きました。ありがとうございます。
以上を組み込めばゲームのマップ移動でキャラが動いているはずです。
さーて、ここまででRPGのどのぐらいが完成したのでしょうか?
「プログラミング/初心者向け/チュートリアル/段階的学習/FF風RPGを作れ - game-develop.com wiki」
http://bit.ly/b8Nxiz
少し段階として難易度のばらつきはありますが、ここまででレベル6をクリアです。
実のところ、まだまだですよね。この作業の多さがRPG作成者を悩ませるんですよね。
さて、次回はチュートリアルと順番が違いますがレベル8,9のウィンドウ・システムを作成します。
更に其の次のイベントに入ると音関係は後回しなのでトントン拍子に進んでレベル11まで行けると思います。
果てして今年中に終わるか!私にも分かりません(^^;