进入每一关之前,需要对所有游戏数据初始化。进入隐藏地图,同样需要初始化。而且,从隐藏地图返回上层地图,还要保证玩家角色出现在“出水管”处。地图数据、玩家数据、视图数据,都要设置正确。
所有的游戏数据,即封装在gamemap中的数据,分成如下几种:
场景数据:包含当前关卡的地图,所有精灵,金币,提示信息。
视图数据:视图窗口坐标。
玩家数据:玩家角色的个人信息,例如金钱数量,攻击方式,游戏次数。
1. 场景数据:
int iGameState;//当前游戏状态
int iMatch; //当前关卡
各种精灵的数组:
struct MapObject MapArray[MAX_MAP_OBJECT]; //地图物品
struct MapObject MapBkArray[MAX_MAP_OBJECT]; //地图背景物品
struct ROLE MapEnemyArray[MAX_MAP_OBJECT]; //小怪
struct MapObject MapCoinArray[MAX_MAP_OBJECT]; //金币
struct ROLE FireArray[MAX_MAP_OBJECT]; //子弹
struct MapObject BombArray[MAX_MAP_OBJECT]; //爆炸效果
//当前关卡的地图信息
struct MAPINFO mapinfo;
//图片帧
int ienemyframe; //小怪图片帧
int ibkobjframe; //背景图片帧
//玩家攻击
int iTimeFire;//两个子弹的间隔时间
int iBeginFire;//是否正在发子弹
//攻击对象提示
char AttackName[20];//攻击对象名称
int iAttackLife;//攻击对象生命值
int iAttackMaxLife;// 攻击对象最大生命值
2. 视图数据:
int viewx;//视图起始坐标
3. 玩家数据:
int iMoney; //金钱数量
int iAttack; //攻击方式
int iLife; //玩家游戏次数
可见,每次加载地图前,要初始化场景数据和视图数据,而玩家数据不变,如金钱数量。
游戏数据处理:
假设没有隐藏地图的功能,游戏数据只需要完成初始化的功能,分别位于以下三个地方:
程序运行前,初始化;
过关后,初始化,再加载下一关地图;
失败后,初始化,再加载当前地图;
1. 游戏程序运行,所有游戏数据初始化。
函数:BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
代码:把所有游戏数据初始化
gamemap.Init();
游戏初始化函数:void GAMEMAP::Init()
代码:
//设置游戏初始状态
iGameState=GAME_PRE;
//设置当前关卡
iMatch=0;
//设置玩家数据 玩家游戏次数,金钱数量,攻击种类
iLife=3;
iMoney=0;
iAttack=ATTACK_NORMAL;
//设置视图坐标
viewx=0;
//初始化场景数据
InitMatch();
场景数据初始化函数:void GAMEMAP::InitMatch()
代码:把所有游戏数据清除(置0)
memset(MapArray,0,sizeof(MapArray));
memset(BombArray,0,sizeof(BombArray));
ienemyframe=0;
iFireNum=0;
……
这样,程序启动,InitInstance中完成第一次初始化。
2. 过关后,游戏数据初始化,加载下一关地图。
过关检测函数:int GAMEMAP::IsWin()
代码:
//判断玩家是否到达地图终点
if(rmain.xpos >= MAX_PAGE*GAMEW*32 )
{
//读取下一关地图编号
iMatch=mapinfo.iNextMap;
if(iMatch>=MAX_MATCH)
{
//如果全部通过
Init(); //初始化所有数据
LoadMap(); //加载地图
}
else
{
InitMatch(); //初始化场景数据
//设置玩家坐标
rmain.SetPos(BM_USER,3*32,8*32);
rmain.InitRole(0,GAMEW*32*MAX_PAGE-32);
//加载下一关的地图
LoadMap();
}
3. 如果玩家失败,重新加载当前地图。
失败检测函数:int GAMEMAP::IsWin()
代码:如果玩家碰到了小怪,或者踩到火圈,游戏失败,调用Fail()进一步处理。
//检测角色和敌人的碰撞
for(i=0;i<MAX_MAP_OBJECT;i++)
{
if(MapEnemyArray[i].show)
{
if(HLINE_ON_RECT(玩家坐标 小怪坐标))
{
if(0 == rmain.movey)
{
//玩家在行走过程中,碰到小怪,游戏失败
Fail();
}
else
{
//玩家在下落过程中,碰到火圈,游戏失败
switch(MapEnemyArray[i].id)
{
case ID_ANI_BOSS_HOUSE:
case ID_ANI_BOSS_HOUSE_A:
Fail();
……
//玩家到达地图底端(掉入小河),游戏失败
if(rmain.ypos > GAMEH*32)
{
Fail();
return 0;
}
失败处理函数:void GAMEMAP::Fail()
代码:
//玩家游戏次数减1
iLife--;
//设置游戏状态
iGameState=GAME_FAIL_WAIT;
GAME_FAIL_WAIT状态结束后,调用函数void GAMEMAP::Fail_Wait()加载地图。
函数:void GAMEMAP::Fail_Wait()
代码:
if( iLife <=0)
{
//游戏次数为0,重新开始,初始化所有数据
Init();
}
else
{
//还能继续游戏
}
//设置玩家坐标
rmain.SetPos(BM_USER,3*32,8*32);
rmain.InitRole(0,GAMEW*32*MAX_PAGE-32);
//加载当前地图
LoadMap();
至此,在没有隐藏地图的情况下,游戏数据管理(只有初始化)介绍完了。
增加了隐藏地图的功能,游戏数据管理包括:初始化,数据刷新。哪些数据刷新需要刷新
1. 刷新玩家坐标。
例如,从第一关(地图编号为0)进入隐藏地图,玩家出现在(3,8),即横向第3格,纵向第8格。玩家返回第一关后,要出现在“出水管”的位置(66,7)。
2. 刷新视图坐标。
例如,从第一关进入隐藏地图,玩家出现在(3,8),视图对应地图最左边,玩家返回第一关后,视图要移动到“出水管”的位置。
3. 刷新背景图片的坐标。
例如,从第一关进入隐藏地图,玩家出现在(3,8),天空背景对应地图最左边,玩家返回第一关后,背景图片要移动到“出水管”的位置。
隐藏地图加载函数:void GAMEMAP::ChangeMap()
代码:
//初始化视图坐标
viewx=0;
//获取隐藏地图编号
iMatch=mapinfo.iSubMap;
//初始化场景数据
InitMatch();
//设置玩家坐标
rmain.SetPos(BM_USER,mapinfo.xReturnPoint*32,mapinfo.yReturnPoint*32);
//玩家角色初始化
rmain.InitRole(0,GAMEW*32*MAX_PAGE-32);
//设定视图位置
if(rmain.xpos - viewx > 150)
{
SetView(mapinfo.xReturnPoint*32-32);//往左让一格
if(viewx>(mapinfo.viewmax-1)*GAMEW*32)
viewx=(mapinfo.viewmax-1)*GAMEW*32;
}
//设定人物活动范围
rmain.SetLimit(viewx, GAMEW*32*MAX_PAGE);
//设定背景图片坐标
bmSky.SetPos(BM_USER,viewx,0);
//加载地图
LoadMap();
}
所以,地图信息表中,要包含“出水管”的坐标。完整的地图信息表如下:
struct MAPINFO
{
int iNextMap; //过关后的下一关编号
int iSubMap; //进入水管后的地图编号
int xReturnPoint; //出水管的横坐标
int yReturnPoint; //出水管的纵坐标
int iBackBmp; //背景图片ID
int viewmax; //视图最大宽度
};
struct MAPINFO allmapinfo[]={
{1,3,66,7,0,5},
{2,4,25,4,1,5},
{MAX_MATCH,-1,-1,-1,2,5},
{-1,0,3,8,3,1},
{-1,1,3,8,3,2}
};
说明:
第0关:
{1,3,66,7,0,5},表示第0关的下一关是第1关,从水管进入第3关,出水管位于(66,7),天空背景id为0,视图最大宽度为5倍窗口宽度。
第3关:
{-1,0,3,8,3,1},表示第3关没有下一关,从水管进入第0关,出水管位于(3,8),天空背景id为3,视图最大宽度为1倍窗口宽度。
这样,隐藏地图切换的同时,视图数据,玩家数据均正确。
各个动态元素,地图的各种处理都已完成,只需要让玩家控制的小人,走路,跳跃,攻击,进出水管。玩家的动作控制怎样实现?且听下回分解。
附:
超级玛丽第一版源码链接:http://download.csdn.net/source/497676
超级玛丽增强版源码链接:http://download.csdn.net/source/584350