超级玛丽制作揭秘21游戏数据管理

 进入每一关之前,需要对所有游戏数据初始化。进入隐藏地图,同样需要初始化。而且,从隐藏地图返回上层地图,还要保证玩家角色出现在“出水管”处。地图数据、玩家数据、视图数据,都要设置正确。

所有的游戏数据,即封装在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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值