类说明:这是一个专门处理游戏背景的类。在横版游戏或射击游戏中,都有一个背景画面,如山、天空、云、星空等等。这些图片一般只有1到2倍屏幕宽度,然后像一个卷轴一样循环移动,连成一片,感觉上像一张很长的图片。这个类就是专门处理这个背景的。在超级玛丽增强版中,主要关卡是3关,各有一张背景图片;从水管进去,有两关,都用一张全黑图片。共四张图。这四张图大小一致,纵向排列在一个位图文件中。MYBKSKY这个类,派生于MYBITMAP。由于背景图片只需要完成循环移动的效果,只需要实现一个功能,而无需关心其他任何问题(例如句柄、dc)。编码起来很简单,再次反映出面向对象的好处。
技术原理:
怎样让一张图片像卷轴一样不停移动呢?很简单,假设有一条垂直分割线,把图片分成左右两部分。先显示右边部分,再把左边部分接到图片末尾。不停移动向右移动分割线,图片就会循环地显示。
成员函数功能列表:
class MYBKSKY:public MYBITMAP
{
public:
MYBKSKY();
~MYBKSKY();
//show
//功能 显示一个背景.
//入参 无
void DrawRoll(); //循环补空
//功能 显示一个背景,并缩放图片
//入参 横纵方向缩放比例
void DrawRollStretch(int x,int y);
//功能 指定显示某一个背景,并缩放图片,游戏中用的就是这个函数
//入参 横纵方向缩放比例 背景图片ID(纵向第几个)
void DrawRollStretch(int x,int y,int id);
//功能 设置图片位置
//入参 新的横纵坐标
void MoveTo(int x,int y);
//功能 循环移动分割线
//入参 分割线移动的距离
void MoveRoll(int x);
//data
//分割线横坐标
int xseparate;
};
函数具体实现都很简单,例如:
void MYBKSKY::DrawRollStretch(int x,int y, int id)
{
//选入句柄
SelectObject(hdcsrc,hBm);
//将分割线右边部分显示在当前位置
StretchBlt(hdcdest,
xpos,ypos, //当前位置
(width-xseparate)*x,height*y, //缩放比例
hdcsrc,
xseparate,id*height, //右边部分的坐标
width-xseparate,height, //右边部分的宽高
SRCCOPY);
//将分割线左边部分接在图片末尾
StretchBlt(hdcdest,xpos+(width-xseparate)*x,ypos,
xseparate*x,height*y,
hdcsrc,0,id*height,
xseparate,height,
SRCCOPY);
}
使用举例:
定义 MYBKSKY bmSky;
初始化
mario01/mario01.cpp(234): bmSky.Init(hInstance,IDB_BITMAP_MAP_SKY,1,4);
mario01/mario01.cpp(235): bmSky.SetDevice(hscreen,hmem,GAMEW*32*MAX_PAGE,GAMEH*32);
mario01/mario01.cpp(236): bmSky.SetPos(BM_USER,0,0);
游戏过程中显示
mario01/mario01.cpp(366): bmSky.DrawRollStretch(2,2,gamemap.mapinfo.iBackBmp);
每隔一定时间,移动分割线
mario01/mario01.cpp(428): bmSky.MoveRoll(SKY_SPEED);//云彩移动
以下两处与玩家角色有关:
当玩家切换到一张新地图时,刷新背景图片的坐标
mario01/gamemap.cpp(314): bmSky.SetPos(BM_USER,viewx,0);
当玩家向右移动时,刷新背景图片的坐标
mario01/gamemap.cpp(473): bmSky.SetPos(BM_USER,viewx,0);
至此,游戏背景图片的功能就做完了。
附:
超级玛丽第一版源码链接:http://download.csdn.net/source/497676
超级玛丽增强版源码链接:http://download.csdn.net/source/584350