超级玛丽制作揭秘14爆炸效果,金币

 大家的支持就是我的动力。

子弹每次攻击到效果,都会显示一个爆炸效果。只涉及图片显示,它的结构很简单。如下:
struct MapObject
{
 int x;
 int y;
 int w;
 int h;
 int id;
 int iframe;
 int iframemax;//最大帧数
 int show; //是否显示
};
存储问题。
爆炸效果仍然使用数组加游标的方法,如下:
 struct MapObject BombArray[MAX_MAP_OBJECT];
 int iBombNum;

生成。
当子弹和小怪碰撞后,生成。
函数:void GAMEMAP::ClearEnemy(int i)
代码部分:
 //生成
BombArray[iBombNum].show=1;
 BombArray[iBombNum].id=ID_ANI_BOMB;
 BombArray[iBombNum].iframe=0;
 BombArray[iBombNum].x=MapEnemyArray[i].x-BOMB_XOFF;
 BombArray[iBombNum].y=MapEnemyArray[i].y-BOMB_YOFF;
 //修改数组游标
 iBombNum=(iBombNum+1)%MAX_MAP_OBJECT;

显示。
和子弹、小怪的显示方法相同。
函数:void GAMEMAP::ShowAniObj(MYANIOBJ & bmobj)
代码部分:
 for(i=0;i<MAX_MAP_OBJECT;i++)
 {
  if (BombArray[i].show)
  {
   ystart=BombArray[i].y;
   xstart=BombArray[i].x;
   bmobj.DrawItem(xstart,ystart,BombArray[i].id, BombArray[i].iframe); 
  }
 }

帧刷新。
和子弹、小怪的帧刷新方法相同。
函数:void GAMEMAP::ChangeFrame(int itimeclip)
代码部分:
for(i=0;i<MAX_MAP_OBJECT;i++)
 {
  if(BombArray[i].show)
  {
   BombArray[i].iframe++;
//当第四张图片显示完毕,设置为不可见。
   if(BombArray[i].iframe>3)
   {
    BombArray[i].show=0;
   }
  } 
 }

碰撞检测:爆炸效果不涉及碰撞检测。
消失:如上所述,爆炸效果在动画结束后消失。

金币。
金币的处理比小怪更简单。当玩家和金币碰撞后,金币消失,增加金钱数量。
存储问题。
用数组加游标的方法(下一个版本中封装起来),如下:
 struct MapObject MapCoinArray[MAX_MAP_OBJECT];
 int iCoinNum;

金币的生成。
和小怪相似,从地图文件中加载。以第二关为例,地图文件中的金币数据是:
6 5 32 32 3    
7 5 32 32 3    
8 5 32 32 3    
9 5 32 32 3    
18 4 32 32 3   
19 4 32 32 3   
20 4 32 32 3
数据依次表示横坐标,纵坐标,宽,高,图片id
函数:int GAMEMAP::LoadMap()
代码部分:
 while(temp[0]!='#' && !feof(fp))
 {
  sscanf(temp,"%d %d %d %d %d",
   &MapCoinArray[i].x,
   &MapCoinArray[i].y,
   &MapCoinArray[i].w,
   &MapCoinArray[i].h,
   &MapCoinArray[i].id);   
  MapCoinArray[i].show=1;
  MapCoinArray[i].iframe=0;
  //坐标转换,乘以32
  MapCoinArray[i].x*=32;
  MapCoinArray[i].y*=32;
  //设置这个动画元件的最大帧
  switch(MapCoinArray[i].id)
  {
  case ID_ANI_COIN:
   MapCoinArray[i].iframemax=4;
   break;
  }
  i++;
  iCoinNum++;
  //读取下一行数据
  FGetLineJumpCom(temp,fp); 
 }

金币显示:
和小怪的显示方法相同.
函数:void GAMEMAP::ShowAniObj(MYANIOBJ & bmobj)
代码:
 //显示金币,和其他物品
 for(i=0;i<iCoinNum;i++)
 {
  ystart=MapCoinArray[i].y;
  xstart=MapCoinArray[i].x;
  bmobj.DrawItem(xstart,ystart,MapCoinArray[i].id, MapCoinArray[i].iframe); 
 }

金币帧刷新:
和小怪的帧刷新方法相同.
函数:void GAMEMAP::ChangeFrame(int itimeclip)
代码:
 for(i=0;i<MAX_MAP_OBJECT;i++)
  {
   //如果金币可见,帧加一
   if(MapCoinArray[i].show)
   {       MapCoinArray[i].iframe=(MapCoinArray[i].iframe+1)%MapCoinArray[i].iframemax;
   }
  }

金币碰撞检测:
和小怪的碰撞检测方法相似,区别在于:金币的碰撞检测没有判断是否可见,只要金币位于屏幕中,和玩家碰撞,则金币消失,金钱数量iMoney增加。
函数:int GAMEMAP::CheckAni(int itimeclip)
代码:
 for(i=0;i<iCoinNum;i++)
 {
  tempx=MapCoinArray[i].x;
  tempy=MapCoinArray[i].y;
  
  if ( IN_AREA(tempx, viewx-32, VIEWW) )
  {
   //玩家坐标是rmain.xpos rmain.ypos
   if( RECT_HIT_RECT(rmain.xpos,
    rmain.ypos,
    32,32,
    tempx,
    tempy,
    MapCoinArray[i].w,MapCoinArray[i].h)
    )
   {
    switch(MapCoinArray[i].id)
    {
    case ID_ANI_COIN:
     //增加金钱数量
     iMoney+=10; 
     //金币消失
     ClearCoin(i);
     break;
    }    
    return 0;
   }  
  }
 } // end of for

金币消失:
和小怪的消失不一样.不需要设置show为0, 而是直接删除元素.即数组移动的方法.
函数:void GAMEMAP::ClearCoin(int i)
代码:
 //检查合法性
 if(i<0 || i>=iCoinNum)
  return;
 //减少一个金币,或者减少一个其他物品
 for(;i<iCoinNum;i++)
 {
  MapCoinArray[i]=MapCoinArray[i+1];
 }
 //修改数量
 iCoinNum--;
由此可见,直接删除元素,省去了是否可见的判断。但凡事都有两面性,移动数组显然比单个元素的设置要慢(实际上不一定,可以优化)。方法多种多样,这就是程序的好处,永远有更好的答案。
所有的动态元素都介绍完了。所谓动态元素,就是有一个生成、运行、销毁的过程。只不过,有的复杂一些,如子弹、旋风、蘑菇兵、火圈,有些元素简单一些,如爆炸效果、金币。方法都大同小异,要强调的是,这不是最好的方法。碰到金币后,会出现‘+10’的字样,怎么做呢?这个问题会再次说明,方法多种多样。且听下回分解。
附:
超级玛丽第一版源码链接:http://download.csdn.net/source/497676
超级玛丽增强版源码链接:http://download.csdn.net/source/584350

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值