当前访客身份:游客 [ 登录 | 加入 OSCHINA ]

代码分享

当前位置:
代码分享 » C/C++  » Windows编程
分享到: 
收藏 +0
2
复习到GDI,就来写写。这里分享一部份代码,其余的在群共享!Y(^_^)Y 欢迎广大编程爱好者加入!(群:▁翼★″编程交流づ   234056226)
标签: Windows

代码片段(5) [全屏查看所有代码]

1. [图片] 开始菜单.jpg    

2. [图片] 游戏中.jpg    

3. [图片] 暂停中.jpg    

4. [图片] 游戏结束.jpg    

5. [代码][C/C++]代码     跳至 [5] [全屏预览]

#include"Square_Data.h"
#include<tchar.h>
#include"resource.h"

//#define DEBUG_	MessageBeep (MB_ICONEXCLAMATION)
#define SQ_TIMER_1		0x1			//计时器
#define SLEEP_TIMER		600			//下落速度
#define SLEEP_TIMER_1   10			//快速下落

//////////////////////////////////////////////////////////////////////////
/************************************************************************/
/*                      尺寸宏定义                                       */
/************************************************************************/

#define SQ_SIZE			30							//方块的尺寸为30*30
#define SQ_ARC_SIZE		(SQ_SIZE/4)					//方块四角弧
#define SQ_POOL_SIZE_X  (SQ_SIZE*SQ_POOL_CY)			//方块池的尺寸
#define SQ_POOL_SIZE_Y  (SQ_SIZE*SQ_POOL_CX)

#define SQ_INTERVAL_SIZE (SQ_SIZE/2)				//信息框之间的间隔尺寸

#define SQ_NEXT_BOX_X	(SQ_SIZE*5)					//下一个方块框尺寸
#define SQ_NEXT_BOX_Y	(SQ_SIZE*6)

#define SQ_SCORE_BOX_X	SQ_NEXT_BOX_X				//分数框尺寸
#define SQ_SCORE_BOX_Y  SQ_SCORE_BOX_X			

#define SQ_EXPLAIN_BOX_X SQ_NEXT_BOX_X				//操作说明框尺寸
#define SQ_EXPLAIN_BOX_Y (SQ_SIZE*4)

#define SQ_MESSAGE_BOX_X SQ_NEXT_BOX_X				//其它信息框尺寸
#define SQ_MESSAGE_BOX_Y (SQ_SIZE*2)

//#define MENU_SIDE			20						//菜单每项边框线长()

#define WINDOW_SIZE_X   (SQ_POOL_SIZE_X+SQ_SIZE*4+SQ_NEXT_BOX_X)		//窗口总尺寸
#define WINDOW_SIZE_Y   (SQ_POOL_SIZE_Y+SQ_SIZE*2)

#define MENU_BOX_SIZE_X (SQ_POOL_SIZE_X/5*4)		//菜单框尺寸
#define MENU_BOX_SIZE_Y (WINDOW_SIZE_Y/6*4)

#define PAUSE_BOX_SIZE_X (SQ_POOL_SIZE_X - SQ_SIZE)				//暂停框尺寸
#define PAUSE_BOX_SIZE_Y (SQ_SIZE*5)

#define OVER_BOX_SIZE_X  (SQ_POOL_SIZE_X/5*4)		//结束框
#define OVER_BOX_SIZE_Y  (SQ_POOL_SIZE_X/4*3)

//////////////////////////////////////////////////////////////////////////
/************************************************************************/
/*							界面框架函数声明                             */
/************************************************************************/

static VOID Main_Interface (HDC);		//主界面绘制
static VOID Menu_Box	   (HDC);		//菜单框
static VOID Pause_Box      (HDC);		//暂停框
static VOID Over_Box       (HDC);		//结束框

static VOID Draw_Menu_Side	   (HDC);		//绘制
static VOID Draw_SQ_D		   (HDC, RECT);	//绘制单个方块

static VOID Update_Data        (HDC);					//更新分数及方块个数
static VOID Comb_Rect		   (PRECT, RECT);			//合并两个矩形
static VOID SQ_Rect_Box        (PRECT, PRECT);			//给出方块,计算出占用最大矩形
static VOID Draw_SQ			   (HDC, POINT);	        //绘制方块
static VOID Inval_Ass_SQ       (HWND, POINT);			//使得辅助方块无效

//////////////////////////////////////////////////////////////////////////
/************************************************************************/
/*                          全局变量声明                                 */
/************************************************************************/

static enum {MAIN, MENU, PAUSE, OVER} InterFlag;			//标记当前界面
static enum {ID_1, ID_2, ID_Main} MenuID;
static RECT   MenuRect[OVER+1][ID_Main+1];					//所有菜单项矩形

//static REC;										//菜单边框尺寸
static   RECT            DataRt[3];					//保存需要更新的数据框
static   HBRUSH			 MainhBr;					//主画刷

//////////////////////////////////////////////////////////////////////////

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

