1、/*void DoUpShift(HDC);*/void DoRedirection(HDC);void DoAccelerate(HDC);int cur_left, cur_top; /记录方块当前的位置int width_block, height_block; /方块的宽带和高度static byte *block = NULL; /方块,方块为随机大小,采用动态分配内存方式,所以这里是指针变量void DrawPanel(HDC hdc); /绘制表格void RefreshPanel(HDC hdc); /刷新面板bool IsTouchBottom(HDC); /判断是否到达底部
2、void ClearRow(HDC); /消行byte g_panelROWSCOLS = 0 ;int score = 0; /分数/升级所需分数值#define SCORE_LEVEL_INC 80/int main()int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) /HINSTANCE hInstance=GetModuleHandle(NULL); WNDCLASS wndClass; MSG uMsg; wndClass.style = CS
3、_HREDRAW | CS_VREDRAW; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndClass.lpfnWndProc = WndProc; wndClass.hInstance = hInstance; wnd
4、Class.lpszClassName = TEXT(Tetris); wndClass.lpszMenuName = NULL; if (!RegisterClass(&wndClass) printf(Register Class Occur Error! exit(1); hWnd = CreateWindow(wndClass.lpszClassName, TEXT(Tetris Demo), WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, hInstance, NULL); ShowWindow(hWnd, SW_SHOW); UpdateWindow(
5、hWnd); while (GetMessage(&uMsg, NULL, 0, 0) TranslateMessage(&uMsg); DispatchMessage(& return uMsg.wParam;LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) HDC hdc; PAINTSTRUCT ps; /int x,y; /在这个函数块中没有用到,其实 switch (message) case WM_CREATE: MoveWindow(hwnd, 400, 10, CELL
6、*COLS + 8, CELL*COLS + 32, FALSE);/这里CELL*COLS+8表示的意义是窗口的宽,CELL*COLS+32表示的高;该句补上宽和高 srand(unsigned int)time(NULL); ExportBlock(); /根据上面的随机种子生成一个输出的俄罗斯方块(落下来的) timer_id = SetTimer(hwnd, ID_TIMER, interval_base - level*interval_unit, NULL);/参数2:触发计时器的事件,参数3:计时器的时间间隔 return 0; /既然有计时器,当然就要对计时器消息进行处理 ca
7、se WM_TIMER: hdc = GetDC(hwnd); DoDownShift(hdc); /生成的方块下落 ReleaseDC(hwnd, hdc); case WM_KEYDOWN: switch (wParam) case VK_LEFT: /左方向键左移? if (!isPause) DoLeftShift(hdc); break; case VK_RIGHT:isPause) DoRightShift(hdc);/右方向键右移? case VK_UP:isPause) /*DoUpShift(hdc);*/DoRedirection(hdc);/转向? case VK_DOW
8、N: /DoDownShift(hdc);isPause) DoAccelerate(hdc); case VK_SPACE: isPause =/*true;*/!isPause; /这里一个细节,差点弄错啊,还需要多注意、多头脑风暴下 if (isPause) if (timer_id) KillTimer(hwnd, ID_TIMER); timer_id = 0; else timer_id = SetTimer(hwnd, ID_TIMER, interval_base - level*interval_unit, FALSE); case WM_DESTROY: if (block
9、) free(block); /block表示每次往下掉的方块 if (timer_id) KillTimer(hwnd, ID_TIMER); PostQuitMessage(0); case WM_PAINT: hdc = BeginPaint(hwnd, &ps); DrawPanel(hdc); /绘制面板 RefreshPanel(hdc); /刷新 EndPaint(hwnd, & return DefWindowProc(hwnd, message, wParam, lParam);/下面,按照我们在WndProc()函数中需要用到的子函数来写出其定义bool ExportBlo
10、ck() /输出方块 int sel; if (block) free(block); /释放之前分配的内存 block = NULL; sel = rand() % 7; switch (sel) case 0: /水平条 width_block = 4; height_block = 1; block = (byte *)malloc(sizeof(byte)*width_block*height_block); *(block + 0) = 1; /可以理解为*(block+0*width_block+0)=1,即第一行的第一个方格,下面同理 *(block + 1) = 1; /*(b
11、lock+0*width_block+1)=1 *(block + 2) = 1; /*(block+0*width_block+2)=1 *(block + 3) = 1; /*(block+0*width_block+3)=1,作者实际是用的渲染的想法 cur_top = 0 - height_block; /奇怪,作者的坐标系到底是怎样的观念,这里怎么用0-height_block,表示方块还未完全显示 cur_left = (COLS - width_block) / 2; break; case 1: /三角 width_block = 3; height_block = 2; *(
12、block + 0) = 0; /可以理解为*(block+0*width_block+0)=0,即第一行的第一个方格,下面同理 *(block + 2) = 0; /*(block+0*width_block+2)=0 /*(block+1*width_block+0)=1,第二行开始 *(block + 4) = 1; /*(block+1*width_block+1)=1 *(block + 5) = 1; /*(block+1*width_block+2)=1 case 2: /左横折 /可以理解为*(block+0*width_block+0)=1,下面同理 | *(block +
13、1) = 0; /*(block+0*width_block+1)=0 | | | /*(block+1*width_block+0)=1 case 3: /右横折 /可以理解为*(block+0*width_block+0)=0,下面同理 | /*(block+0*width_block+1)=0 case 4: /左闪电 /可以理解为*(block+0*width_block+0)=1,下面同理 /*(block+0*width_block+1)=1 *(block + 3) = 0; /*(block+1*width_block+0)=0 case 5: /右闪电 /可以理解为*(blo
14、ck+0*width_block+0)=0,下面同理 /*(block+0*width_block+1)=1 /*(block+0*width_block+2)=1 *(block + 5) = 0; /*(block+1*width_block+2)=0 case 6: /石头 width_block = 2; /可以理解为*(block+0*width_block+0)=1,下面同理 return block != NULL;void DoDownShift(HDC hdc) /下移 if (NULL = block)return; if (IsTouchBottom(hdc) /到底部
15、/消行处理 ClearRow(hdc); /输出下一个方块 cur_top+; RefreshPanel(hdc);void DoLeftShift(HDC hdc) /左移 int x, y; if (0 = cur_left)return; if (cur_top0)return; /方块没有完整显示前,不能左移 for (y = 0; yheight_block; y+) for (x = 0; x= 0; x-) /从右边开始扫描,获取该行最右边的实心方格块 /判断当前方格在面板上右边一个方格是否为实心,是就代表不能再右移 if (g_panelcur_top + ycur_left
16、+ x + 1)return; /只判断最右边的一个实心方格 cur_left+;void DoRedirection(HDC hdc) /改变方向 int i, j; byte * temp = NULL; /方块完整显示前不能转向 temp = (byte *)malloc(sizeof(byte)*width_block*height_block); for (i = 0; i i+) for (j = 0; j= ROWS | temp_cur_left= COLS) free(temp); /退出前必须先释放内存 return;max_len; /转向所需的空间内有已被占用的实心方格存在,即转向失败 if (g_paneltemp_cur_top + itemp_cur_left + j) free(temp); return; /把临时变量的值赋给block,只能赋值,而不能赋指针值 /blockij=tempij; *(block + i*width_block + j) = *(temp + i*width_block + j);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1