我的俄罗斯方块,WI32,GDI
2016-03-12 14:05
405 查看
#include <Windows.h> #include <time.h> #include <iostream> using namespace std; HWND hwnd; #define UUMLINES ((int)(sizeof devcaps/sizeof devcaps[0]))//注意加空格 #define W 12 #define H 20 #define CELL 30 #if(1) //block_shap ,0--19,1+2+8+4+5 #define BLOCKS_NUM 19 #define BLOCK_SHAPE_O 0 #define BLOCK_SHAPE_I_1 1 #define BLOCK_SHAPE_I_2 2 #define BLOCK_SHAPE_L_0 3 #define BLOCK_SHAPE_L_1 4 #define BLOCK_SHAPE_L_2 5 #define BLOCK_SHAPE_L_3 6 #define BLOCK_SHAPE_L_4 7 #define BLOCK_SHAPE_L_5 8 #define BLOCK_SHAPE_L_6 9 #define BLOCK_SHAPE_L_7 10 #define BLOCK_SHAPE_S_0 11 #define BLOCK_SHAPE_S_1 12 #define BLOCK_SHAPE_S_2 12 #define BLOCK_SHAPE_S_3 14 #define BLOCK_SHAPE_T_0 15 #define BLOCK_SHAPE_T_1 16 #define BLOCK_SHAPE_T_2 17 #define BLOCK_SHAPE_T_3 18 #endif #define MAP_NONE 0 #define MAP_LAND 1 #define MAP_BLOCK 2 #define MOVE_TIME 200 #define REFRESH_TIME 33 #define CHANGE_TIME 150 #define STATE_DOWN 0 #define STATE_LEFT 1 #define STATE_RIGHT 2 #define STATE_LAND 3 #define STATE_CHANGESHAPE 4 #define SCORE_EACH 5 #define COLOR_BK RGB(255,255,255) #define COLOR_BLOCK RGB(0,0,0) class Clock { public: void Init() { curtime = GetTickCount(); pretime = curtime; premovetime = curtime; curmovetime = curtime; curchangtime = curtime; prechangetime = curtime; } bool isRefresh() { curtime = GetTickCount(); if (curtime - pretime > REFRESH_TIME) { pretime = curtime; return true; } else return false; } bool isChangeShape() { curchangtime = GetTickCount(); if (curchangtime - prechangetime > CHANGE_TIME) { prechangetime = curchangtime; return true; } else return false; } bool isMove() { curmovetime = GetTickCount(); if (curmovetime - premovetime > MOVE_TIME) { premovetime = curmovetime; return true; } else return false; } private: clock_t curtime; clock_t pretime; clock_t curmovetime; clock_t premovetime; clock_t curchangtime; clock_t prechangetime; }; void VerCpy(int dest[BLOCKS_NUM][4][4], int source[BLOCKS_NUM][4][4]) { memcpy(dest, source, 4 * 4 * BLOCKS_NUM*sizeof(int)); } class Point { public: int x; int y; }; class Block { private: int shape_num;//0-18,共19个 int shape_num_width[BLOCKS_NUM];//记录每种状态的宽度 int shape_num_height[BLOCKS_NUM]; int shape_state_size[5];//分别为1,2,8,4,4,共19 int blocks[BLOCKS_NUM][4][4]; Point pos; enum block_state { DOWN,LEFT,RIGHT,LAND,CHANGESHAPE }blockstate; public: void BlockDistribute() { pos.x = W / 2; pos.y = -4; srand((unsigned int)time(NULL)); shape_num = rand()%BLOCKS_NUM;///0-19 ChangeBlockState(STATE_DOWN); } void Init() { #if(1) int temp_blocks[BLOCKS_NUM][4][4]= { { {1,1,0,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0} },//1 { { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 } },//2 { { 1, 1, 1, 1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//3 { { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 } },//4 { { 0, 0, 1, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//5 { { 1, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },//6 { { 1, 1, 1, 0 }, { 1, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//7 { { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 } },//8 { { 1, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//9 { { 1, 1, 0, 0 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 0, 0, 0, 0 } },//10 { { 1, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//11 { { 0, 1, 1, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//12 { { 1, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },//13 { { 1, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//14 { { 0, 1, 0, 0 }, { 1, 1, 0, 0 }, { 1, 0, 0, 0 }, { 0, 0, 0, 0 } },//15 { { 0, 1, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//16 { { 0, 1, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },//17 { { 1, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },//18 { { 1, 0, 0, 0 }, { 1, 1, 0, 0 }, { 1, 0, 0, 0 }, { 0, 0, 0, 0 } },//19 }; #endif memcpy(blocks,temp_blocks, 4 * 4 * BLOCKS_NUM*sizeof(int)); int temp_num_width[BLOCKS_NUM] = { 2, 1, 4, 2, 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 2, 3, 2, 3, 2 }; memcpy(shape_num_width, temp_num_width, BLOCKS_NUM*sizeof(int)); int temp_shape_state_size[5] = { 0, 2, 10, 14, 18 }; memcpy(shape_state_size, temp_shape_state_size, 5 * sizeof(int)); int temp_shape_state_heigth[BLOCKS_NUM] = { 2, 4, 1, 3, 2, 3, 2, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 3 }; memcpy(shape_num_height, temp_shape_state_heigth, BLOCKS_NUM*sizeof(int)); pos.x = W / 2; pos.y = -4; blockstate = DOWN; srand((unsigned int)time(NULL)); shape_num = rand() % BLOCKS_NUM ; } void ChangeShape() { if (shape_num > BLOCK_SHAPE_O) { int key; // int minnum; for (key = 0; key < 5; key++) { if (shape_state_size[key] >= shape_num) break; } if ((++shape_num)>shape_state_size[key]) shape_num = shape_state_size[key - 1] + 1; } else return; } int GetNextShapeNum() { if (shape_num > BLOCK_SHAPE_O) { int key; // int minnum; for (key = 0; key < 5; key++) { if (shape_state_size[key] >= shape_num) break; } if ((shape_num + 1)>shape_state_size[key]) return shape_state_size[key - 1] + 1; else return shape_num + 1; } else return shape_num; } void ChangeBlockState(int STATE) { switch (STATE) { case STATE_DOWN: blockstate = DOWN; break; case STATE_LEFT: blockstate = LEFT; break; case STATE_RIGHT: blockstate = RIGHT; break; case STATE_CHANGESHAPE: blockstate = CHANGESHAPE; break; case STATE_LAND: blockstate = LAND; break; } } int GetBlockState() { switch (blockstate) { case DOWN: return STATE_DOWN; break; case LEFT: return STATE_LEFT; break; case RIGHT: return STATE_RIGHT; break; case LAND: return STATE_LAND; break; case CHANGESHAPE: return STATE_CHANGESHAPE; break; } return DOWN; } int GetShapenum() { return shape_num; } int GetShapeWidth(int num) { return shape_num_width[num]; } int GetShapeHeigt(int num) { return shape_num_height[num]; } void GetBlockShape(int m[4][4],int number) { memcpy(m, blocks[number], 16 * sizeof(int)); } Point GetPos() { return pos; } void LeftMove() { pos.x--; /// if (pos.x <= 0) // pos.x = 0; } void RightMove() { pos.x++; // if (pos.x >=W-1) // pos.x = W-1; } void DownMove() { pos.y++; // if (pos.y >= H - 1) // pos.y = H - 1; } }; class GameSystem { private: int map[H][W]; int color[2];//背景,砖块 int score;//line的可次方,linescore = 5 int speed;//特指砖块移动速度,定义为1,即没0.5s移动1格 Block block; Clock clock; WCHAR strings[100]; public: void Init() { for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { map[i][j] = MAP_NONE; } } color[0] = 0; color[1] = 1; score = 0; int speed = 1; clock.Init(); block.Init(); Render(); } void InsertBlock() { int shapenum = block.GetShapenum(); int shape[4][4] = { 0 }; Point pos = block.GetPos(); int hidelen = ((pos.y < 0) ? -pos.y : 0); if (hidelen == 4) return; block.GetBlockShape(shape, shapenum); for (int i = hidelen; i < 4; i++) { for (int j = 0; j < 4; j++) { if (shape[i][j]) map[pos.y + i][pos.x + j] = MAP_BLOCK; } } //gai if (block.GetBlockState() == STATE_LAND) { FixMap(); score += Checkline() * 10; block.BlockDistribute(); } } void RefreshMap() { for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { if (map[i][j] == MAP_BLOCK) map[i][j] = MAP_NONE; } } } void FixMap() { //经过判断砖块应该插入地图,成为地图一部分 for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { if (map[i][j] == MAP_BLOCK) map[i][j] = MAP_LAND; } } } bool isOkToDo(int state) { //准备阶段 Point pos = block.GetPos(); int shape[4][4] = { 0 }; int shapenum = block.GetShapenum(); int shapewidth ; int shapeheight; int nextshapenum; switch (state)//先判断特殊,再一起判断常规--碰撞 { case STATE_DOWN: //先判断底部 shapeheight = block.GetShapeHeigt(shapenum); shapewidth = block.GetShapeHeigt(shapenum); if (shapeheight + pos.y >= H) return false; block.GetBlockShape(shape, shapenum); pos.y++;//gai break; case STATE_LEFT: //需要修改pos.x,获取当前shape if (pos.x <= 0) return false; else pos.x--; shapeheight = block.GetShapeHeigt(shapenum); shapewidth = block.GetShapeHeigt(shapenum); block.GetBlockShape(shape, shapenum); break; case STATE_RIGHT://与右边墙壁 shapewidth= block.GetShapeWidth(shapenum); if (pos.x + shapewidth >= W) return false; else pos.x++; shapeheight = block.GetShapeHeigt(shapenum); block.GetBlockShape(shape, shapenum); break; case STATE_CHANGESHAPE://右,下特殊 //右 nextshapenum = block.GetNextShapeNum(); shapewidth = block.GetShapeWidth(nextshapenum); shapeheight = block.GetShapeHeigt(nextshapenum); if (nextshapenum == BLOCK_SHAPE_O) return false; if (pos.x + shapewidth >= W) return false; //下 else if (pos.y + shapeheight > H) return false; else shapenum = nextshapenum; block.GetBlockShape(shape,shapenum); break; } //根据地图判断一般情况--砖块碰撞 int hidelen = ((pos.y < 0) ? -pos.y : 0); if (hidelen == 4) return true; block.GetBlockShape(shape, shapenum); for (int i = hidelen; i < shapeheight; i++) { for (int j = 0; j < 4; j++) { if (map[pos.y + i][pos.x + j] + shape[i][j] >= 2) return false; } } return true; } int Checkline() { int lines = 0; //经过判断砖块应该插入地图,成为地图一部分 for (int i = H-1; i >=0; i--) { int count = 0; for (int j = 0; j < W; j++) { count += map[i][j]; } if (count == W) { lines++; for (int k = i; k > 0; k--) { for (int j = 0; j < W; j++) { if (k == 0) map[k][j] = 0; else map[k][j] = map[k - 1][j]; } } i++; } } return lines; } void Chargeblock() { // int temp_block[4][4] = { 0 }; switch (block.GetBlockState()) { case STATE_DOWN: if (clock.isMove()) { if (isOkToDo(STATE_DOWN)) { block.DownMove(); } else block.ChangeBlockState(STATE_LAND); } break; case STATE_LAND: // FixMap(); //score += Checkline() * 10; //block.BlockDistribute(); break; case STATE_LEFT: //判断是否可以左,可以则左移,否则,不变,状态也要做出相应的改变 if (clock.isMove()) { if (isOkToDo(STATE_LEFT)) { block.LeftMove(); } } block.ChangeBlockState(STATE_DOWN); break; case STATE_RIGHT: if (clock.isMove()) { if (isOkToDo(STATE_RIGHT)) { block.RightMove(); } } block.ChangeBlockState(STATE_DOWN); break; case STATE_CHANGESHAPE: if (isOkToDo(STATE_CHANGESHAPE)&&clock.isChangeShape()) { block.ChangeShape(); } block.ChangeBlockState(STATE_DOWN); break; } } void DrawRectangle(int x1, int y1, int x2, int y2, COLORREF c) { HDC hdc; HBRUSH hbrush; RECT rect; SetRect(&rect, x1, y1, x2, y2); hbrush = CreateSolidBrush((COLORREF)c); hdc = GetDC(hwnd); FillRect(hdc, &rect, hbrush); ReleaseDC(hwnd, hdc); DeleteObject(hbrush); } void DrawText(TCHAR* text, int x, int y, COLORREF c) { HDC hdc; hdc = GetDC(hwnd); SetTextColor(hdc,(COLORREF)c); SetBkMode(hdc, TRANSPARENT); TextOut(hdc, x, y, text, lstrlen(text)); ReleaseDC(hwnd, hdc); } void Render() { for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { int y = i*CELL; int x = j*CELL; switch (map[i][j]) { case MAP_NONE: DrawRectangle(x, y, x + CELL, y + CELL,RGB(0,0,0)); break; case MAP_BLOCK: DrawRectangle(x, y, x + CELL, y + CELL, RGB(255,0,0)); break; case MAP_LAND: DrawRectangle(x, y, x + CELL, y + CELL, RGB(255, 0, 0)); break; } } } wsprintf(strings, TEXT("score:%d"), score); DrawText(strings, CELL , CELL, RGB(0, 255, 0)); } void Sendstate(int state) { //if ((state!=-1)&&clock.isMove()) if (state!=-1) block.ChangeBlockState(state); } void Gamemain(int state) { RefreshMap(); Sendstate(state); Chargeblock(); InsertBlock(); if (clock.isRefresh()) { Render(); } } }; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("DevCaps1"); GameSystem game; MSG msg = { 0 }; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW;// | CS_OWNDC; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_APPSTARTING); wndclass.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH)); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("窗口创建需要WINNT"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("eluosifangkuai"), WS_DLGFRAME | WS_POPUP,200,20, W*CELL,H*CELL, NULL, NULL, NULL, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); game.Init(); int state = -1; while (msg.message != WM_QUIT) { if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { if (GetAsyncKeyState(VK_UP)) state = STATE_CHANGESHAPE; if (GetAsyncKeyState(VK_LEFT)) state = STATE_LEFT; if (GetAsyncKeyState(VK_RIGHT)) state = STATE_RIGHT; game.Gamemain(state); state = -1; } } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static int cxChar, cxCaps, cyChar; // int status; // TCHAR szBuffer[10]; HDC hdc; // int i; PAINTSTRUCT ps; // TEXTMETRIC tm; // RECT rect; switch (message) { case WM_CREATE: hdc = GetDC(hwnd); ReleaseDC(hwnd, hdc); return 0; case WM_KEYDOWN: switch (VK_UP) { case VK_UP : SendMessage(hwnd, WM_KEYDOWN, VK_UP, 0); break; case VK_DOWN: SendMessage(hwnd, WM_KEYDOWN, VK_DOWN, 0); break; case VK_LEFT: SendMessage(hwnd, WM_KEYDOWN, VK_LEFT, 0); break; case VK_RIGHT: SendMessage(hwnd, WM_KEYDOWN, VK_RIGHT, 0); break; } case WM_PAINT: hdc = BeginPaint(hwnd, &ps); // SelectObject(ps.hdc, GetStockObject(DC_BRUSH)); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
相关文章推荐
- http协议学习系列
- 团队管理法则
- 根据两点经纬度计算距离
- 第二次上机实践项目-项目1-个人所得税计算器
- iOS截取视频缩略图的两种方法
- 再谈AC算法
- 团队晋升法则
- 团队生存法则
- Libevent源码分析(一)--- 基本数据结构
- 正则化方法:L1和L2 regularization、数据集扩增、dropout
- 利用hexo搭建博客
- C++11 lambda表达式
- CodeForces - 622A Infinite Sequence (思想)水
- FTP工作模式<二>
- 再谈KMP/BM算法(II)
- 再谈KMP/BM算法(I)
- 在线HTTP POST/GET接口测试 地址
- DOM编程练习(二)
- Android语音识别DEMO
- Xcode 快捷键