课程设计说明书课程名称:高级语言程序设计设计题目:俄罗斯方块游戏院部:计算机科学与信息工程学院学生姓名:学号:专业班级:物联网工程指导教师:2015年6月课程设计任务书目录一前言 (4)二需求分析 (4)三概要设计 (5)四详细设计 (7)五改进或增加功能模块说明 (8)六程序测试 (8)七课程设计总结 (11)八致谢 (11)九参考文献 (12)十源程序 (12)俄罗斯方块游戏一前言C++程序设计牵涉到面向对象程序设计的理论、C++语言的语法以及算法等3个方面的内容,其中每一方面都包含十分丰富的内容,都可以分别单独成论。
显然在一个程序中深入、详细地介绍以上3个方面的知识是不可能的,必须把它们有机地结合起来,综合应用。
不同的书对此采取不同的写法,侧重点有所不同,各有道理,也各有优缺点,适合于不同的读者。
需要在教学实践中检验,取长补短,不断完善。
作者认为:要进行C++程序设计当然需要了解面向对象程序设计的有关概念,但是本课程毕竟不是一门面向对象程序设计的理论课程,在本书中不是抽象地介绍面向对象程序设计的理论,而是在介绍C++语言的特点和应用过程中自然地引出面向对象程序设计的有关概念,通过C++的编程过程理解面向对象程序设计方法。
在介绍程序设计过程中,介绍有关的算法,引导读者思考怎样构造一个算法。
编写程序的过程就是设计算法的过程。
要用C++编程序,最基本的要求是正确掌握和运用C++。
由于C++语法复杂,内容又多,如果对它缺乏系统的了解,将难以真正应用,编出来的程序将会错误百出,编译出错,事倍功半。
本书的做法是全面而系统地介绍C++的主要特点和功能,引导读者由简而繁地学会编写C++程序。
有了C++编程的初步基础后,再进一步提高,掌握更多更深入的算法。
这样的方法可能符合大多数学习者的情况,降低了学习难度。
程序设计是一门实践性很强的课程,只靠听课和看书是学不好的。
衡量学习好坏的标准不是“懂不懂”,而是“会不会干”。
因此必须强调多编程,多上机实践。
考虑到不同学校、不同专业、不同读者对学习C++有不同的要求。
二需求分析1 要求(1)用C语言实现程序设计;(2)定义各个函数分别完成不同功能,如背景设计,判断等;(3)画出查询模块的流程图;(4)系统的各个功能用函数调用的形式实现;(5)界面友好(良好的人机互交),程序要有注释。
2 任务(1)定义各类头文件,变量及宏定义;(2)图形模块,设计出俄罗斯方块背景界面;(3)设定玩家操作模块和胜负判断模块;(4)画出部分模块的流程图;(5)编写代码;(6)程序分析与调试。
3 运行环境(1)WINDOWS7/8/2000/XP系统(2)TurboC2.0编译环境4 开发工具C++三概要设计3.1 模块组成图根据分析,俄罗斯方块这个程序一共要实现如下几个功能,开始游戏、游戏的暂停\继续、游戏控制和退出游戏。
其中游戏控制最为主要和重要,它控制着整个游戏的画面和有关数据的操作,是游戏的核心部分。
暂停和退出功能做成一体,在退出的提示下不做任何操作即可实现暂停的功能。
程序结构如图3-1所示。
图3-1 功能模块图2 查询函数流程图根据分析后的程序结构图设计出相应的流程图。
俄罗斯方块的内容主要包括游戏开始,画背景和边框,显示分数等级和下一个方块的预览图;根据速度没隔一定时间方块自动下落,当有按键操作时,根据相应按键执行动作,每次动作前要判断是否动作可以执行。
下落方块满一行时,消去该行,根据消去行数得到相应分数。
分数达到一定程度,等级提升,速度加快。
如图3-2所示。
图3-2 系统流程图四详细设计在程序的开头部分定义要用到的头文件,以及各种常量如设定棋盘大小,设定游戏模式及如何执行。
代码如下。
bool rotate(sCord *lpsCord,int rType,int rNumber,bool firstRotate);void getRandom();//初始化方格形状void getNext(sCord *targ,const sCord* sur);//取出下一个方块void draw();//绘出方格void start();//开始游戏bool downAble();//能否下落bool leftAble();//能否左移bool rightAble();//能否右移bool disRows(HWND hwnd);//判断能否消行五改进或增加功能模块说明5.1游戏界面游戏界面采用WndClass函数编写,代码如下。
WNDCLASS wndclass;wndclass.style=CS_HREDRAW|CS_VREDRAW;//|~(WS_MINIMIZEBOX|WS_MAXIMIZEBO X) ;wndclass.lpfnWndProc=WndProc;wndclass.cbClsExtra=0;wndclass.cbWndExtra=0;wndclass.hInstance=hInstance;wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);wndclass.hbrBackground= (HBRUSH)GetStockObject (WHITE_BRUSH);// CreateSolidBrush(RGB(195,195,237));wndclass.lpszMenuName= NULL;wndclass.lpszClassName= szAppName;俄罗斯方块的游戏界面包括游戏区域边框、下落方块绘制、右部计分和预览图显示等。
游戏区域边框的绘制比较简单,循环中确定光标的位置输出特定字符,即可完成边框绘制。
游戏区方块的绘制,循环从数据数组中依次读出数据,根据读到的数据显示“□”,最后组成方块的形状,完成方块的绘制。
计分和预览图部分先画出一个矩形区域,然后控制光标在其中显示分数、等级、预览图和提示信息。
5.2生成方块本程序中生成的方块有七种形状,在程序运行生成方块时,调k=rand()%KINDS+1;语句,确定当前要显示的是哪一个方块形状。
而在实际运行中,第一次需要调用两次生成方块函数getRandom(),将先产生的赋给游戏当前方块,第二个赋给预览图方块。
以后每次产生一个方块,把预览方块赋给当前方块,把新产生的赋给预览方块。
5.3方块变形俄罗斯方块的特点就在于通过方块的变形拼满整行来消去该行方块从而使游戏可以继续下去,很难想象不能变形的俄罗斯方块是什么样子。
而变形的过程就是根据当前方块形状改变方块的相对位置,这样就可以改变方块的形状了。
在程序中每当按下Up键,程序判断可以变形后,根据当前方块的形状序号和变化形状序号调用相应的方块数值赋给draw()函数,通过刷新重画就可以显示变化后的方块了。
5.4方块显示以上方块的操作都是数据层面的操作,而真正要在游戏窗口中看到数据的变化,还必须把方块不断的绘制出来。
这就是draw()函数的作用。
把当前运动的方块对应节点存储在一个4*4数组里,变形和生成方块的过程就是更新该数组数据的过程。
然后在draw()函数里检测数组的各个值,并控制光标跳到一定位置,画出“■”组成方块。
5.5障碍判断障碍判断,就是在方块运动中或者变形中判断周围是否有障碍阻碍下落、移位、变形。
当方块下落遇到下面有方块或者到达下边界则应停止下落并记录数据,存入背景数据数组。
变形时应判断这个变形是否可以进行,如果有障碍则不能变形。
例如当方块达到右边界,而若变形则会越过边界,那么这个变形的命令是不应执行的。
所有这些判断都由meet()函数进行,根据是否有障碍返回1或0,再由其他函数接收执行相应操作。
5.6消行计分游戏玩家拼满一行后,程序消去满行,并计分。
中当一个方块下落停止后,程序检查方块是否充满了游戏区域,如果是结束游戏。
不是,则判断是否构成消行条件,从下落方块的最低点依次向上检查是否可以消行,根据消去行数分数增加。
分数达到一定程度,等级提升,速度加快。
六程序测试1 测试游戏能否正确显示期盼界面游戏打开界面,如图3-3所示。
图3-3 打开界面2执行程序后,显示本游戏的界面,进行模式选择游戏中界面,如图3-4所示。
图3-4 游戏界面七课程设计总结通过这次课程设计,我收获了很多。
首先把所学知识加以利用和巩固,其次在实践中遇到问题去探索和学习,更增加了新知识实践证明达到了预期的目的,积累了经验。
由于程序是用文本窗口模拟的图形,界面比较简陋,如果使用MFC用C++来实现,那么界面将会非常好,只是由于所学知识有限,只有下一步去探索了。
通过这次的学习设计,我发现我还有许许多多的不足的地方,比如c++的程序设计,源代码的书写等等,刚开始我发现我的问题后,十分紧张,感觉很绝望,没有别人的帮助,自己动手设计曾经自己想都没想过的东西,虽然很兴奋,但想想自己无从下手,后来通过上网查找资料,进图书馆查找书籍等,终于知道了俄罗斯方块游戏的设计概念,终于知道了设计的方法,于是,渐渐地我的游戏设计理念诞生了。
通过这次设计,我学会了很多东西,例如通过网络资料来寻求帮助,自己改正错误,加强了我自己的自己动手能力,对今后的学习和生活有很大的帮助,有助于以后的课程设计顺利完成。
八致谢经过两个多星期的努力,终于把本游戏程序改写出来,在这期间要感谢各同学对我帮助和支持,同时也感谢程序老师对我的教导。
九参考文献(1)《C课程设计》黄明梁旭周绍斌编著,电子工业出版社出版(2)《C课程设计案例精编》黄晓东编著,中国水利水电出版社出版。
(3)《C程序设计实用教程》张永常主编,电子工业出版社出版。
十源程序/*头文件data.h:*/#ifndef DATA_H_#define DATA_H_#include<windows.h>static const int KINDS=7;//方块种类数量static const int COLS=10;//数据列数/** 7行10列数组每行对应一种方块类别。
* 每行的前四列为x坐标,中间四列为y坐标* 第九列为方块类别代码,最后一列为该类型方块有几种变形* 用一个5*5的矩阵表示7种类别方块共19种变形*///每种方块的代号static const int TYPE1=1;static const int TYPE2=2;static const int TYPE3=3;static const int TYPE4=4;static const int TYPE5=5;static const int TYPE6=6;static const int TYPE7=7;//变形的种类static const int RTYPE1=1;static const int RTYPE2=2;static const int RTYPE3=4;static int rTypeNext;static int rTypeDown;//初始化方块坐标及对应的类别和变形种类static const int index[KINDS][COLS]={ {0,1,0,1,0,0,-1,-1,TYPE1,RTYPE1},{-1,0,1,2,0,0,0,0,TYPE2,RTYPE2}, {0,0,1,1,1,0,0,-1,TYPE3,RTYPE2}, {0,0,1,1,-1,0,0,1,TYPE4,RTYPE2},{-1,0,0,1,0,0,1,0,TYPE5,RTYPE3},{-1,0,1,1,0,0,0,-1,TYPE6,RTYPE3},{-1,0,1,1,0,0,0,1,TYPE7,RTYPE3}};//定时器IDstatic const int TIMER=1;////初始游戏级别对应的时间间隔static int CURRENTLEVEL=600;static int level=1;//每种图形所包含的小方块数static const int CTN=4;typedef struct { //方块形状定义int x;int y;}sCord;sCord sDown[CTN],sNext[CTN];//下一个方块的坐标static RECT rectNext[CTN];//正在下落方块的坐标static RECT rectDown[CTN];//显示区域的大小static const int cxSize=25;static const int cySize=35;//方块偏离(0,0)得位置static int offsetx;static int offsety;static int offsetxNext;static int offsetyNext;//自定义消息static const int MS_DOWN=10001;//暂停static bool go=true;//开始static bool startGame=false;//结束static bool gameOver=false;//得分static int score;RECT rt={326,81,425,455};//每个方格包含的像素static const int pelsSize=13;//显示区域大小的定义static const POINT area[]={0,455,326,455,326,0};//显示区域的表示方法最后一列最后一行分别对应该行该列所具有的方块总数0表示没有方块1表示有static int fillArea[cySize+1][cxSize+1];HBRUSH hBrush1=CreateSolidBrush(RGB(0,0,255));//方块颜色:蓝色HBRUSH hBrush2=CreateSolidBrush(RGB(255,0,128)); //分数区域颜色:粉色HPEN hPen1=CreatePen(PS_SOLID,0,RGB(245,245,245));//背景格颜色:灰色#endif /* DATA_H_ */这是源文件MainPro.cpp#include"Data.h"#include<iostream>#include<cstdlib>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);/** 逆时针方向旋转方格返回能否旋转* @param lpsCord 要旋转的方块坐标指针* @param rType 旋转类型* @param rNumber 旋转次数* @param 是否第一次旋转*/bool rotate(sCord *lpsCord,int rType,int rNumber,bool firstRotate);void getRandom();//初始化方格形状void getNext(sCord *targ,const sCord* sur);//取出下一个方块void draw();//绘出方格void start();//开始游戏bool downAble();//能否下落bool leftAble();//能否左移bool rightAble();//能否右移bool disRows(HWND hwnd);//判断能否消行void getRandom() //初始化方格形状{int k=rand()%KINDS+1;for(int i=0;i<KINDS;i++){if(index[i][COLS-2]==k){rTypeNext=index[i][COLS-1];//获得旋转类型for(int j=0;j<CTN;j++){sNext[j].x=index[i][j];sNext[j].y=index[i][j+4];}break;}}rotate(sNext,rTypeNext,rand()%rTypeNext+1,true);int min_y=0;for (int t = 0; t < CTN; t++)min_y = min_y > sNext[t].y ? sNext[t].y : min_y;offsetxNext=(int)(cxSize/2)*pelsSize+(int)(pelsSize/2);//x方向的中间显示offsetyNext=(-min_y)*pelsSize+(int)(pelsSize/2);//保证置顶显示}bool rotate(sCord *lpsCord,int rType,int rNumber,bool firstRotate) // 旋转{int tempx;int tempy;int temp;int tx=(offsetx-(int)(pelsSize/2))/pelsSize;int ty=(offsety-(int)(pelsSize/2))/pelsSize;bool ra=true;switch(rType){case RTYPE1:ra=false;break;case RTYPE2:{if(rNumber%2!=0){for (int j = 0; j < CTN; j++){tempx=-lpsCord->y+tx;tempy=lpsCord->x+ty;lpsCord++;if(!firstRotate&&(fillArea[tempx][tempy]>0||tempx>24||tempx<0||tempy<0||tempy>34)) {ra=false;}}lpsCord-=4;if(ra){if (rNumber % 2 != 0)for (int k = 0; k < CTN; k++){temp = -lpsCord->x;lpsCord->x = lpsCord->y;lpsCord->y = temp;lpsCord++;}}}break;case RTYPE3:for(int k=0;k<rNumber;k++){for(int l=0;l<CTN;l++){tempx=lpsCord->y+tx;tempy=(-lpsCord->x)+ty;lpsCord++;if(!firstRotate&&(fillArea[tempx][tempy]>0||tempx>24||tempx<0||tempy<0||tempy>34)) {ra = false;}}lpsCord-=4;}if(ra)for (int i = 0; i < rNumber; i++){for (int j = 0; j < CTN; j++){temp = -lpsCord->x;lpsCord->x = lpsCord->y;lpsCord->y = temp;lpsCord++;}lpsCord=lpsCord-4;}break;}return ra;void getNext(sCord *targ,const sCord* sur) //取出下一个方块{rTypeDown=rTypeNext;offsetx=offsetxNext;offsety=offsetyNext;for(int i=0;i<CTN;i++){targ->x=sur->x;targ->y=sur->y;sur++;targ++;}getRandom();}void draw(HWND hwnd,const sCord* shape,RECT *rect,HBRUSH hBrush,int offsetx,int offsety) //绘出方格{HDC hdc=GetDC(hwnd);SelectObject(hdc,hBrush);SelectObject(hdc,hPen1);for(int i=0;i<CTN;i++){Rectangle(hdc,pelsSize*shape->x-(int)(pelsSize/2)+offsetx,pelsSize*shape->y-(int)(pelsSize/2) +offsety,pelsSize*shape->x+(int)(pelsSize/2)+offsetx+2,pelsSize*shape->y+(int)(pelsSize/2)+offsety+2);shape++;}ReleaseDC(hwnd,hdc);}void start() //开始游戏{if(!startGame){for (int i = 0; i < cySize + 1; i++)for (int j = 0; j < cxSize + 1; j++)fillArea[i][j] = 0;startGame=true;go=true;score=0;}}bool downAble() //能否下落{bool da=true;int x=(offsetx-(int)(pelsSize/2))/pelsSize;int y=(offsety-(int)(pelsSize/2))/pelsSize;int xtemp;int ytemp;for(int i=0;i<CTN;i++){xtemp=sDown[i].x+x;ytemp=sDown[i].y+y+1;if(fillArea[ytemp][xtemp]>0||ytemp>34) {da=false;break;}}if (!da){for (int k = 0; k < CTN; k++){xtemp = sDown[k].x + x;ytemp = sDown[k].y + y;fillArea[ytemp][xtemp] = 1;fillArea[ytemp][cxSize]++;fillArea[cySize][xtemp]++;}}return da;}bool leftAble() //能否左移{bool la = true;int x = (offsetx - (int) (pelsSize / 2)) / pelsSize; int y = (offsety - (int) (pelsSize / 2)) / pelsSize; int xtemp;int ytemp;for (int i = 0; i < CTN; i++){xtemp = sDown[i].x + x-1;ytemp = sDown[i].y + y;if (fillArea[ytemp][xtemp] > 0 || xtemp <0) {la = false;break;}return la;}bool rightAble() //能否右移{bool ra = true;int x = (offsetx - (int) (pelsSize / 2)) / pelsSize; int y = (offsety - (int) (pelsSize / 2)) / pelsSize ; int xtemp;int ytemp;for (int i = 0; i < CTN; i++){xtemp = sDown[i].x + x+1;ytemp = sDown[i].y + y;if (fillArea[ytemp][xtemp] > 0 || xtemp > 24) {ra = false;break;}}return ra;}bool disRows(HWND hwnd) //消行{HDC hdc=GetDC(hwnd);bool da=false;int row[CTN];//可以消除的行for (int ii = 0; ii < CTN; ii++)row[ii] = 0;int number = 0;//可连续消的行数static int levelScore;SelectObject(hdc,hPen1);for (int i = 0; i < cySize; i++){if (fillArea[i][cxSize] == cxSize)row[number++] = i;}if (number > 0)//可以消行{da=true;levelScore+=(number + 1) * number / 2; score += (number + 1) * number / 2;if(levelScore>2)//增加游戏级别levelScore=0;CURRENTLEVEL=(int)CURRENTLEVEL*2/3;SetTimer(hwnd,TIMER,CURRENTLEVEL,NULL);for(int i=0;i<15;i++){if((int)CURRENTLEVEL*3*(i+1)/2>=600){level=i+2;break;}}}InvalidateRect(hwnd,&rt,true);for (int k = 0; k < number; k++){for(int i=row[k];i>0;i--){for(int j=0;j<cxSize+1;j++){fillArea[i][j]=fillArea[i-1][j];}}}InvalidateRect(hwnd,NULL,true);}ReleaseDC(hwnd,hdc);return da;}int main(){HINSTANCE hInstance=NULL;static TCHAR szAppName[]=TEXT("ELS");HWND hwnd;MSG msg;WNDCLASS wndclass;wndclass.style=CS_HREDRAW|CS_VREDRAW;//|~(WS_MINIMIZEBOX|WS_MAXIMIZEB OX) ;wndclass.lpfnWndProc=WndProc;wndclass.cbClsExtra=0;wndclass.cbWndExtra=0;wndclass.hInstance=hInstance;wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);wndclass.hbrBackground= (HBRUSH)GetStockObject (WHITE_BRUSH);// CreateSolidBrush(RGB(195,195,237));wndclass.lpszMenuName= NULL;wndclass.lpszClassName= szAppName;if(!RegisterClass(&wndclass)){MessageBox(NULL,TEXT("REGISTER ERROR"),szAppName,MB_ICONERROR);return 0;}hwnd=CreateWindow(szAppName,TEXT("俄罗斯方块"),WS_DLGFRAME|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,//( WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX)&~WS_BORDER,//WS_SIZEBOX WS_OVERLAPPEDWINDOW&~WS_MAXIMIZEBOX,WS_CAPTION|//&~WS_MAXIMIZEBO X禁用最大化选项300,100,429,480,NULL,NULL,hInstance,NULL);ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd);while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){HDC hdc;PAINTSTRUCT ps;RECT r;static bool down=false;bool isSend=false;switch(message){case WM_CREATE:{SetTimer(hwnd,TIMER,CURRENTLEVEL,NULL);//cout<<"level1"<<endl;return 0;}case WM_SIZE:return 0;case WM_TIMER:{if(startGame&&go){if (down){if(!downAble())//不能再下落条件{// cout<<"can not down"<<endl;down=false;disRows(hwnd);if(!isSend){SendMessage(hwnd,MS_DOWN,0,0);isSend=true;}}else{draw(hwnd, sDown, rectDown,(HBRUSH)GetStockObject(WHITE_BRUSH), offsetx, offsety);offsety += pelsSize;draw(hwnd, sDown, rectDown,hBrush1, offsetx, offsety);}}}return 0;}case MS_DOWN:{draw(hwnd,sNext,rectNext,(HBRUSH)GetStockObject(WHITE_BRUSH),369,44);getNext(sDown,sNext);draw(hwnd,sNext,rectNext,hBrush1,369,44);draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety);//判断游戏是否结束offsety-=pelsSize;if(downAble()){offsety+=pelsSize;isSend=false;down=true;}else{// cout<<"game over!"<<endl;startGame=false;gameOver=true;InvalidateRect(hwnd,&rt,true);}}case WM_PAINT:{hdc = BeginPaint(hwnd, &ps);GetClientRect(hwnd, &r);SelectObject(hdc,hPen1);SelectObject(hdc,hBrush1);for(int i=1;i<cxSize+8;i++){MoveToEx(hdc,i*pelsSize,0,NULL);LineTo(hdc,i*pelsSize,476);}for(int j=1;j<cySize;j++){MoveToEx(hdc,0,j*pelsSize,NULL);LineTo(hdc,425,j*pelsSize);}SaveDC(hdc);for(int t=0;t<cySize;t++)for(int k=0;k<cxSize;k++){if(fillArea[t][k]>0){Rectangle(hdc,k*pelsSize,t*pelsSize,(k+1)*pelsSize+1,(t+1)*pelsSize+1);}}if(startGame){draw(hwnd,sNext,rectNext,hBrush1,369,44);draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety);}FillRect(hdc,&rt,hBrush2);WCHAR ss[20];WCHAR ll[20];wsprintf(ss,TEXT("score:%d"),score);wsprintf(ll,TEXT("level:%d"),level);TextOut(hdc,331,300,ll,lstrlen(ll));TextOut(hdc,331,320,ss,lstrlen(ss));if(gameOver){TextOut(hdc,330,200,TEXT("game over!"),strlen("game over!"));}SelectObject(hdc, GetStockObject(BLACK_PEN));Polyline(hdc, area, 3);//绘制一个矩形MoveToEx(hdc, 325, 80, NULL);LineTo(hdc, 425, 80);EndPaint(hwnd, &ps);return 0;}case WM_KEYDOWN:switch(wParam){case VK_UP:{if(go&&startGame){down=false;draw(hwnd,sDown,rectDown,(HBRUSH)GetStockObject(WHITE_BRUSH),offsetx,offsety);rotate(sDown,rTypeDown,1,false);draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety);}}return 0;case VK_DOWN:{if(go&&startGame){down=false;draw(hwnd,sDown,rectDown,(HBRUSH)GetStockObject(WHITE_BRUSH),offsetx,offsety);int k=(offsety-(int)(pelsSize)/2)/pelsSize;while(k<cySize){if(downAble()){offsety+=pelsSize;}elsebreak;}draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety);disRows(hwnd);SendMessage(hwnd,MS_DOWN,0,0);}return 0;}case VK_LEFT:{if(leftAble()&&go&&startGame){down=false;draw(hwnd,sDown,rectDown,(HBRUSH)GetStockObject(WHITE_BRUSH),offsetx,offsety);offsetx-=pelsSize;draw(hwnd,sDown,rectDown,hBrush1,offsetx,offsety);}return 0;}case VK_RIGHT:{if(rightAble()&&go&&startGame){down=false;draw(hwnd, sDown, rectDown, (HBRUSH) GetStockObject(WHITE_BRUSH), offsetx, offsety);offsetx+=pelsSize;draw(hwnd, sDown, rectDown, hBrush1,offsetx, offsety);}return 0;}case VK_SPACE:{go=!go;return 0;}case VK_RETURN:{if(!startGame&&!gameOver){//cout<<"startGame"<<endl;gameOver=false;start();getRandom();SendMessage(hwnd,MS_DOWN,0,0);}if(!startGame&&gameOver){// cout<<"RestartGame!"<<endl;gameOver=false;start();level=1;InvalidateRect(hwnd,NULL,true);getRandom();SendMessage(hwnd,MS_DOWN,0,0);}return 0;}}return 0;case WM_KEYUP:switch(wParam){case VK_UP:if(go)down=true;return 0;case VK_LEFT:if(go)down=true;return 0;case VK_RIGHT:if(go)down=true;return 0;}return 0;case WM_DESTROY:DeleteObject(hBrush1);DeleteObject(hBrush2);DeleteObject(hPen1);KillTimer(hwnd,TIMER);PostQuitMessage(0);return 0;}return DefWindowProc(hwnd,message,wParam,lParam); }。