当前位置:文档之家› 俄罗斯方块

俄罗斯方块

俄罗斯方块俄罗斯方块小游戏姓名:罗君学号:102054221指导老师:孔老师日期:2011/12/221设计描述这个程序是由MFC所做的小游戏:俄罗斯方块,俄罗斯方块也就是人们广泛称为积木的游戏,它是利用一些形状各异小方块却是用正方形组成的方块,当然在我所做的这个程序里,我用了有着7种不同的方块。

,经过不同位置不同角度的变化之后,堆积在一起的一种智力游戏。

而当同一行被小方格填满时,那一行也就跟着消失,此时玩家就可以得到一分,这里所设置的分值为,没消去一行,便可以得到一分,而主界面的背景被设为了12行及18列,当所堆积的小方块的垂直高度等于界面背景的高度时,这时就会在视图类中弹出一个消息对话框“游戏已经结束”。

这里所要实现的就是这样一个小游戏,不过出于达到为了更加使游戏玩家得到娱乐的放松,我已经为此游戏添加了动听的游戏的背景音乐。

还有就是当程序运行时,首先出现在客户区的是一幅封面位图,当游戏玩家点击文件菜单中的开始子菜单时,游戏正式进入游戏界面。

而从我们编程的角度讲,我们只需要提供各种方块的图形,提供几个键盘操作键以供方块的形状和位置的变化,提供几个功能函数以供游戏的正常进行。

各种方块图形:利用数组定形,然后利用随机函数随机地不按顺序地按游戏的需要而出现。

键盘操作键:就是四个方向键。

其中左、右、下三个键意思一样,上键的功能不是使方块向上,而是使方块的下落角度改变。

2设计分析2.1由于所选封面的位图的大小的限制,贴的客户区的位图不能完全覆盖整个客户区,考虑到游戏运行的效果,所以必须对运行后客户区大小重新作出界定,处于这种原因,所以应该在CMainFrame类中的PreCreateWindow (CREATESTRUCT& cs)函数中添加代码:cs.cx=500,cs.cy=590;再者就是一个有戏必须有开始,暂停和结束的按钮,为了实现这一功能,我做了如下程序,将菜单栏中的文件菜单项下的子菜单项都删除,重新为该菜单项添加3个子菜单项,分别为开始(IDC_MENU_START),暂停(IDC_MENU_PAUSE),退出(IDC_MENU_EXIT).并分别给这三个菜单项添加Command命令响应,并让CView类接收此命令响应消息。

2.2 资源编辑添加位图:封面:IDB_BITMAP1背景:IDB_BITMAP2方块:IDB_BITMAP4添加菜单:开始:ID_MENU_START2.2变量函数接着就是定义变量了,但是,由于这个游戏要添加的变量和函数太多了,我们要建一个新类。

由于新类将会涉及到变量。

添加普通类CRussia,见下图。

图2-1-12.3添加变量函数:由于两个类一共有很多变量函数,列举如下:// 4_1View.h :CRussia russia; //俄罗斯类bool start; //开始标志CBitmap fengmian; //用于封面BOOL m_bPause; //暂停afx_msg void OnMenuStart(); //开始菜单afx_msg void OnTimer(UINT nIDEvent); //计时器afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); //键盘操作// Russia.h:int Russia[100][100]; //游戏数组int Now[4][4]; // 当前图形int Will[4][4]; //上一图形int After[4][4]; //变换后的图形CPoint NowPosition; //当前图形的左上角位置int Count; //当前可能出现的图形形状数,bool end; //游戏结束int m_Level; //级别int m_Speed; //速度int m_Score; //分数i nt m_RowCount,m_ColCount; //行列数CBitmap fangkuai; //方块CBitmap jiemian; //背景void DrawScore(CDC*pDC); //显示分数等内容v oid LineDelete();//消行void Move(int direction); //方块移动bool Change(int a[][4],CPoint p,int b[][100]); //方块变化,即方向键上键操作bool Meet(int a[][4],int direction,CPoint p); //是否与原来方块接触,或与边界接触v oid DrawWill(); //显示下一个方块void DrawJiemian(CDC*pDC); //显示界面void Start(); //开始3 源代码构造函数:CMy4_1View::CMy4_1View(){// TODO: add construction code herefengmian.LoadBitmap(IDB_BITMAP1);start=false;m_bPause=false;}CRussia::CRussia(){jiemian.LoadBitmap(IDB_BITMAP2);fangkuai.LoadBitmap(IDB_BITMAP4);}画图函数:void CMy4_1View::OnDraw(CDC* pDC){CMy4_1Doc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data hereCDC Dc;if(Dc.CreateCompatibleDC(pDC)==FAL SE)AfxMessageBox("Can't create DC");//没有开始,显示封面if( !start){Dc.SelectObject(fenmian);p DC->BitBlt(0,0,500,550,&Dc,0,0,SRCCOPY) ;}//显示背景elserussia.DrawJiemian(pDC);}界面函数:还是那个道理,当有一些客户区生效(被挡住或最小化)时,它必须重画,而如果游戏只是玩了一半,它必然在重画时必须把原先已经出现的方块、分数等也显示出来,怎么办?就必须在画封面的同时也画出它们。

