データは講座8-0で解説したPlatinumで作成したfmfフォーマットの物を使用します。
詳しくはプログラム編にて説明しますので、とりあえずヘッダを解説しましょう。
[map.h]
●定数
まず定数で、マップ毎にロード出来るキャラクタの最大数を定義します。
町人とかのキャラクタの種類の最大数となります。
今のコードだと16種類の町人です。まぁ、十分だと思います。
#ifndef INCLUDE_MAP_H
#define INCLUDE_MAP_H
//----------------------------------------------------------------------
// 定数
//----------------------------------------------------------------------
// 最大のマップ登録キャラクタ数
#define MAPDEF_CHAR_MAX 16
マップの情報を定義するための構造体です。
今回の場合は後で解説するdata.cpp/hに記述しています。
マップは、マップ名をキーにして検索しますので同名は許されませんので注意してください。
マップフィル名、マップチップ画像ファイル名、マップ固有のキャラクタ・ファイル
の定義は名前の通りです。
エンカウントに付いては、今のところ予定って感じです。
エンカウントする平均歩数とエンカウント時に出現する敵の種別を指定します。
本当は、DQやFFだともう少し細かいエンカウント制御をしているんですが
簡単RPGと言うことでご容赦下さい。
●構造体 MapSize_t
map_Loadした時にマップのサイズ情報を返す構造体です。
チップサイズとピクセルサイズを得ることが出来ます。
//----------------------------------------------------------------------
// 構造体
//----------------------------------------------------------------------
// マップ定義構造体
typedef struct {
char *mapName; //マップ名
char *mapFile; //マップファイル名(fmf)
char *mapCgFile; //マップチップ画像ファイル名
char *(mapCharFile[MAPDEF_CHAR_MAX]); //マップ固有のキャラクタ・ファイル
int EncountAveSteps; //エンカウント平均歩数(0にするとバトルは発生しない。エンカウントする平均歩数を指定する)
int EncountEnemyType; //エンカウントする敵の種別
//イベント構造体ポインタ(未定義)
} MapDefine_t;
// マップサイズ構造体
typedef struct {
int cx; //横チップ数
int cy; //縦チップ数
int px; //横ピクセルサイズ(横チップ数×1チップの横ピクセル数)
int py; //縦ピクセルサイズ(縦チップ数×1チップの縦ピクセル数)
} MapSize_t;
これに付いては詳細を説明しませんが、map_Initを最初に一回呼んで、
あとは終わるときにmap_Endを呼びます。
map_Loadは文字通りマップとマップ固有キャラをロードします。
map_Drawでロードしたマップとマップ固有キャラを表示。
map_HitJudgeでマップ地形やマップ固有キャラとの衝突を判定できます。
//----------------------------------------------------------------------
// 関数の宣言
//----------------------------------------------------------------------
// マップ管理の初期化。マップを定義を設定する。
extern void map_Init(MapDefine_t mapDefines[]);
// マップ管理の終了。確保したマップ・メモリの破棄。
extern void map_End();
// マップのロード。必要に応じて前のマップの破棄。マップのサイズを返す。
extern MapSize_t map_Load(char *mapName);
// マップ表示。px,pyは表示するマップの左上の座標。
extern void map_Draw(int px,int py,int frame);
// マップとの当たり判定。px,pyはキャラクタの左上座標。
extern int map_HitJudge(int px,int py);
// イベント判定
// map_Event(int x,int y); //詳細未定。
#endif /*INCLUDE_MAP_H*/
続いてプログラム部分です。
[map.cpp]
少々長いので覚悟してください。
外部関数で5つ、内部関数で7つあります。
●まず先頭部分です。
内部関数は、当たり判定とロード系、破棄系に分かれます。
詳しくは各関数の説明で。
#include
#include "main.h"
#include "map.h"
#include "char.h"
//----------------------------------------------------------------------
// 内部関数の定義
//----------------------------------------------------------------------
// マップとの当たり判定
static int map_HitCheck(int px,int py);
// マップ固有キャラとの当たり判定
static int map_HitMapCharCheck(int px,int py);
// 新しいマップデータをロード
static void map_LoadMapData(char *mapName);
// マップ定義を検索する。
static MapDefine_t *map_searchMapDef(char *mapName);
// 新しいキャラクタをロード
static void map_LoadCharData();
// 前のマップデータの破棄
static void map_DeleteMapData();
// 前のキャラクタの破棄
static void map_DeleteCharData();
ここからいきなり多いですね。
まずマップレイヤーの定義で、前に書いた通り3つのレイヤーがあります。
マップチップ、マップの地形当たり判定、イベントのレイヤーですね。
マップチップ画像の横の個数(MAPCG_WIDTH)は横の個数だけ定義しています。
マップキャラのパーツ定義は、マップに表示されるキャラクタのパーツ構成と
発生しうるキャラクタの最大数を定義します。
EVENT_CHAR_BORN_NOはは後で解説しますが、イベント定義のキャラ発生に関わる
定数です。
//----------------------------------------------------------------------
// 定数
//----------------------------------------------------------------------
// マップレイヤーの定義
enum {
MAP_LAYER_CHIP, //マップチップのデータ
MAP_LAYER_HIT, //マップの地形当たり判定
MAP_LAYER_EVENT, //マップのイベントデータ
MAP_LAYER_MAX,
};
// マップチップ画像の横の個数。
// 横16個x縦16個の256個でマップチップを構成します。
#define MAPCG_WIDTH 16
// マップキャラのパーツ定義
#define MAP_CHAR_XNUM 3 //横3パーツ(アニメ)
#define MAP_CHAR_YNUM 4 //縦4パーツ(方向)
#define MAP_CHAR_BORN_MAX 64 //マップ上の発生するかもしれないキャラの最大数
// イベントに関する定義
#define EVENT_CHAR_BORN_NO 0x40 //キャラ発生のスタートイベント番号
これは、Platinumのマップファイルであるfmf形式ファイルのフォーマットです。
Platinumのサンプルプログラムからそのまま貰ってきました。
fmfファイルから直接読み込むことで、ヘッダ情報を得ることが出来ます。
//----------------------------------------------------------------------
// 構造体
//----------------------------------------------------------------------
// FMFファイルヘッダ (20 bytes)
typedef struct tag_FMFHeader {
DWORD dwIdentifier; // ファイル識別子 'FMF_'
DWORD dwSize; // ヘッダを除いたデータサイズ
DWORD dwWidth; // マップの横幅
DWORD dwHeight; // マップの高さ
BYTE byChipWidth; // マップチップ1つの幅(pixel)
BYTE byChipHeight; // マップチップ1つの高さ(pixel)
BYTE byLayerCount; // レイヤーの数
BYTE byBitCount; // レイヤデータのビットカウント
} FMF_HEADER;
マップ固有のキャラの位置や画像を管理するための構造体です。
// マップ固有キャラの情報
typedef struct {
int bLive; //存在フラグ
int muki; //向き
int px; //座標ピクセルX
int py; //座標ピクセルY
int ChrObjNo; //キャラオブジェクトの番号
int AnimOfs; //アニメタイミングを変えるためのオフセット
} MapChar_t;
マップ管理のための情報が詰まった構造体です。
マップ定義配列や今現在のマップ名、今現在有効なマップ定義でマップを管理します。
読み込まれたマップのデータは、FMFファイルヘッダ、マップデータ全体、レイヤー毎の
マップデータとして管理されます。
imageMapCGは一枚絵として読み込んだマップチップ画像です。
マップ固有のキャラは、MapCharObj、MapCharNums、MapCharで管理されます。
MapMngDataは、その構造体の実体です。
// マップ管理構造体
typedef struct {
MapDefine_t *mapDefines; //マップ定義配列
char mapName[512]; //マップ名
MapDefine_t *cur_mapDef; //有効なマップ定義
// マップのデータ
FMF_HEADER fmfHeader; //FMFファイルヘッダ
BYTE *allMapData; //マップデータ全体
BYTE *MapData[MAP_LAYER_MAX]; //マップデータ。レイヤー毎
// マップチップ画像データ
int imageMapCG; //マップチップ画像(一枚絵として読み込む)
// マップ固有のキャラクタ・データ
CHAR_OBJECT MapCharObj[MAPDEF_CHAR_MAX]; //マップ固有のキャラのオブジェクト
int MapCharNums; //マップ固有のキャラのオブジェクトの有効数
MapChar_t MapChar[MAP_CHAR_BORN_MAX]; //マップ固有のキャラの情報
} MapMng_t;
//----------------------------------------------------------------------
// 変数
//----------------------------------------------------------------------
// マップ定義の情報配列ポインタ
static MapMng_t MapMngData = {NULL};
次もマップ管理のプログラム編です。