INT WINAPI WinMain (HINSTANCE hIns, HINSTANCE hPre, PSTR szCmdLine, INT iCmdShow)
{
	PTCHAR		  pName = _T("Square");
	HWND		  hwnd;
	MSG			  msg;
	WNDCLASS	  wlass;

	ZeroMemory (&wlass, sizeof (WNDCLASS));

	wlass.style				= CS_HREDRAW | CS_VREDRAW;
	wlass.lpfnWndProc		= WndProc;
	wlass.hInstance			= hIns;
	wlass.hIcon				= LoadIcon   (hIns, _T("翼"));
	wlass.hCursor			= LoadCursor (NULL, IDC_ARROW);
	wlass.hbrBackground		= (HBRUSH) GetStockObject (BLACK_BRUSH);
	wlass.lpszClassName		= pName;

	if (!RegisterClass (&wlass))
	{
		MessageBox (NULL, _T("注册窗口失败!"), pName, MB_ICONERROR);
		return 0;
	}

	hwnd = CreateWindow (pName, _T("翼_【俄罗斯方块】"), 
						WS_POPUPWINDOW | WS_VISIBLE,
						CW_USEDEFAULT, CW_USEDEFAULT,
						CW_USEDEFAULT, CW_USEDEFAULT,
						NULL, NULL, hIns, NULL);

	ShowWindow (hwnd, iCmdShow);
	UpdateWindow (hwnd);

	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg);
		DispatchMessage  (&msg);
	}

	return msg.wParam;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT ms, WPARAM wParam, LPARAM lParam)
{
	static POINT			 wop, nwop;			//窗口在屏幕上的坐标
	HDC						 hdc;
	PAINTSTRUCT				 ps;
	HBRUSH					 hbr;
	static    POINT          ExPoint;			//方块运行主控制

	switch (ms)
	{
		case WM_CREATE:
			Initialization_SQ_   (SQ_SIZE, SQ_SIZE);		//初始化方块数据
			Get_SQ_Pool_ConCoord (&ExPoint);
			MainhBr = Get_SQ_CurrentHBrush();

			InterFlag = MENU;
			MenuID    = ID_1;

			wop.x = (GetSystemMetrics (SM_CXSCREEN) - WINDOW_SIZE_X)/2;
			wop.y = (GetSystemMetrics (SM_CYSCREEN) - WINDOW_SIZE_Y)/2;

			MoveWindow (hwnd, wop.x, wop.y, WINDOW_SIZE_X, WINDOW_SIZE_Y, FALSE);

			return 0;

		case WM_LBUTTONDOWN:
			nwop.x = LOWORD (lParam);			
			nwop.y = HIWORD (lParam);

			break;

		case WM_MOUSEMOVE:						//鼠标拖动窗口
			if (wParam == MK_LBUTTON)
			{
				POINT  po = {LOWORD (lParam) - nwop.x, HIWORD (lParam) - nwop.y};

				wop.x += po.x;
				wop.y += po.y;

				MoveWindow (hwnd, wop.x, wop.y, WINDOW_SIZE_X, WINDOW_SIZE_Y, TRUE);
			}
			break;

		case WM_PAINT:									//绘制
			hdc = BeginPaint (hwnd, &ps);
			hbr = (HBRUSH) SelectObject (hdc, MainhBr);

			Main_Interface     (hdc);
			Traverse_SQ_Pool   (SQ_POOL_CX-1, hdc, Draw_SQ_D);

			switch (InterFlag)
			{
				case MAIN:							//游戏界面
					Draw_SQ (hdc, ExPoint);
					break;

				case MENU:							//菜单界面
					Menu_Box	   (hdc);
					Draw_Menu_Side (hdc);
					break;

				case PAUSE:							//暂停界面
					Pause_Box    (hdc);
					break;

				case OVER:							//结束界面
					Over_Box       (hdc);
					Draw_Menu_Side (hdc);
					break;
			}

			Update_Data  (hdc);				//必要数据
			SelectObject (hdc, hbr);
			EndPaint     (hwnd, &ps);
			return 0;

		case WM_KEYDOWN:
			switch (wParam)
			{
				case VK_UP:
				case VK_DOWN:
					switch (InterFlag)
					{
						case MENU:
							{
								RECT  rc;

								CopyRect    (&rc, &MenuRect[MENU][MenuID]);
								InflateRect (&rc, 5, 5);

								MenuID = (MenuID == ID_1)? ID_2:ID_1;

								InvalidateRect (hwnd, &rc, FALSE);

								CopyRect       (&rc, &MenuRect[MENU][MenuID]);
								InflateRect    (&rc, 5, 5);
								InvalidateRect (hwnd, &rc, FALSE);
								UpdateWindow   (hwnd);
							}
							break;

						case MAIN:									//上下操作
							{
								RECT  Ort[4], Nrt[4], or, nr;

								GetClient_SQ_Coord (Ort, ExPoint);
								SQ_Rect_Box        (Ort, &or);

								if (wParam == VK_UP)
								{ 
									if (Switch_SQ_Form (Nrt, ExPoint))		//切换形态
									{
										SQ_Rect_Box (Nrt, &nr);
										Comb_Rect   (&nr, or);

										Inval_Ass_SQ (hwnd, ExPoint);
									}
									else break;
								}
								else{
									if (Judge_SQ_Move (ExPoint.x, ExPoint.y +1))
									{
										++ExPoint.y;
										GetClient_SQ_Coord (Nrt, ExPoint);
										SQ_Rect_Box        (Nrt, &nr);
										Comb_Rect		   (&nr, or);		//合并
									}
									else{									//落底
										if (Judge_Game_Over (ExPoint))
										{
											InterFlag = OVER;
											MenuID    = ID_1;

											Save_Score ();					//保存最高分
											CopyRect   (&nr, &MenuRect[MAIN][ID_Main]);
										}
										else{
											INT    li = Judge_SQ_Dele (&nr, ExPoint), i;
											
											SetTimer (hwnd, SQ_TIMER_1, SLEEP_TIMER, NULL);	   //恢复速度

											Get_SQ_Pool_ConCoord (&ExPoint);

											for (i=0; i<2; i++)									
												InvalidateRect (hwnd, &DataRt[i], TRUE);	 //更新数据框

											GetClient_SQ_Coord (Ort, ExPoint);
											SQ_Rect_Box        (Ort, &or);
											InvalidateRect     (hwnd, &or, FALSE);
											Inval_Ass_SQ       (hwnd, ExPoint);

											if (li)											//删除满行
											{
												OffsetRect (&nr, SQ_SIZE, SQ_SIZE);		
												CopyRect   (&or, &nr);
											}
											else{
												UpdateWindow   (hwnd);
												break;
											}
										}
									}
								}

								InvalidateRect (hwnd, &nr, TRUE);
								UpdateWindow   (hwnd);
							}
							break;
					}
					break;

				case VK_LEFT:		//左
				case VK_RIGHT:
					{
						if (Judge_SQ_Move ((wParam == VK_LEFT? ExPoint.x -1 : ExPoint.x +1), ExPoint.y))
						{
							RECT  Nrt[4], or, nr;

							GetClient_SQ_Coord (Nrt, ExPoint);				//原位
							SQ_Rect_Box        (Nrt, &or);

							wParam == VK_LEFT? --ExPoint.x : ++ExPoint.x;

							GetClient_SQ_Coord (Nrt, ExPoint);				//新位
							SQ_Rect_Box        (Nrt, &nr);
							Comb_Rect		   (&nr, or);					//合并

							Inval_Ass_SQ       (hwnd, ExPoint);
							InvalidateRect     (hwnd, &nr, TRUE);
							UpdateWindow       (hwnd);
						}
					}
					break;

				case VK_RETURN:					//回车
					switch (InterFlag)
					{
						case MENU:				//主菜单
							switch (MenuID)
							{
								case ID_1:					//开始游戏
								//		InterFlag = MAIN;
								break;
	
								case ID_2:					//退出游戏
									SendMessage (hwnd, WM_CLOSE, 0, 0);
									return 0;
							}
							break;

						case OVER:			//游戏结束
							Initialization_SQ_   (SQ_SIZE, SQ_SIZE);	
							Get_SQ_Pool_ConCoord (&ExPoint);

							InvalidateRect (hwnd, &DataRt[0], TRUE);
							InvalidateRect (hwnd, &DataRt[1], TRUE);
							break;

						case MAIN:
							SetTimer (hwnd, SQ_TIMER_1, SLEEP_TIMER_1, NULL);
							

						default:
							return 0;
					}

					InterFlag = MAIN;
					InvalidateRect (hwnd, &MenuRect[MAIN][ID_Main], TRUE);
					UpdateWindow   (hwnd);

					SetTimer (hwnd, SQ_TIMER_1, SLEEP_TIMER, NULL);
					break;

				case VK_SPACE:					//空格
					switch (InterFlag)
					{
						case MAIN:
							InterFlag = PAUSE;
							KillTimer      (hwnd, SQ_TIMER_1);
							InvalidateRect (hwnd, NULL, FALSE);
							UpdateWindow   (hwnd);
							break;

						case PAUSE:
							InterFlag = MAIN;
							SetTimer       (hwnd, SQ_TIMER_1, SLEEP_TIMER, NULL);
							InvalidateRect (hwnd, &MenuRect[PAUSE][ID_Main], TRUE);
							UpdateWindow   (hwnd);
							break;
					}
					break;

				case VK_TAB:			//TAB
					if (InterFlag == OVER || (MessageBeep (MB_ICONEXCLAMATION), IDYES == MessageBox (hwnd, _T("确定返回菜单将当前得分清除?"),_T("俄罗斯方块"), 0x20L | MB_YESNO)))
					{
						InterFlag = MENU;
						MenuID    = ID_1;				//返回菜单初始化数据

						Initialization_SQ_   (SQ_SIZE, SQ_SIZE);		
						Get_SQ_Pool_ConCoord (&ExPoint);

						InvalidateRect (hwnd, &DataRt[0], TRUE);
						InvalidateRect (hwnd, &DataRt[1], TRUE);
						InvalidateRect (hwnd, &MenuRect[MAIN][ID_Main], TRUE);
						UpdateWindow   (hwnd);
					}
					break;
			}
			break;

		case WM_KEYUP:
			{
				switch (wParam)
				{
					case VK_ESCAPE:
						SendMessage (hwnd, WM_CLOSE, 0, 0);
						break;
				}
			}
			break;

		case WM_ACTIVATEAPP:
			if (InterFlag == MAIN)
				SendMessage (hwnd, WM_KEYDOWN, (WPARAM) VK_SPACE, 0);
			break;

		case WM_TIMER:
			switch (wParam)
			{
				case SQ_TIMER_1:
					if (InterFlag == MAIN)
						SendMessage (hwnd, WM_KEYDOWN, (WPARAM) VK_DOWN, 0);
					else
						KillTimer (hwnd, SQ_TIMER_1);
					break;
			}
			break;

		case WM_CLOSE:
			MessageBeep (MB_ICONEXCLAMATION);
			if (IDYES != MessageBox (hwnd, _T("确定要退出吗?"),_T("俄罗斯方块"), 0x20L | MB_YESNO))
				return 0;

		case WM_DESTROY:
			KillTimer       (hwnd, SQ_TIMER_1);
			Delete_SQ_Data  ();			//删除初始化方块时所创建信息
			PostQuitMessage (0);
			return 0;
	}

	return DefWindowProc (hwnd, ms, wParam, lParam);
}

