|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 逾越书 于 2020-1-5 23:47 编辑
流星蝴蝶剑是2002年出的单机游戏,
我们现在对里面的地图信息进行读取,做交流学习之用
定义地图结构(自定义)
struct MeteorMap
{
/*ReadOne*/
int _mapFlag = 0x05; //1. ( 4个char ) 05 00 00 00 地图标记---------
int mapNumber=0xF0000000; //2. ( 4个char ) 0A 00 00 00 编号
int mapNameSize; //3. ( 4个char ) 07 00 00 00 名字长度
/*ReadTwo*/
char* mapName = NULL; //4. (mapNameSize 个char) D6 D3 C8 E9 B6 B4 00 地图名字 char mapName[mapNameSize];
int snNameSize; //5. ( 4个char ) 63 4E 31 33 31 00 sn长度
/*ReadThree*/
char* snName = NULL; //6. ( snNameSize 个char) 63 4E 31 33 31 00 sn名字 char snName[snNameSize];
char _plotFlagChar1 = 0x01; //7(1个char) 01 00 00 00 辅助标记-------- -
int _NULL = 0x00; //8. ( 4个char ) 00 00 00 00 暂时理解为填充0---------
int _plotFlag3 = 0x03; //9. ( 4个char ) 03 00 00 00 辅助标记 ---------
int mapDisplay; //10. ( 4个char ) 0B 00 00 00 将0B改成0A此地图将不会显示
int modeDisplay; //11.( 4个char ) 11 00 00 00 剧情模式 按逻辑位或 (剧情|死斗|暗杀|护城|劫镖|盟主)
int __NULL = 0x00; //12.( 4个char ) 00 00 00 00 暂时理解为填充0---------
int _plotFlagC = 0x0C; //13.( 4个char ) 0C 00 00 00 辅助标记 ---------
int musicNum; //14.( 4个char ) 05 00 00 00 音乐编号 ( 05 ) == (s5.mp3)
int ___NULL = 0x00; //15.( 4个char ) 00 00 00 00 辅助标记 ---------
int _plotFlag1 = 0x01; //16.( 4个char ) 01 00 00 00 辅助标记 ---------
int modeList; //17.( 4个char ) 03 00 00 00 剧情任务排号
int curMapSize = 0x41; //18.( 4个char ) 0x41+mapSize+snSize 当前地图长度(非常重要的元素)//这个值会写入数组地图信息
int ____NULL = 0x00; //19.( 4个char ) 00 00 00 00 辅助标记 ---------
};
接着用数组保存地图信息 MeteorMap mapAllList[999]; //全部地图为999
char mapAllName[999][30]; //地图名字 "一线天"
char snAllName[999][20]; //地图表示 "SN03"
接下来是部分是读取过程:
CFile file;
CString filePath = _T("d:\\Meteor.res");
MeteorMap map; //临时存储一个地图数据
int Arr[12] = { 0 }; //次要成员变量存储
char snName[30] = { 0 }; // str "钟乳洞"
char mapName[20] = { 0 }; // str "SN01"
int mapEntryAddress = 0xEA1E; //第一个地图开始位置偏移
file.Open(filePath, CFile::modeRead | CFile::modeReadWrite); //打开文件
file.Seek(mapEntryAddress, CFile::begin); //定位地图开始位置
int index = 0;
for ( index = 0;index<999;index++)
{
/*ReadOne*/
file.Read(&map._mapFlag, 4); //读标志
file.Read(&map.mapNumber, 4); //编号
file.Read(&map.mapNameSize, 4); //名字长度
if ((0x00000005 != map._mapFlag) | (map.mapNameSize <= 4)) //标志不存在结束
{
break;
}
/*ReadTwo*/
file.Read(mapName, map.mapNameSize); //Read名字
strncpy_s(mapAllName[index], mapName,30); //临时mapname copy到列表数组里面
file.Read(&map.snNameSize, 4); //SN01长度
/*ReadThree*/
file.Read(snName, map.snNameSize);
strncpy_s(snAllName[index], snName, 20);
file.Read(&map._plotFlagChar1, 1);
for (int i = 0; i < 12; i++)
{
file.Read(&Arr, 4); //后面成员一次读取4个char 总共12次, 读完一个地图
}
map.mapDisplay = Arr[2]; //将0B改成0A此地图将不会显示
map.modeDisplay = Arr[3]; //剧情模式 按逻辑位或 (剧情|死斗|暗杀|护城|劫镖|盟主)
map.musicNum = Arr[6]; //音乐编号 ( 05 ) == (s5.mp3)
map.modeList = Arr[9]; //剧情任务排号
map.curMapSize =0x41+map.mapNameSize+map.snNameSize;
mapAllList[index] = map; // 存储 MeteorMap 结构体
lastMap = map; //把当前地图当做最后一个地图
map._mapFlag = 0;//如果存在标志,置为0,方便下次读取
}
file.Close();
问:读入过程为何分为三部分?
答:。因为第2次读取位置根据第1次map.mapNameSize值决定,同样,第3次读取位置根据第一次 map.snNameSize值决定,不然,定位不对,无法正确读到下一个地图
现在信息已经保存在mapAllList数组里面了,接下来就是把mapAllList成员信息显示
USES_CONVERSION;
CString str;
int i = m_ListBox.GetCurSel();
SetDlgItemText(IDC_EDIT1, A2T(mapAllList.mapName));
SetDlgItemText(IDC_EDIT2, A2T(mapAllList.snName));
str.Format(_T("%d"), mapAllList.modeDisplay);
SetDlgItemText(IDC_EDIT3, str);
str.Format(_T("%d"), mapAllList.modeList);
SetDlgItemText(IDC_EDIT4, str);
str.Format(_T("%d"), mapAllList.curMapSize);
SetDlgItemText(IDC_EDIT5, str);
str.Format(_T("%d"), mapAllList.musicNum);
SetDlgItemText(IDC_EDIT6, str);
讲数组SetDlgItemText(IDC_EDIT1, A2T(mapAllList.mapName));放入编辑框显示,i数值就是地图meteor.res编号
下面显示出来主要部分,其它部分可以通过MeteorMap结构相应显示 。
QQ:1947767412 |
-
-
|