当然,刚开始时它们是不会符合条件的。

voidCRussia::DrawJiemian(CDC*pDC){CDC Dc;if(Dc.CreateCompatibleDC(pDC)==FAL SE)AfxMessageBox("Can't create DC");//画背景Dc.SelectObject(jiemian);pDC->BitBlt(0,0,500,550,&Dc,0,0,SRCC OPY);//画分数,速度,难度DrawScore(pDC);//如果有方块,显示方块//游戏区for(int i=0;i<m_RowCount;i++)for(int j=0;j<m_ColCount;j++)if(Russia[i][j]==1){Dc.SelectObject(fangkuai);p DC->BitBlt(j*30,i*30,30,30,&Dc,0,0,SRCCO PY);}//预先图形方块for(int n=0;n<4;n++)for(int m=0;m<4;m++)if(Will[n][m]==1){Dc.SelectObject(fangkuai);p DC->BitBlt(365+m*30,240+n*30,30,30,&Dc, 0,0,SRCCOPY);}}信息函数:其中还涉及另外一个函数DrawScore(pDC),它是画分数、速度、难度(本程序省略)的。

由于它的代码不是太少,另外用了一个函数,这样有利于理解。

void CRussia::DrawScore(CDC*pDC){int nOldDC=pDC->SaveDC();//设置字体CFont font;if(0==font.CreatePointFont(300,"Comic Sans MS")){AfxMessageBox("Can't Create Font");}pDC->SelectObject(&font);//设置字体颜色及其背景颜色CString str;pDC->SetTextColor(RGB(39,244,10));pDC->SetBkColor(RGB(255,255,0));//输出数字str.Format("%d",m_Level);if(m_Level>=0)pDC->TextOut(440,120,str);str.Format("%d",m_Speed);if(m_Speed>=0)pDC->TextOut(440,64,str);str.Format("%d",m_Score);if(m_Score>=0)pDC->TextOut(440,2,str);pDC->RestoreDC(nOldDC);}至此,可以看的都画完了。

程序一般都是会先处理图形界面,因为这样在编核心内容时能够让人有一个检查的机会。

菜单开始函数:现在,游戏总该开始了吧。

添加菜单开始函数:ID_MENU_START其函数如下:void CMy4_1View::OnMenuStart(){// TODO: Add your command handler code herestart=true;russia.Start();SetTimer(1,50*(11-russia.m_Speed ),NU LL);}先把start赋值为true,再调用russia.Start()函数,让它对俄罗斯方块游戏的相应变量赋值,为了使游戏能够调整速度,设置一个可变的计数器。

那么,russia.Start()函数做了什么呢?开始函数:void CRussia::Start(){end=false;//运行结束标志m_Score=0; //初始分数m_Speed=0; //初始速度m_Level=1; //初始难度m_RowCount=18; //行数m_ColCount=12; //列数Count=7; //方块种类//清空背景数组for(int i=0;i<m_RowCount;i++)for(int j=0;j<m_ColCount;j++){Russia[i][j]=0;}//清空方块数组Now[ ][ ] Will[ ][ ]for(i=0;i<4;i++)for(int j=0;j<4;j++){Now[i][j]=0;Will[i][j]=0;}//先画Will[][]DrawWill();//再画Now[][]&Will[][]DrawWill();}预备方块:DrawWill()的作用是,把预备方块给当前方块,再生成一个预备方块。

相关主题