//////////////////////////////////////////////////////////////////////////
/************************************************************************/
/*                      函数定义                                         */
/************************************************************************/
//主界面
VOID Main_Interface	(HDC hdc)
{
	INT		 in[] = {0, SQ_SIZE + SQ_POOL_SIZE_X, WINDOW_SIZE_X - SQ_SIZE}, 
			arc[] = {SQ_ARC_SIZE*SQ_ARC_SIZE, SQ_ARC_SIZE*2}, x, y;
	HBRUSH   hbr;
	RECT     rt;
	PTCHAR   pstr[] = {
						_T("-- 下一个 --"),

						_T("\n分数:\n\n方块数:"),

						_T(" 操作说明 "),
						_T("回车:快速下落\n\
						Esc :退出\n\
						空格:暂停\n\
						Tab :返回菜单"),

						_T("制作人:_翼_\n交流群:234056226\n^_^代码在群共享^_^")
	};
	HFONT  font[2], ofont;

	font[0] = CreateFont (30, 10, 0, 0, FW_BOLD, 0, 1, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);
	font[1] = CreateFont (19, 8, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);

	for (x=0; x<WINDOW_SIZE_Y; x += WINDOW_SIZE_Y - SQ_SIZE)
	{
		for (y=0; y<WINDOW_SIZE_X; y += SQ_SIZE)
		{
			RoundRect (hdc, y, x, y+SQ_SIZE, x+SQ_SIZE, SQ_ARC_SIZE, SQ_ARC_SIZE);
		}
	}

	for (x=0; x<3; x++)
	{
		for (y=SQ_SIZE; y<WINDOW_SIZE_Y; y += SQ_SIZE)
		{
			RoundRect (hdc, in[x], y, in[x]+SQ_SIZE, y+SQ_SIZE, SQ_ARC_SIZE, SQ_ARC_SIZE);
		}
	}

	rt.left   = rt.top = SQ_SIZE;						//方块池边框
	rt.right  = rt.left + SQ_POOL_SIZE_X;
	rt.bottom = rt.top + SQ_POOL_SIZE_Y;
	InflateRect (&rt, 1, 1);
	FrameRect (hdc, &rt, MainhBr);
	CopyRect  (&MenuRect[MAIN][ID_Main], &rt);
														//浅灰色画刷
	hbr = (HBRUSH) SelectObject (hdc, GetStockObject (LTGRAY_BRUSH));

	rt.left = (x = WINDOW_SIZE_X - SQ_NEXT_BOX_X - SQ_SIZE*2 + SQ_INTERVAL_SIZE) +3;

	y = SQ_SIZE + SQ_INTERVAL_SIZE/2;					
	RoundRect (hdc, x, y, rt.right = SQ_NEXT_BOX_X + x, rt.bottom = SQ_NEXT_BOX_Y + y, arc[0], arc[1]);

	ofont = (HFONT) SelectObject (hdc, font[0]);			//输出“下一个”文本
	SetTextColor (hdc, RGB(200, 0, 255));
	SetBkMode    (hdc, TRANSPARENT);

	CopyRect (&DataRt[0], &rt);		//更新区域

	rt.top = SQ_NEXT_BOX_Y;
	DataRt[0].bottom = rt.top;
	DrawText (hdc, pstr[0], _tcslen (pstr[0]), &rt, DT_CENTER | DT_VCENTER);

	rt.top =  y += SQ_NEXT_BOX_Y + SQ_INTERVAL_SIZE/2;
	RoundRect (hdc, x, y, rt.right = SQ_SCORE_BOX_X + x, rt.bottom = SQ_SCORE_BOX_Y + y, arc[0], arc[1]);
	DrawText  (hdc, pstr[1], _tcslen (pstr[1]), &rt, DT_LEFT | DT_VCENTER);	//输出

	rt.top =  (y += SQ_SCORE_BOX_Y + SQ_INTERVAL_SIZE/2);
	RoundRect (hdc, x, y, rt.right = SQ_EXPLAIN_BOX_X + x, rt.bottom = SQ_EXPLAIN_BOX_Y + y, arc[0], arc[1]);
	DrawText  (hdc, pstr[2], _tcslen (pstr[2]), &rt, DT_CENTER | DT_VCENTER);

	SelectObject (hdc, font[1]);
	SetTextColor (hdc, RGB(100,10,50));
	rt.top += SQ_SIZE +5;
	DrawText  (hdc, pstr[3], _tcslen (pstr[3]), &rt, DT_LEFT| DT_VCENTER);

	rt.top = y += SQ_EXPLAIN_BOX_Y + SQ_INTERVAL_SIZE/2;
	RoundRect (hdc, x, y, rt.right = SQ_MESSAGE_BOX_X + x, rt.bottom = SQ_MESSAGE_BOX_Y + y, arc[0], arc[1]);
	DrawText  (hdc, pstr[4], _tcslen (pstr[4]), &rt, DT_CENTER | DT_VCENTER);

	DeleteObject (font[0]);
	DeleteObject (font[1]);
	SelectObject (hdc, ofont);
	SelectObject (hdc, hbr);

//	Update_Data (hdc);	//更新数据
}

