上次发表的一个win32的俄罗斯方块游戏这次把代码发出来
并来这个游戏还是要改进的,改进的方法是用多线程来分配游戏的数据运算与绘画图像动画播放的,现在没时间做了,那位有兴趣的可以照我的代码写出你自己的游戏!!!!程序代码:
// 俄罗斯方块.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "resource.h" #define MAX_LOADSTRING 100 //时间ID #define TIME 0x1 #define YELLO_RECT 0x1 #define RED_RECT 0x2 #define GREEN_RECT 0x3 //自定义消息 #define WM_RANDRECT WM_USER +1 //out to rect message #define WM_STARTGAME WM_USER + 2 //start a game message #define WM_COMEOVER WM_USER + 3 //game to over message #define WM_OUTRECT WM_USER + 4 //Out to rect message #define WM_READYGAME WM_USER + 5 //ready out to rect message #define WM_MOVERECT WM_USER + 6 //start move rect message #define WM_DRAWRECT WM_USER + 7 //draw down here rect message #define WM_NEXTGAME WM_USER + 8 //Next game #define WM_LOADRECT WM_USER + 9 //Load rect #define WM_NEXTRECT WM_USER + 10 //Show next rect #define WM_MOVEPOINT WM_USER + 11 //Show Flas #define WM_OUTTEXT WM_USER + 12 #define VKDOWN 1 //keyboard to down message #define VKUP 2 //keyboard to up message #define VKLEFT 4 //keyboard to left #define VKRIGHT 8 //keyboard to right #define VKSPACE 16 //keyboard to space #define ID_SHOWRECT 1 //out to rect ID #define ID_NEXTRECT 2 //next rect ID // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text WNDPROC OldProc; //Old windows proc // Foward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK SHOWRECT(HWND, UINT, WPARAM, LPARAM); //OutRect Proc Function typedef struct COUNT { BYTE count; WORD x; WORD y; WORD cy; }COUNT,*PCOUNT; //自定义函数 void InitRect(char a[], int size); //初始化画面函数 void RandRect(BYTE p[], BYTE &x); //随机出方块 void Round(BYTE a[], int size, int x); //转动方块函数 int InToRect(HWND hDlg, BYTE a[],const BYTE b[], const int x, const int y); //方块赋值于显示矩阵中 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. MSG msg; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_MY, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage is only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; HBITMAP hBitmap; HBRUSH hBrush; hBitmap = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BK)); hBrush = CreatePatternBrush(hBitmap); DeleteObject(hBitmap); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_MY); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = hBrush; //(HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_MY; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex); } // // FUNCTION: InitInstance(HANDLE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^WS_MAXIMIZEBOX, CW_USEDEFAULT, 0, 400, 520, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // int IsToMove(const BYTE pOutRect[],const BYTE ShowRect[], const int x, const int y, const int type) { int top; int flag = 0; int i, j; switch(type) { case VKDOWN: //判断能否下落方块 top = int(pOutRect[16] - 1); i = top; for(;i >= 0; i--) //判断在第几行出现方格 { flag = 0; for(j = 0; j < pOutRect[16] && !flag; j++) { if(pOutRect[i*pOutRect[16] + j]) flag = 1; } if(flag) break; else top--; } if(y + top >= 19) return 0; //到达底部 for(j = top; j >= 0; j--) { if(y + j < 0) break; flag = j * pOutRect[16]; for(int l = 0; l < pOutRect[16]; l++) { if(pOutRect[flag +l] && ShowRect[(y+j+1)*11+x+l]) { if(y <= 0 && (x >3 && x < 9)) return VKUP; //游戏结速 return 0; //方块下落 } } } return VKDOWN; case VKLEFT: //判断能否向左移动方块 top = 0; //判断左边是在第几例 for(i = 0; i < pOutRect[16]; i++) { flag = 0; for(j = 0; j < pOutRect[16]; j++) { if(pOutRect[j*pOutRect[16] + i]) { flag = 1; break; } } if(flag) break; else top++; } if(x + top -1 >= 0) //未到边 { for(i = 0; i < pOutRect[16]; i++) { flag = i * pOutRect[16] + top; for(j = 0; j < pOutRect[16] - top; j++) { if(pOutRect[flag + j] && ShowRect[(y + i) * 11 + x + top + j - 1]) return 0; //不能向左移动了 } } return VKLEFT; } return 0; case VKRIGHT: top = pOutRect[16] - 1; //判断左边是在第几例 for(i = pOutRect[16] - 1; i >= 0; i--) { flag = 0; for(j = 0; j < pOutRect[16]; j++) { if(pOutRect[j*pOutRect[16] + i]) { flag = 1; break; } } if(flag) break; else top--; } if(x + top + 1 < 11) //未到边 { for(i = top; i >= 0; i--) { for(j = 0; j < pOutRect[16]; j++) { flag = j * pOutRect[16] + i; if(pOutRect[flag] && ShowRect[(y + j) * 11 + x + top + i + 1]) return 0; //不能向左移动了 } } return VKRIGHT; } return 0; } return 0; } void DrawRect(HDC hdc, HDC Memhdc, BYTE a,const int x, const int y) { switch(a) { case 0: BitBlt(hdc,x,y,20,20,Memhdc,20,20,SRCCOPY); break; case 1: BitBlt(hdc,x,y,20,20,Memhdc,40,0,SRCCOPY); break; case 2: BitBlt(hdc,x,y,20,20,Memhdc,0,0,SRCCOPY); break; case 3: BitBlt(hdc,x,y,20,20,Memhdc,20,0,SRCCOPY); break; case 4: BitBlt(hdc,x,y,20,20,Memhdc,0,20,SRCCOPY); break; case 5: BitBlt(hdc,x,y,20,20,Memhdc,0,40,SRCCOPY); break; } } void PlayPoint(WORD& COUNTS, HDC hdc,HDC hdcRect, COUNT a[],BYTE ShowRect[]) { int s,i,j; if(!COUNTS) return ; SetBkMode(hdc,TRANSPARENT); for(j = 0,i = 0x8000; j < 16; j++,i>>=1) //演示动画 { if(i ^ (i & COUNTS)) continue; //没动画或帧数为0 s = (a[j].y - 1) * 11 +a[j].x; DrawRect(hdc,hdcRect,ShowRect[s],a[j].x*20,(a[j].y-1)*20); s = a[j].y * 11 +a[j].x; DrawRect(hdc,hdcRect,ShowRect[s],a[j].x*20,(a[j].y)*20); if(!(--a[j].count)) { COUNTS ^= i; continue; } TextOut(hdc,a[j].x*20,a[j].cy -( 20 - a[j].count),TEXT("+5"),2); } } void PlayRect(WORD& COUNTS, HDC hdc,HDC hdcRect, COUNT b[],BYTE ShowRect[]) { int i,j,k,l,r; if(!COUNTS) return ; k = 1; for(j = 0,i = 0x8000; j < 16; j++,i>>=1) //演示动画 { if(b[j].cy < 1) continue; if(b[j].cy == 1) { ShowRect[b[j].y*11+b[j].x] = 0; if(b[j].count < 12) { BitBlt(hdc,b[j].x * 20,b[j].y * 20, 20, 20,hdcRect,(b[j].count % 3) * 20,(b[j].count / 3 + 2)*20,SRCCOPY); b[j].count++; } else { COUNTS ^= i; b[j].cy = 0; BitBlt(hdc,b[j].x * 20,b[j].y * 20, 20,20, hdcRect,20,20,SRCCOPY); l = b[j].x - 1 >= 0 ? b[j].x - 1 : -1; r = b[j].x + 1 < 11 ? b[j].x - 1 : -1; if(((l == -1) || !ShowRect[(b[j].y - k)*11 + l]) && ((r == -1) || !ShowRect[(b[j].y - k)*11 + r]) && ShowRect[(b[j].y - k)*11+b[j].x]) { do { ShowRect[(b[j].y - k + 1)*11 + b[j].x] = ShowRect[(b[j].y - k)*11 + b[j].x]; k++; }while(ShowRect[(b[j].y - k)*11 + b[j].x]); ShowRect[(b[j].y - k + 1)*11 + b[j].x] = 0; } } } else b[j].cy--; } } void Play(HWND hDlg, WPARAM wParam,LPARAM lParam, WORD& COUNTS, COUNT a[]) { int i; int x,y; x = LOWORD(lParam); y = HIWORD(lParam); switch(wParam) { case 0: for(i = 0x8000; !(i ^ ((WORD)i&COUNTS)) && i; i>>=1) ; COUNTS |= (WORD)i; for(i = 0; i < 16; i ++) { if(a[i].count <= 0) { a[i].count = 15; //15帧动画 a[i].x = (WORD)x; a[i].cy = (WORD)y * 20; a[i].y = (WORD)y; break; } } break; case 1: for(i = 0x8000; !(i ^ ((WORD)i&COUNTS)) && i; i>>=1) ; COUNTS |= (WORD)i; for(i = 0; i < 16; i ++) { if(a[i].cy < 1) { a[i].cy = 240; //定时器 a[i].count = 0; //动画帖数 a[i].x = (WORD)x; a[i].y = (WORD)y; SendMessage(GetParent(hDlg),WM_OUTTEXT,a[i].x,a[i].y); break; } } break; case 2: for(i = 0,wParam = 0x8000; i < 16; i ++,wParam>>=1) { if(a[i].cy > 0) { if(a[i].x == x && a[i].y == y) { a[i].cy =0; //定时器 //a[i].count = 12; //动画帖数 COUNTS ^=(WORD)wParam; } } } break; case 3: for(i = 0; i < 16; i ++) { if(a[i].cy > 0 && a[i].y < (WORD)lParam) { a[i].y++; } } break; } } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; //显示 HFONT font,Old; //字体 static HWND ShowRect, //显示方块子窗口句丙 NextRect; //显示下一个方块子窗口句丙 static int Lever, //关卡 Point, //分数 cPoint; //记数分数 static char OutRect[16]; //移动方块和下一个方块 static BYTE OutWidth; //方块的宽度 int i; switch (message) { case WM_CREATE: //创建窗口消息 srand((int)GetCurrentTime()); //设置随机函数 ShowRect = CreateWindow(TEXT("static"),TEXT(""),WS_CHILD|WS_VISIBLE,20,60,220,400,hWnd,(HMENU)ID_SHOWRECT,hInst,NULL); //创健显示方块子静态子窗口 NextRect = CreateWindow(TEXT("static"),TEXT(""),WS_CHILD|WS_VISIBLE,260,100,80,80,hWnd,(HMENU)ID_NEXTRECT,hInst,NULL); //创健显示下一个方块静态子窗口 OldProc = (WNDPROC) SetWindowLong(ShowRect,GWL_WNDPROC,(LONG)SHOWRECT); //窗口子类化 //窗口子类化 SetWindowLong(NextRect,GWL_WNDPROC,(LONG)SHOWRECT); //窗口子类化 SendMessage(ShowRect,WM_LOADRECT,0,0); SendMessage(hWnd,WM_STARTGAME,1,40); //发一个开始游戏消息WM_STARTGAME WPARAM 为关卡 LPARAM 为关卡分数 break; case WM_STARTGAME: //开始游戏 Lever = (int) wParam; //取得关卡 if(Lever > 10) Lever = 1; Point = lParam; //取得关卡分数 cPoint= 0; //关卡记数分数 SendMessage(ShowRect,WM_READYGAME,Lever,0);//初始化显示子窗口数据 SendMessage(ShowRect,WM_MOVERECT,0,0); //发一个刷方块消息 break; case WM_NEXTGAME: //下一关游戏 if(lParam) { MessageBox(NULL,TEXT("进入下一关"),TEXT("提示"),MB_OK); Point += 20; cPoint = 0; SendMessage(hWnd,WM_STARTGAME,Lever+1,Point); } else { cPoint += wParam; //加分 if(cPoint >= Point){ KillTimer(ShowRect,1);SendMessage(hWnd,WM_NEXTGAME,0,Lever+1);} //进入下一关 if(Lever > 10) Lever = 0; InvalidateRect(hWnd,NULL,TRUE); } break; case WM_NEXTRECT: //显示下一个方块 SendMessage(NextRect,WM_NEXTRECT,0,0); break; case WM_COMEOVER: //游戏结速 MessageBox(NULL,TEXT("游戏结速"),TEXT("提示"),MB_OK); break; case WM_OUTTEXT: { TCHAR Text[30]; i = wsprintf(Text,"%d -- %d ",wParam,lParam); hdc = GetDC(hWnd); TextOut(hdc,260,240,Text,i); ReleaseDC(hWnd,hdc); } break; case WM_SETFOCUS: //设显示子窗口 SetFocus(ShowRect); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); SetBkMode(hdc,TRANSPARENT); // font = CreateFont(30,30,0,0,700,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,0,DEFAULT_QUALITY,0,"XIE"); Old =(HFONT)SelectObject(hdc,font); SetTextColor(hdc,RGB(255,0,0)); TextOut(hdc,40,10,TEXT("俄罗斯方块"),10); DeleteObject(font); SelectObject(hdc,Old); { TCHAR Text[20]; i = wsprintf(Text,"关卡:第 %d 关",Lever); TextOut(hdc,260,200,Text,i); i = wsprintf(Text,"分数:%d/%d",Point,cPoint); TextOut(hdc,260,220,Text,i); } EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // Mesage handler for about box.