我的俄罗斯方块,WI32,GDI

#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);
}

你可能感兴趣的:(俄罗斯方块,gdi)