您的位置:首页 > 其它

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

2008-11-17 18:17 495 查看
大家的支持就是我的动力。

子弹每次攻击到效果,都会显示一个爆炸效果。只涉及图片显示,它的结构很简单。如下:
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: