超级玛丽制作揭秘4图片显示 类MYANIOBJ

来源:互联网 发布:雅思6.5有多难 知乎 编辑:程序博客网 时间:2024/04/30 00:23

 类说明:这个类负责游戏中的图片显示。菜单背景、通关和游戏结束的提示图片,由MYBITMAP处理(大小一致的静态图片)。游戏背景由MYBKSKY处理。其余图片,也就是游戏过程中的所有图片,都是MYANIOBJ处理。

技术原理:游戏中的图片大小不一致,具体在超级玛丽中,可以分成两类:矩形图片和不规则图片。在位图文件中,都是纵向排列各个图片,横向排列各帧。用两个数组存储各个图片的宽和高。为了方便显示某一个图片,用一个数组存储各个图片的纵坐标(即位图文件中左上角的位置)。使用时,由逻辑层指定“哪个图片”的“哪一帧”,显示在“什么位置”。这样图片的显示功能就实现了。

成员函数功能列表:
class MYANIOBJ:public MYBITMAP
{
public:
 MYANIOBJ();
 ~MYANIOBJ();

 //init list
 //功能 初始化宽度数组 高度数组 纵坐标数组 是否有黑白图
 //入参 宽度数组地址 高度数组地址 图片数量 是否有黑白图(0 没有, 1 有)
 //(图片纵坐标信息由函数计算得出)
 void InitAniList(int *pw,int *ph,int inum,int ismask);

 //功能 初始化一些特殊的位图,例如各图片大小一致,或者有其他规律
 //入参 初始化方式 参数1 参数2
 //(留作以后扩展, 目的是为了省去宽高数组的麻烦)
 void InitAniList(int style,int a,int b);

 //show
 //功能 显示图片(不规则图片)
 //入参 横纵坐标(要显示的位置) 图片id(纵向第几个), 图片帧(横向第几个)
 void DrawItem(int x,int y,int id,int iframe);
 //功能 显示图片(矩形图片)
 //入参 横纵坐标(要显示的位置) 图片id(纵向第几个), 图片帧(横向第几个)
 void DrawItemNoMask(int x,int y,int id,int iframe);
 //功能 指定宽度, 显示图片的一部分(矩形图片)
 //入参 横纵坐标(要显示的位置) 图片id(纵向第几个), 显示宽度 图片帧(横向第几个)
 void DrawItemNoMaskWidth(int x,int y,int id,int w,int iframe);
 //功能 播放一个动画 即循环显示各帧
 //入参 横纵坐标(要显示的位置) 图片id(纵向第几个)
 void PlayItem(int x,int y,int id);

 //宽度数组 最多支持20个图片
 int wlist[20];
 //高度数组 最多支持20个图片
 int hlist[20];
 //纵坐标数组 最多支持20个图片
 int ylist[20];

 //动画播放时的当前帧
 int iframeplay;
};

函数实现上也很简单。构造函数中,所有成员数据清零;初始化时,将各图片的高度累加,即得到各图片的纵坐标。显示图片的方法如前所述。
使用举例:
游戏图片分成三类:地图物品、地图背景物体、精灵(即所有不规则图片)
MYANIOBJ bmMap;
MYANIOBJ bmMapBkObj;
MYANIOBJ bmAniObj;
初始化宽高信息
程序中定义一个二维数组,例如:
int mapani[2][10]={
{32,32,64,32,32,52,64,32,64,32},
{32,32,64,32,32,25,64,32,64,32},
};
第一维mapani[0]存储10个图片的宽度,第二维mapani[1]存储10个图片的高度,初始化时,将mapani[0],mapani[1]传给初始化函数即可。

1. 地图物品的显示:
定义
mario01/mario01.cpp(82):MYANIOBJ bmMap;
初始化
这一步加载位图
mario01/mario01.cpp(238): bmMap.Init(hInstance,IDB_BITMAP_MAP,1,1);
这一步初始化DC
mario01/mario01.cpp(239): bmMap.SetDevice(hscreen,hmem,GAMEW*32*MAX_PAGE,GAMEH*32);
这一步设置宽高信息, 图片为矩形
mario01/mario01.cpp(240): bmMap.InitAniList(mapsolid[0],mapsolid[1], sizeof(mapsolid[0])/sizeof(int),0);
对象作为参数传给逻辑层, 显示地图物品
mario01/mario01.cpp(368):    gamemap.Show(bmMap);
2. 血条的显示:
打怪时,屏幕上方要显示血条。由于同样是矩形图片,也一并放在了地图物品的位图中。
变量声明
mario01/gamemap.cpp(11):extern MYANIOBJ bmMap;
显示血条背景,指定图片宽度:最大生命值*单位生命值对应血条宽度
mario01/gamemap.cpp(522):  bmMap.DrawItemNoMaskWidth(xstart-1, ATTACK_TO_Y-1,ID_MAP_HEALTH_BK,
显示怪物血条,指定图片宽度:当前生命值*单位生命值对应血条宽度
mario01/gamemap.cpp(525):  bmMap.DrawItemNoMaskWidth(xstart, ATTACK_TO_Y,ID_MAP_HEALTH,

3. 地图背景物体的显示
背景物体包括草、河流、树木、目的地标志。这些物体都不参与任何逻辑处理,只需要显示到屏幕上。图片放在一个位图文件中,都是不规则形状。
定义
mario01.cpp(83):MYANIOBJ bmMapBkObj;
初始化并加载位图
mario01/mario01.cpp(242): bmMapBkObj.Init(hInstance,IDB_BITMAP_MAP_BK,1,1);
设置dc
mario01/mario01.cpp(243): bmMapBkObj.SetDevice(hscreen,hmem,GAMEW*32*MAX_PAGE,GAMEH*32);
设置各图片宽高信息
mario01/mario01.cpp(244): bmMapBkObj.InitAniList(mapanibk[0],mapanibk[1],sizeof(mapanibk[0])/sizeof(int),1);
对象作为参数传给逻辑层, 显示地图背景物体
mario01/mario01.cpp(367):    gamemap.ShowBkObj(bmMapBkObj);
4. 精灵的显示
精灵包括:蘑菇(玩家,敌人1,敌人2),子弹、旋风、爆炸效果、金币、撞击金币后的得分、攻击武器(那个从魂斗罗里抠来的东东)、火圈1、火圈2、箭头(用于开始菜单选择)。
定义
mario01.cpp(84):MYANIOBJ bmAniObj;
初始化加载位图
mario01/mario01.cpp(246): bmAniObj.Init(hInstance,IDB_BITMAP_ANI,1,1);
设置dc
mario01/mario01.cpp(247): bmAniObj.SetDevice(hscreen,hmem,GAMEW*32*MAX_PAGE,GAMEH*32);
设置宽高信息
mario01/mario01.cpp(248): bmAniObj.InitAniList(mapani[0],mapani[1],sizeof(mapani[0])/sizeof(int),1);
菜单显示(即菜单文字左边的箭头)
mario01/mario01.cpp(341):    gamemap.ShowMenu(bmAniObj);
对象作为参数传给逻辑层, 显示各个精灵
mario01/mario01.cpp(369):    gamemap.ShowAniObj(bmAniObj);

附:
超级玛丽第一版源码链接:http://download.csdn.net/source/497676
超级玛丽增强版源码链接:http://download.csdn.net/source/584350

原创粉丝点击