打飞机游戏
1.2 飞机控制
备份1_1工作区文件夹,并将文件夹名字改为1_2,后面操作在1_2文件夹工作区进行。 ?将源盘程序例子中的背景位图文件bitmap2.bmp复制到当前工作区res文件夹中。
单击“Insert”菜单“Resource”命令,选择“Bitmap”位图资源图标,单击“Import”按钮,将背景位图文件bitmap2.bmp加入到项目
,资源ID值为IDB_BITMAP2。 ?利用“Insert”菜单“New Class”命令,对话框如下:
在Class type列
框选择Generic Class,然后在Name编辑框输入类名字CGame,单击OK按钮,定义CGame 游戏类。
?在定义CGame 游戏类头文件Game.h中,
class CGame
{
public:
CGame();
virtual ~CGame();
//设置透明位图
void TransparentBitmap(HDC hdc, HBITMAP hBitmap,
short xStart, short yStart, short xadd,short yadd,
COLORREF cTransparentColor);
//透明色
COLORREF cTransparentColor;
//我方飞机
CBitmap plane;
//背景数组
int back[15][12];
//飞机出现位置
int xStart,yStart;
};
?在定义CGame 游戏类实现文件Game.cpp中,在构造函数中输入初始化代码 CGame::CGame()
{
int i,j;
plane.LoadBitmap(IDB_BITMAP2);
//设置透明色
cTransparentColor=RGB(192,192,192);
//飞机开始出现位置
xStart=5;
yStart=10;
//数组为0
for(i=0;i<15;i++)
for(j=0;j<12;j++)
back[i][j]=0;
}
?在定义CGame 游戏类实现文件Game.cpp中,输入下面函数代码
void CGame::TransparentBitmap(HDC hdc, HBITMAP hBitmap,
short xStart, short yStart, short xadd,short yadd,
COLORREF cTransparentColor) {
BITMAP m_bm;
COLORREF cColor;
// 创建临时DC
HDC hMem, hBack, hObject, hTemp, hSave;
hBack = CreateCompatibleDC(hdc);
hObject = CreateCompatibleDC(hdc);
hMem = CreateCompatibleDC(hdc);
hSave = CreateCompatibleDC(hdc);
hTemp = CreateCompatibleDC(hdc);
// 选入位图
SelectObject(hTemp, hBitmap);
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&m_bm);
//显示位图宽高
POINT ptSize;
// 取得位图的宽度
ptSize.x = m_bm.bmWidth;
// 取得位图的该度
ptSize.y = m_bm.bmHeight;
// 转换为逻辑点值
DPtoLP(hTemp, &ptSize, 1);
// 创建临时位图
HBITMAP bmBack, bmObject, bmMem, bmSave;
// 单色位图
bmBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
bmObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
// 与设备兼容位图
bmMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
// 将创建的临时位图选入临时DC中
HBITMAP OldbmBack, OldbmObject, OldbmMem, OldbmSave;
OldbmBack = (HBITMAP)SelectObject(hBack, bmBack);
OldbmObject = (HBITMAP)SelectObject(hObject, bmObject);
OldbmMem = (HBITMAP)SelectObject(hMem, bmMem);
OldbmSave = (HBITMAP)SelectObject(hSave, bmSave);
// 设置映射模式
SetMapMode(hTemp, GetMapMode(hdc));
// 先保留原始位图
BitBlt(hSave, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCCOPY);
// 将背景颜色设置为需透明的颜色
cColor = SetBkColor(hTemp, cTransparentColor);
// 创建目标屏蔽码
BitBlt(hObject, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCCOPY);
// 恢复源DC的原始背景色
SetBkColor(hTemp, cColor);
// 创建反转的目标屏蔽码
BitBlt(hBack, 0, 0, ptSize.x, ptSize.y, hObject, 0, 0, NOTSRCCOPY);
// 拷贝主DC的背景到目标DC
BitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY);
// 屏蔽位图的显示区
BitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hObject, 0, 0, SRCAND);
// 屏蔽位图中的透明色
BitBlt(hTemp, 0, 0, ptSize.x, ptSize.y, hBack, 0, 0, SRCAND);
// 将位图与目标DC的背景左异或操作
BitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCPAINT);
// 拷贝目标到屏幕上
StretchBlt(hdc, xStart, yStart, ptSize.x+xadd, ptSize.y+yadd, hMem, 0, 0, ptSize.x,
ptSize.y,SRCCOPY);
// 恢复原始位图
BitBlt(hTemp, 0, 0, ptSize.x, ptSize.y, hSave, 0, 0, SRCCOPY);
// 删除临时内存位图
DeleteObject(SelectObject(hBack, OldbmBack));
DeleteObject(SelectObject(hObject, OldbmObject));
DeleteObject(SelectObject(hMem, OldbmMem));
DeleteObject(SelectObject(hSave, OldbmSave));
// 删除临时内存DC
DeleteDC(hMem);
DeleteDC(hBack);
DeleteDC(hObject);
DeleteDC(hSave);
DeleteDC(hTemp);
}
?使用类向导在视类CMy1_1View处理键盘按下WM_KEYDOWN消息
void CMy1_1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
switch(nChar)
{
case VK_F3:
//暂停是否
bPause=!bPause;
//是,设置计时器
if(bPause)
SetTimer(1,200,NULL);
//否,停止计时
else
KillTimer(1);
break;
//左移
case VK_LEFT:
//位置减1
game.xStart--;
//边界
if(game.xStart<0)
game.xStart=0;
break;
//道理同上
case VK_RIGHT:
game.xStart++;
if(game.xStart>14)
game.xStart=14;
break;
//上跳
case VK_UP:
if(game.yStart>0)
game.yStart--;
break;
//下跳
case VK_DOWN:
if(game.yStart<10)
game.yStart++;
break;
}
OnDraw(GetDC());
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
?在CMy1_1View视类添加游戏类对象和暂停控制变量 class CMy1_1View : public CView
{
protected: // create from serialization only
CMy1_1View();
DECLARE_DYNCREATE(CMy1_1View)
// Attributes
public:
CMy1_1Doc* GetDocument();
//屏幕宽度
int width;
//屏幕高度
int height;
//背景位图移动大小:10
int goup;
//背景位图
CBitmap backmap;
//类CGame
CGame game;
//暂停
bool bPause;
„„„„„„„„„„„„„„~
}
并在该文件添加文件包含命令:#include "Game.h"
?在视类构造函数中初始化暂停控制变量
CMy1_1View::CMy1_1View()
{
// TODO: add construction code here
backmap.LoadBitmap(IDB_BITMAP1); //装入背景位图资源
//开始背景位图的位置
goup=1000;
//是否暂停
bPause=true;
}
?在视类OnDraw画窗口函数添加显示飞机的命令
void CMy1_1View::OnDraw(CDC* pDC) {
CMy1_1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CRect WindowRect;
GetWindowRect(&WindowRect);
//屏幕宽度
width=WindowRect.right-WindowRect.left;
//屏幕高度
height=WindowRect.bottom-WindowRect.top;
CDC Dc;
if(Dc.CreateCompatibleDC(pDC)==FALSE)
AfxMessageBox("Can't create DC");
//在不同位置显示位图
Dc.SelectObject(backmap);
//显示两张位图使它们连接
pDC->BitBlt((width-800)/2,0,800,height,&Dc,0,goup-2000,SRCCOPY);
pDC->BitBlt((width-800)/2,0,800,height,&Dc,0,goup,SRCCOPY);
CClientDC dc(this);
//显示我方飞机
game.TransparentBitmap(dc.GetSafeHdc(), game.plane,(width-800)/2+game.xStart*50+20,
game.yStart*height/600*50, 0,0, game.cTransparentColor);
}
?编译运行,按Esc键退出。
完成本步骤结果参考1_2文件夹。
?