//菜单框
VOID Menu_Box (HDC hdc)
{
	HFONT   hfont, ohf;
	INT     hfx = 20, hfy = hfx*3;
	PTCHAR   str[] = {
						_T("俄罗斯方块\n(基础版)"),
						_T("开 始 游 戏"),
						_T("退 出 游 戏")
	};
	RECT   rc = {
					SQ_SIZE + SQ_POOL_SIZE_X/5/2,
					WINDOW_SIZE_Y/6,
					MENU_BOX_SIZE_X, MENU_BOX_SIZE_Y
	};

	rc.right  += rc.left;
	rc.bottom += rc.top;

	CopyRect (&MenuRect[MENU][ID_Main], &rc);			//保存以便使用

	hfont = CreateFont (hfy, hfx, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);
	ohf   = (HFONT)SelectObject (hdc, hfont);
	SetTextColor (hdc, RGB (0,0,0));
	RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom, MENU_BOX_SIZE_X/2, MENU_BOX_SIZE_Y/5);
	rc.top   += 15;

	DrawText (hdc, str[0], _tcslen (str[0]), &rc, DT_CENTER | DT_VCENTER);
	
	DeleteObject (hfont);
	hfont = CreateFont (30, 10, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);
	SelectObject (hdc, hfont);
	SetTextColor (hdc, RGB (255,255,255));

	MenuRect[MENU][0].left   = rc.left + MENU_BOX_SIZE_X/2 - 60;		//计算开始游戏坐标
	MenuRect[MENU][0].top    = rc.top + SQ_SIZE*5;
	MenuRect[MENU][0].right  = MenuRect[MENU][0].left + 120;
	MenuRect[MENU][0].bottom = MenuRect[MENU][0].top + 30;

	CopyRect (&MenuRect[MENU][1], &MenuRect[MENU][0]);
	MenuRect[MENU][1].top    += SQ_SIZE *2;
	MenuRect[MENU][1].bottom += SQ_SIZE *2;

	for (hfx=0; hfx<2; hfx++)
	{
//		FrameRect (hdc, &MenuRect[MENU][hfx], (HBRUSH)GetStockObject (BLACK_BRUSH));
		DrawText  (hdc, str[hfx+1], _tcslen (str[hfx+1]), &MenuRect[MENU][hfx], DT_CENTER | DT_VCENTER);
	}

	SelectObject (hdc, ohf);
	DeleteObject (hfont);
}

