我的俄罗斯方块,WI32,GDI

来源:互联网 发布:ios编程培训 编辑:程序博客网 时间:2024/06/05 21:50
#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;}elsereturn false;}bool isMove(){curmovetime = GetTickCount();if (curmovetime - premovetime > MOVE_TIME){premovetime = curmovetime;return true;}elsereturn 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,共19int 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-19ChangeBlockState(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};#endifmemcpy(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;}elsereturn;}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;elsereturn shape_num + 1;}elsereturn 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  = 5int 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;}}//gaiif (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++;//gaibreak;case STATE_LEFT://需要修改pos.x,获取当前shapeif (pos.x <= 0)return false;elsepos.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;elsepos.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;elseshapenum = 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;elsemap[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();}elseblock.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);}

0 0