1、C+课程设计打砖块游戏MFC课程设计说明书设计题目: 打砖块游戏 所属系部: 计算机工程系 专 业: 计算机科学与技术 学 号: XXXX XXX 姓 名: XXXX 指导教师: XXXX 设计日期: 12-26 一、 设计任务1.1 任务描述使用MFC框架设计一个打砖块游戏。在客户区内显示砖块分布,小球和托盘。按空格键开始游戏,Esc键结束游戏。开始游戏小球可以跳起来打砖块,移动鼠标实现托盘的移动,打到的砖块消失。如果托盘没有接到小球,那么生命值减一,共有三次生命,生命都用完时,可以继续或结束。1.2 设计要求1. 自定义屏幕二维坐标系:x轴水平向右为正,y轴垂直向上为正,坐标系原点位于客户
2、区中心。2. 新加上两个类Brick类和Baffle类,分别用来定义并绘制砖块和托盘。3. 使用定时器函数控制小球的运动。4. 使用双缓冲技术实现动画。5. 在TestView类中实现砖块的分布6. 添加函数实现小球各种的碰撞速度大小和方向的改变。7. 添加函数实现鼠标移动控制托盘。1.3 效果图设计效果图如图1所示。图1 小球打砖块效果图二、 设计思路本设计首先构建双缓冲框架,小球和砖块、客户区边界发生碰撞后,改变运动方向。设置游戏关卡并绘制砖块分布。鼠标移动控制托盘。托盘没有接住小球,生命值则减一。游戏结束时显示对话框以便继续或退出游戏。三、 关键源代码及注释3.1 关于窗口外观设计的代码
3、:int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct) if (CFrameWnd:OnCreate(lpCreateStruct) = -1) return -1; SetMenu(NULL);/去掉菜单栏 CMenu* p=GetSystemMenu(FALSE); p-RemoveMenu(SC_SIZE,MF_BYCOMMAND);/禁止改变窗口大小 return 0;BOOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs) if( !CFrameWnd:PreCreateWindow(c
4、s) ) return FALSE; the CREATESTRUCT cs cs.style &=(WS_MAXIMIZEBOX); /过滤最大化 cs.x = 100; cs.y = 100; cs.cx = 809; cs.cy = 610; return TRUE;3.2 Baffle类中的各种定义CBaffle:CBaffle(double x,double y,double w,double h,double s) m_XPos=x,m_YPos=y; m_Width=w,m_Height=h,m_HalfW=w/2.0,m_HalfH=h/2.0; m_Speed=s,m_Pre
5、XPos=x;void CBaffle:SetPositionX(double x)/设置x方向位置 m_PreXPos=m_XPos; m_XPos=x;void CBaffle:SetPositionY(double y)/设置y方向位置 m_YPos=y;void CBaffle:SetWidth(double w)/设置宽度 m_Width=w; m_HalfW=w/2.0;void CBaffle:SetHeight(double h)/设置高度 m_Height=h; m_HalfH=h/2.0;void CBaffle:CalculateSpeed()/速度计算 m_Speed=
6、(m_XPos-m_PreXPos);void CBaffle:DrawBaffle(CDC* pDC)/绘制托盘 CDC MemDC; MemDC.CreateCompatibleDC(pDC); CBitmap NewBitmap,*pOldBitmap; NewBitmap.LoadBitmap(IDB_BAFFLE); pOldBitmap=MemDC.SelectObject(&NewBitmap); pDC-BitBlt(int(m_XPos-m_HalfW),int(m_YPos-m_HalfH+2),int(m_Width),int(m_Height),&MemDC,0,0,S
7、RCCOPY); MemDC.DeleteDC();void CBaffle:SetSpeed(double s) m_Speed=s;/设置速度3.3 Brick类中的各种定义CBrick:CBrick(double x,double y,double w,double h) m_XPos=x,m_YPos=y; m_Width=w,m_Height=h; m_HalfW=w/2.0,m_HalfH=h/2.0; m_Enable=TRUE; m_Score=0; m_Color=RGB(255,255,255);void CBrick:SetEnable() m_Enable=TRUE;v
8、oid CBrick:SetDisable() m_Enable=FALSE;void CBrick:SetPosition(double x,double y)/设置坐标 m_XPos=x,m_YPos=y;void CBrick:SetWidth(double w) m_Width=w,m_HalfW=w/2;void CBrick:SetHeight(double h) m_Height=h,m_HalfH=h/2;void CBrick:SetColor(COLORREF clr) m_Color=clr;void CBrick:SetScore(int value) m_Score=
9、value;void CBrick:DrawBrick(CDC *pDC,double& c,double& d)/绘制砖块 CDC MemDC; MemDC.CreateCompatibleDC(pDC); CBitmap NewBitmap,*pOldBitmap; NewBitmap.LoadBitmap(IDB_BRICK); double dx=c-m_HalfW; double dy=d-m_HalfH; pOldBitmap=MemDC.SelectObject(&NewBitmap); pDC-BitBlt(int(dx),int(dy),int(m_Width),int(m_
10、Height),&MemDC,0,0,SRCCOPY); MemDC.DeleteDC();3.4 双缓冲函数void CTestView:DoubleBuffer()/双缓冲 CDC* pDC=GetDC(); GetClientRect(&rect);/获得客户区的大小 pDC-SetMapMode(MM_ANISOTROPIC);/pDC自定义坐标系 pDC-SetWindowExt(rect.Width(),rect.Height();/设置窗口范围 pDC-SetViewportExt(rect.Width(),-rect.Height();/x轴水平向右,y轴垂直向上 pDC-Se
11、tViewportOrg(rect.Width()/2,rect.Height()/2);/屏幕中心为原点 CDC MemDC;/内存DC CBitmap NewBitmap,*pOldBitmap;/内存中承载图像的临时位图 MemDC.CreateCompatibleDC(pDC);/建立与屏幕pDC兼容的MemDC NewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height();/创建兼容位图 pOldBitmap=MemDC.SelectObject(&NewBitmap);/将兼容位图选入MemDC MemDC.SetM
12、apMode(MM_ANISOTROPIC);/MemDC自定义坐标系 MemDC.SetWindowExt(rect.Width(),rect.Height(); MemDC.SetViewportExt(rect.Width(),-rect.Height(); MemDC.SetViewportOrg(rect.Width()/2,rect.Height()/2); DrawObject(&MemDC); BorderTest(); pDC-BitBlt(-rect.Width()/2,-rect.Height()/2,rect.Width(),rect.Height(),&MemDC,-
13、rect.Width()/2,-rect.Height()/2,SRCCOPY);/将内存位图拷贝到屏幕 MemDC.SelectObject(pOldBitmap);/恢复位图 NewBitmap.DeleteObject();/删除位图 MemDC.DeleteDC();/删除MemDC ReleaseDC(pDC);/释放DC3.5 插入背景位图函数CBitmap m_bmp; m_bmp.LoadBitmap(IDB_BITMAP2); BITMAP bm; m_bmp.GetBitmap(&bm); CDC dcMem; dcMem.CreateCompatibleDC(pDC);
14、CBitmap*pOldbmp=dcMem.SelectObject(&m_bmp); pDC-BitBlt(-Rect.Width()/2,-Rect.Height()/2,Rect.Width(),Rect.Height(),&dcMem,0,0,SRCCOPY); dcMem.SelectObject(pOldbmp);3.6 插入文字代码:CString str; str=打砖块游戏; int x,y; CSize size; pDC-SetTextColor(RGB(255,0,180); str.Format(%s,str); size=pDC-GetTextExtent(str,
15、str.GetLength(); x=(int)(double)(-25); y=(int)(double)(Rect.Height()/2-10); pDC-TextOut(x,y,str); str=游戏规则:按空格键或鼠标右键开始,按Esc键暂停。目标为:击落所有的砖块!; pDC-SetTextColor(RGB(200,0,150); str.Format(%s,str); size=pDC-GetTextExtent(str,str.GetLength(); x=(int)(double)(-Rect.Width()/2+120); y=(int)(double)(-Rect.He
16、ight()/2+150); pDC-TextOut(x,y,str);3.7 关于游戏设置关卡的代码: if(m_Init+DrawBaffle(pDC);/绘制托盘 void CTestView:InitBricks()/设置关卡 int m_BrickMatrixGameRowGameColumn=/砖块分布情况图 1,1,1,0,0,1,0,0,0,0,1,0,0,1,1,1, 1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,1,
17、0,0,0,0,0,0,0,0,0,0,1,0,0, 0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0, 0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0, 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0, 0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0, 0,0,0,0,0
18、,1,0,0,0,0,1,0,0,0,0,0, 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0, 0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0, 0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0, 0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ; /起始块砖块中心点所在位置 double StartX=-m_WindowHalfW+m_BrickHalfW; double StartY= m_Wi
19、ndowHalfH-m_BrickHalfH; for(int i=0;iGameRow;i+) for(int j=0;j=1)/设置状态 m_Bricksij.SetEnable(); m_BrikcsCnt+; else m_Bricksij.SetDisable(); void CTestView:ShowBricks(CDC *pDC)/显示砖块 for(int i=0;iGameRow;i+) for(int j=0;jTestBorder(m_WindowWidth,m_WindowHeight); flagBrick=3;/未碰撞 if(flagBroder=0 & flagB
20、roderSetSpeedX(-m_pMarble-m_SpeedX);/x方向速度取反 if(flagBroder=1)/y方向碰撞 m_pMarble-SetSpeedY(-m_pMarble-m_SpeedY);/y方向速度取反 if(flagBroder=2)/x,y方向同时碰撞 m_pMarble-SetSpeedX(-m_pMarble-m_SpeedX);/x方向速度取反 m_pMarble-SetSpeedY(-m_pMarble-m_SpeedY);/y方向速度取反 if(flagBroder=4)/出底线,生命值减1 PlaySound(LPCTSTR)IDR_alarm,
21、 AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC); m_MarbleOnOff=FALSE;/弹球停止运行 m_Life-;/生命值减1 m_pBaffle-SetPositionX(0.0); /重置托盘位置 m_pMarble-SetPosition(MarbleOriX,MarbleOriY);/重置弹球的位置 m_pBaffle-m_Speed=0; /重置托盘的速度 GameOVer();/游戏结束 /=测试并计算弹球与砖块碰撞之后的速度 for(int i=0;iGameRow;i+) for(int j=0;jTestBrick(m_
22、Bricksij); if(Currentflag!=3)/如果碰撞 m_Bricksij.SetDisable();/砖块无效 flagBrick=Currentflag; PlaySound(LPCTSTR)IDR_effect, AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC); m_BrikcsCnt-;/砖块数减1 GameOVer();/游戏结束 if(flagBrick=0)/与砖块在x方向碰撞 m_pMarble-SetSpeedX(-m_pMarble-m_SpeedX); if(flagBrick=1)/在y方向碰撞 m_pMar
23、ble-SetSpeedY(-m_pMarble-m_SpeedY); if(flagBrick=2)/在两个方向上均发生碰撞 m_pMarble-SetSpeedX(-m_pMarble-m_SpeedX); m_pMarble-SetSpeedY(-m_pMarble-m_SpeedY); /=测试并计算弹球与托盘碰撞之后的速度 flagBaffle=m_pMarble-TestBaffle(*m_pBaffle); if(flagBaffle=1) & m_MarbleOnOff)/与托盘发生碰撞 m_pMarble-SetSpeedY(-m_pMarble-m_SpeedY); m_p
24、Marble-SetSpeedX(-m_pMarble-m_SpeedX+m_pBaffle-m_Speed); PlaySound(LPCTSTR)IDR_boing, AfxGetInstanceHandle(), SND_RESOURCE|SND_ASYNC); void CTestView:ShowMarbles(CDC *pDC)/显示弹球 m_pMarble-DrawMarbles(pDC); if(m_Life0) if(m_MarbleOnOff) m_pMarble-MoveMarbles(); void CTestView:OnMouseMove(UINT nFlags,
25、CPoint point)/鼠标移动函数 / TODO: Add your message handler code here and/or call default SetCursor(NULL); if(m_GameOnOff)/如果游戏在运行 double x=point.x; double y=point.y; m_XPos=x-m_WindowHalfW,m_YPos=m_WindowHalfH-y;/设备坐标变换为屏幕坐标 /托盘只在x方向上移动,只考虑左右碰撞 if(fabs(m_XPos)m_WindowHalfW-m_pBaffle-m_HalfW)/x方向碰撞 if(m_XPos0)/与左侧边界碰撞 m_pBaffle-SetPositionX(m_WindowHalfW-m_pBaffle-m_HalfW); else /与右侧边界碰撞 m_pBaffle-SetPositionX(-m_WindowHalfW+m_pBaffle-m_HalfW); else m_pB
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1