//暂停框
VOID Pause_Box (HDC hdc)
{
	HFONT   hfont, ohf;
	PTCHAR  pstr[] = {
					_T("暂停中......"),
					_T("\n\n\n\n╮(╯3╰)╭按回车继续╮(╯3╰)╭")
	};

	hfont = CreateFont   (50, 20, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);
	ohf   = (HFONT)SelectObject (hdc, hfont);
	SetTextColor (hdc, RGB (0,200,100));

	MenuRect[PAUSE][ID_Main].left   = SQ_SIZE + (SQ_POOL_SIZE_X - PAUSE_BOX_SIZE_X)/2;
	MenuRect[PAUSE][ID_Main].top    = (WINDOW_SIZE_Y - PAUSE_BOX_SIZE_Y) /2;
	MenuRect[PAUSE][ID_Main].right  = MenuRect[PAUSE][ID_Main].left + PAUSE_BOX_SIZE_X;
	MenuRect[PAUSE][ID_Main].bottom = MenuRect[PAUSE][ID_Main].top + PAUSE_BOX_SIZE_Y;

//	FrameRect (hdc, &MenuRect[PAUSE][ID_1], (HBRUSH)GetStockObject (WHITE_BRUSH));
	DrawText  (hdc, pstr[0], _tcslen (pstr[0]), &MenuRect[PAUSE][ID_Main], DT_CENTER | DT_VCENTER);

	hfont = CreateFont (20, 7, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);
	DeleteObject (SelectObject (hdc, hfont));
	SetTextColor (hdc, RGB (255,255,255));
	DrawText  (hdc, pstr[1], _tcslen (pstr[1]), &MenuRect[PAUSE][ID_Main], DT_CENTER | DT_VCENTER);

	DeleteObject (SelectObject (hdc, ohf));

}

//结束框
VOID Over_Box (HDC hdc)
{
	HFONT   nfo, ofo;
	PTCHAR  pstr[] = {
						_T("恭喜!┈━═☆\n您的分数已载入史记!"),
						_T("还差点继续加油吧!"),
						_T("历史最高分:	%d\n您的得分:	%d"),
						_T("重新开始")
	};
	TCHAR  Scr[100];
	INT    hfx = 30, Nsc = Get_SQ_Scoring (), Osc = Get_SQ_Histroy_Score ();
	RECT   rt;

	MenuRect[OVER][ID_Main].left   = SQ_SIZE + (SQ_POOL_SIZE_X - OVER_BOX_SIZE_X)/2;		//计算出外矩形
	MenuRect[OVER][ID_Main].top    = (WINDOW_SIZE_Y - OVER_BOX_SIZE_Y)/2;
	MenuRect[OVER][ID_Main].right  = MenuRect[OVER][ID_Main].left + OVER_BOX_SIZE_X;
	MenuRect[OVER][ID_Main].bottom = MenuRect[OVER][ID_Main].top + OVER_BOX_SIZE_Y;

	RoundRect (hdc, MenuRect[OVER][ID_Main].left, MenuRect[OVER][ID_Main].top, MenuRect[OVER][ID_Main].right, MenuRect[OVER][ID_Main].bottom, SQ_SIZE*2, SQ_SIZE);

	nfo = CreateFont (hfx, hfx/3, 0, 0, FW_BOLD, 0, 1, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);
	ofo = (HFONT) SelectObject (hdc, nfo);
	SetTextColor (hdc, RGB (0, 0, 0));
	CopyRect (&rt, &MenuRect[OVER][ID_Main]);

	rt.top    += SQ_INTERVAL_SIZE;
	rt.bottom -= SQ_SIZE*2;
	DrawText (hdc, Nsc > Osc?pstr[0]:pstr[1], _tcslen (Nsc > Osc?pstr[0]:pstr[1]), &rt, DT_CENTER | DT_VCENTER);	//输出标题

	CopyRect (&MenuRect[OVER][ID_1], &MenuRect[OVER][ID_Main]);
	MenuRect[OVER][ID_1].left += OVER_BOX_SIZE_X/2 - (hfx*2);		//计算出选项矩形
	MenuRect[OVER][ID_1].top  += OVER_BOX_SIZE_Y - SQ_SIZE - hfx;
	MenuRect[OVER][ID_1].right = MenuRect[OVER][ID_1].left + 4*hfx;
	MenuRect[OVER][ID_1].bottom = MenuRect[OVER][ID_1].top + hfx;

	DrawText  (hdc, pstr[3], _tcslen (pstr[3]), &MenuRect[OVER][ID_1], DT_CENTER | DT_VCENTER);		//输出菜单项

	nfo = CreateFont (hfx, hfx/3, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);
	DeleteObject (SelectObject (hdc, nfo));
	SetTextColor (hdc, RGB (255, 255, 255));

	rt.top += hfx + SQ_SIZE +5;
	wsprintf (Scr, pstr[2], Osc, Nsc);
	DrawText (hdc, Scr, _tcslen (Scr), &rt, DT_CENTER | DT_VCENTER);

	DeleteObject (SelectObject (hdc, ofo));
}

//菜单线条
VOID Draw_Menu_Side (HDC hdc)
{
	RECT		  rc;

	CopyRect (&rc, &MenuRect[InterFlag][MenuID]);
	InflateRect (&rc, 5, 5);

//	FrameRect (hdc, &rc, (HBRUSH)GetStockObject (BLACK_BRUSH));
	DrawFocusRect (hdc, &rc);
}

//绘制单个方块
VOID Draw_SQ_D (HDC hdc, RECT rc)
{
	RoundRect (hdc, rc.left + SQ_SIZE, rc.top + SQ_SIZE, rc.right + SQ_SIZE, rc.bottom + SQ_SIZE, SQ_ARC_SIZE, SQ_ARC_SIZE);
}

//更新数据
VOID Update_Data (HDC hdc)
{
	HFONT    nfont, ofont;
	TCHAR    str[50];
	POINT    point    = {12, 0};
	RECT     nextSQ[4];
	INT      i, Xmax = 0, Xmin = INT_MAX, Ymax = 0, Ymin = INT_MAX, OffX, OffY;
	HBRUSH   hbr     = (HBRUSH) SelectObject (hdc, Get_SQ_NextHbrush ());				//使用属于方块的画刷

	GetClient_SQ_Next_Coord (nextSQ, point);										//使下一个方块居中显示
	for (i=0; i<4; i++)
	{
		Xmin = min (nextSQ[i].left,  Xmin);
		Xmax = max (nextSQ[i].right, Xmax);

		Ymin = min (nextSQ[i].top,    Ymin);
		Ymax = max (nextSQ[i].bottom, Ymax);
	}
	OffX = (SQ_NEXT_BOX_X - (Xmax - Xmin))/2 + SQ_INTERVAL_SIZE;
	OffY = (SQ_NEXT_BOX_Y - (Ymax - Ymin) - SQ_SIZE)/2 + SQ_INTERVAL_SIZE/2;

	if ((Xmax - Xmin) == SQ_SIZE)				
		OffX -= SQ_SIZE;

	for (i=0; i<4; i++)
	{
		OffsetRect (&nextSQ[i], OffX, OffY);
		Draw_SQ_D  (hdc, nextSQ[i]);
	}
	SelectObject (hdc, hbr);														//////////////

	if (!DataRt[1].left)
	{
		DataRt[1].left   = WINDOW_SIZE_X - SQ_SIZE *4 - SQ_INTERVAL_SIZE;
		DataRt[1].top    = SQ_SIZE*2 + SQ_NEXT_BOX_Y + SQ_INTERVAL_SIZE;
		DataRt[1].right  = WINDOW_SIZE_X - SQ_SIZE - SQ_INTERVAL_SIZE;
		DataRt[1].bottom = DataRt[1].top + SQ_SIZE*3;
	}

	wsprintf (str,_T("%d\n\n%d"), Get_SQ_Scoring(), Get_Pool_SQ_Number());

	nfont = CreateFont (30, 15, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, NULL);
	ofont = (HFONT)SelectObject (hdc, nfont);
	SetTextColor (hdc, RGB (255, 0, 0));

	DrawText (hdc, str, _tcslen (str), &DataRt[1], DT_CENTER | DT_VCENTER);

	SelectObject (hdc, ofont);
	DeleteObject (nfont);
}

//计算方块矩形
VOID SQ_Rect_Box (PRECT SQprc, PRECT prc)
{
	INT     i;

	SetRect (prc, INT_MAX, INT_MAX, 0, 0);

	for (i=0; i<4; i++, SQprc++)
	{
		prc->left   = min (prc->left,   SQprc->left);
		prc->top    = min (prc->top,    SQprc->top);
		prc->right  = max (prc->right,  SQprc->right);
		prc->bottom = max (prc->bottom, SQprc->bottom);
	}

	OffsetRect (prc, SQ_SIZE, SQ_SIZE);
	if (prc->top == 0)								//避免多余的重绘
		prc->top += SQ_SIZE;
}

//合并两个矩形
VOID Comb_Rect (PRECT  prt, RECT rt)
{
	prt->left    = min (prt->left, rt.left);
	prt->top     = min (prt->top, rt.top);
	prt->right   = max (prt->right, rt.right);
	prt->bottom  = max (prt->bottom, rt.bottom);
}

//绘制辅助方块
VOID Draw_SQ (HDC hdc, POINT point)
{
	RECT      rct[4];
	INT       i;
	HBRUSH    hbrush;

	GetClient_SQ_Coord (rct, point);

	hbrush = (HBRUSH) SelectObject (hdc, Get_SQ_CurrentHBrush ());
	for (i=0; i<4; i++)
	{
		if (rct[i].top >= 0)
			Draw_SQ_D  (hdc, rct[i]);
	}

	point.y = SQ_POOL_CX-1;				//辅助方块
	while (point.y >= 0)
	{
		if (Judge_SQ_Move (point.x, point.y))
		{
			HBRUSH  hbr = CreateHatchBrush (HS_DIAGCROSS, RGB(255, 255, 255));

			SelectObject (hdc, hbr);

			GetClient_SQ_Coord (rct, point);
			for (i=0; i<4; i++)
			{
				Draw_SQ_D (hdc, rct[i]);
			}

			SQ_Rect_Box (rct, &DataRt[2]);
			DeleteObject (hbr);

			break;
		}
		--point.y;
	}

	SelectObject (hdc, hbrush);
}

//使辅助方块无效
VOID Inval_Ass_SQ (HWND hwnd, POINT po)
{
	RECT  rt[4], or;

	for (po.y=SQ_POOL_CX-1; po.y >= 0; po.y--)
	{
		if (Judge_SQ_Move (po.x, po.y))
		{
			GetClient_SQ_Coord (rt, po);
			break;
		}
	}
	SQ_Rect_Box    (rt, &or);
	Comb_Rect      (&or, DataRt[2]);
	InvalidateRect (hwnd, &or, TRUE);
}

//////////////////////////////////////////////////////////////////////////


开源中国-程序员在线工具:Git代码托管 API文档大全(120+) JS在线编辑演示 二维码 更多»

发表评论 回到顶部 网友评论(14)

  • 1楼:痞子蔡 发表于 2015-06-27 13:31 回复此评论
    一眼看上去挺漂亮的,但是一看到那字体。。。我还以为写的是控制台程序。
  • 2楼:护士的小黄瓜 发表于 2015-06-27 14:35 回复此评论
    这是大一的课后作业吧
  • 3楼:Succeed丶翼 发表于 2015-06-27 15:07 回复此评论

    引用来自“LAJS”的评论

    这是大一的课后作业吧
    不是的,没有读过大学,只是爱好编程
  • 4楼:护士的小黄瓜 发表于 2015-06-27 17:11 回复此评论

    引用来自“LAJS”的评论

    这是大一的课后作业吧

    引用来自“Succeed丶翼”的评论

    不是的,没有读过大学,只是爱好编程
    想做win桌面app,看看孙鑫讲的mfc还不错,这个窗口的消息循环还是第一讲
  • 5楼:护士的小黄瓜 发表于 2015-06-27 17:11 回复此评论

    引用来自“LAJS”的评论

    这是大一的课后作业吧

    引用来自“Succeed丶翼”的评论

    不是的,没有读过大学,只是爱好编程
    想做win桌面app,看看孙鑫讲的mfc还不错,这个窗口的消息循环还是第一讲
  • 6楼:Succeed丶翼 发表于 2015-06-27 17:17 回复此评论

    引用来自“LAJS”的评论

    这是大一的课后作业吧

    引用来自“Succeed丶翼”的评论

    不是的,没有读过大学,只是爱好编程

    引用来自“LAJS”的评论

    想做win桌面app,看看孙鑫讲的mfc还不错,这个窗口的消息循环还是第一讲
    嗯嗯,好的,谢谢!
  • 7楼:Xiao_f 发表于 2015-06-27 17:32 回复此评论
    支持一下,学习win32API的意义很深远
  • 8楼:Raymin 发表于 2015-06-27 20:42 回复此评论

    引用来自“Xiao_f”的评论

    支持一下,学习win32API的意义很深远
    写的不错,也很有天赋,就是路走偏了。 还强调 WIN32纯GDI 看来已中毒不浅。 建议尽量掌握跨平台的技术,哪怕学学 QT 也好。 不要把自己绑死在一个私有平台上。 离了它,你什么都干不了,它完了,你也跟着完。
  • 9楼:Succeed丶翼 发表于 2015-06-27 21:12 回复此评论

    引用来自“Xiao_f”的评论

    支持一下,学习win32API的意义很深远

    引用来自“Raymin”的评论

    写的不错,也很有天赋,就是路走偏了。 还强调 WIN32纯GDI 看来已中毒不浅。 建议尽量掌握跨平台的技术,哪怕学学 QT 也好。 不要把自己绑死在一个私有平台上。 离了它,你什么都干不了,它完了,你也跟着完。
    多谢前辈!前辈说的是。我打算下一步学安卓了!
  • 10楼:Xiao_f 发表于 2015-06-28 01:18 回复此评论

    引用来自“Xiao_f”的评论

    支持一下,学习win32API的意义很深远

    引用来自“Raymin”的评论

    写的不错,也很有天赋,就是路走偏了。 还强调 WIN32纯GDI 看来已中毒不浅。 建议尽量掌握跨平台的技术,哪怕学学 QT 也好。 不要把自己绑死在一个私有平台上。 离了它,你什么都干不了,它完了,你也跟着完。

    引用来自“Succeed丶翼”的评论

    多谢前辈!前辈说的是。我打算下一步学安卓了!
    并不是能马上转换成生产力的技术才有意义,学习底层API可以让你深入理解一个操作系统,开阔眼界、发散思维,这对以后无论学习什么平台都是百益而无一害的,举个最简单的例子,研究过Windows GDI再用HTML5 Canvas简直易如反掌,比单纯学前端开发的根本不是在一个层面看待问题了
  • 11楼:Raymin 发表于 2015-06-28 12:40 回复此评论
    如果在学底层 API 的时候,不仅仅是想知道 API 接口的使用,而且想知道 API 的实现源码,就去学 Android, Linux, QT... 开源软件吧!私有软件是不会满足你的求知欲的。
  • 12楼:Succeed丶翼 发表于 2015-06-28 14:03 回复此评论

    引用来自“Xiao_f”的评论

    支持一下,学习win32API的意义很深远

    引用来自“Raymin”的评论

    写的不错,也很有天赋,就是路走偏了。 还强调 WIN32纯GDI 看来已中毒不浅。 建议尽量掌握跨平台的技术,哪怕学学 QT 也好。 不要把自己绑死在一个私有平台上。 离了它,你什么都干不了,它完了,你也跟着完。

    引用来自“Succeed丶翼”的评论

    多谢前辈!前辈说的是。我打算下一步学安卓了!

    引用来自“Xiao_f”的评论

    并不是能马上转换成生产力的技术才有意义,学习底层API可以让你深入理解一个操作系统,开阔眼界、发散思维,这对以后无论学习什么平台都是百益而无一害的,举个最简单的例子,研究过Windows GDI再用HTML5 Canvas简直易如反掌,比单纯学前端开发的根本不是在一个层面看待问题了
    我要学的东西还有很多,只能慢慢来了!谢谢你前辈!
  • 13楼:Succeed丶翼 发表于 2015-06-28 14:05 回复此评论

    引用来自“Raymin”的评论

    如果在学底层 API 的时候,不仅仅是想知道 API 接口的使用,而且想知道 API 的实现源码,就去学 Android, Linux, QT... 开源软件吧!私有软件是不会满足你的求知欲的。
    嗯嗯,正有这个打算!谢谢前辈!
  • 14楼:我爱阿牛 发表于 2016-09-11 09:37 回复此评论
    请问下这个完整的代码还有吗
开源从代码分享开始 分享代码