⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 move pic.cpp

📁 一个很好玩的品图游戏源码.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*==========================================================
		Move Pic.cpp -- A move-picture game with SDK
			Soft Zealot (R) Robin Hood, 2001						
	  SoftZealot@china.com		Soft_Zealot@china.com

	====================================================
	我正在学习SDK编程,尝试编写了一个小游戏,因为我讨厌
	一些无聊的编程问题,我喜欢有意思的编程工作 :)

	这个游戏完全是用SDK编写的,没有涉及MFC,其中打开图片
	的函数是Charles Petzold的《Windows程序设计》一书中的
	源代码,我只不过加上了注释,看懂了意思而已。其他的代
	码是我自己编写的,你可以任意使用其中的代码。

	欢迎大家和我讨论编程的问题,你可以在www.csdn.net的专
	家门诊的vc部分找到我,我的id是Soft_Zealot或者
	SoftZealot, :),不好意思,水平不够只好多注册几个。

	如果你发现了bug或者找到了任何能够改进程序性能或者任何
	能够使code更精炼的方法,请你通知我,我会很高兴能够更
	加完善这个游戏。

	====================================================
	有待完成:
	1.胜利时通知游戏者游戏时间
	3.可不可以找到寻找最佳解的算法
	4.如何加入预览功能,可不可以采用类似Splash方法

	====================================================
	bugs :
	1.显示图片后每个Static控件排列不整齐
	2.由于对图像处理和windows底层工作原理还不是很清楚,所
	以有可能会有内存泄漏
==========================================================*/

#include <windows.h>
#include <commdlg.h>
#include <time.h>

#include "Move Pic.h"
#include "resource.h"

/*==========================================================
					应用程序入口函数
==========================================================*/
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
					PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szMenuName[] = TEXT ("MainMenu") ;
	HWND         hwnd ;
	MSG          msg ;
	WNDCLASS     wndclass ;
	
	// save the application's HINSTANCE
	hInst = hInstance ;

	wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc   = WndProc ;		// WndProc !!! here
	wndclass.cbClsExtra    = 0 ;
	wndclass.cbWndExtra    = 0 ;
	wndclass.hInstance     = hInstance ;
	wndclass.hIcon         = LoadIcon (hInstance, "AppIcon") ;	// how to load self-cus icon
	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH) ;
	wndclass.lpszMenuName  = szMenuName ;
	wndclass.lpszClassName = szAppName ;
	
	if (!RegisterClass (&wndclass))
	{
		MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
					szAppName, MB_ICONERROR) ;
		return 0 ;
	}
	
	// Caculate the window's size and position, I don't like huge_window :-)
	int cxWindow, cyWindow;
	cxWindow = GetSystemMetrics (SM_CXSCREEN) / 3;
	cyWindow = GetSystemMetrics (SM_CYSCREEN) / 3;
	
	hwnd = CreateWindow (szAppName,						// window class name
						TEXT ("奇幻拼图  Soft Zealot"),	// window caption
						WS_OVERLAPPEDWINDOW,			// window style
						cxWindow,						// initial x position
						cyWindow,						// initial y position
						cxWindow,						// initial x size
						cyWindow,						// initial y size
						NULL,							// parent window handle
						NULL,							// window menu handle
						hInstance,						// program instance handle
						NULL) ;							// creation parameters
	
	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;
	
	// message WM_QUIT cause function GetMessage return 0
	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
	
	return msg.wParam ;
}


/*==========================================================
						窗口函数
==========================================================*/
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HMENU			hMenu ;
	static HWND				hwndPic_Button[4][4] ;
	static int				iStcPos[4][4], iStcPosSave[4][4] ;
	static HBITMAP			hBitmap, hBmpStc ;
	static int				cxClient, cyClient ;
	static int				i, j ;
	static int				idStcClk, idStcBlank ;
	static OPENFILENAME		ofn ;
	static bool				bWinFlag ;
	BITMAP					bitmap ;
	HDC						hdc, hdcMem, hdcStc ;
	PAINTSTRUCT				ps ;
	RECT					rcClient, rcWin ;
	int						iStcClkPos, iStcBlankPos ;
	int						cxScr, cyScr ;
	float					fcxDiv, fcyDiv, fDiv ;

	switch (message)
	{
	case WM_CREATE:
		InitOfnStruct (ofn, hwnd) ;
		// create statics who hold pic
		for (i = 0; i < 4; i++)
			for (j = 0; j < 4; j++)
			{
				hwndPic_Button[i][j] = 
					CreateWindow (TEXT ("Static"), NULL,
								WS_CHILD | WS_VISIBLE | SS_NOTIFY | SS_BITMAP | SS_SUNKEN,
								0, 0, 0, 0,
								hwnd, (HMENU) (4 * i + j), hInst, NULL) ;
				iStcPos[i][j] = 4 * i + j ;
			}

		// 使static控件不能接收mouse点击消息
		bWinFlag = true ;

		// 开始使reset菜单无效
		hMenu = GetMenu (hwnd) ;
		EnableMenuItem (hMenu, IDM_GAME_RESET, MF_GRAYED) ;
		
		return 0 ;

	case WM_SIZE:
		// get client area size
		cxClient = LOWORD (lParam);
		cyClient = HIWORD (lParam);

		// move the statics to the new center
		for (i = 0; i < 4; i++)
			for (j = 0; j < 4; j++)
			{
				MoveWindow (hwndPic_Button[i][j], 
							(iStcPos[i][j] % 4) * cxClient / 4,
							(iStcPos[i][j] / 4) * cyClient / 4,
							cxClient / 4, cyClient / 4, TRUE);
			}
	
	case WM_PAINT:
		hdc = BeginPaint (hwnd, &ps) ;
		
		EndPaint (hwnd, &ps) ;		
		return 0 ;

	// 处理菜单命令
	case WM_COMMAND:
		switch (LOWORD (wParam))
		{	
		case IDM_GAME_RESET:
			/*==================================================
			游戏复位:因为Static已经加载图像,窗口也得到调整,所
			以我们需要打开图像时,每个Static的位置,在这里恢复
			Static的位置就行了。如果以后加入计时功能,就需要复位
			开始时间。
			==================================================*/
			// 恢复初始Static位置信息
			for (i = 0; i < 4; i++)
				for (j = 0; j < 4; j++)
				{
					iStcPos[i][j] = iStcPosSave[i][j] ;
					// 移动Static控件回到初始位置
					MoveWindow (hwndPic_Button[i][j], 
							(iStcPos[i][j] % 4) * cxClient / 4,
							(iStcPos[i][j] / 4) * cyClient / 4,
							cxClient / 4, cyClient / 4, TRUE);
				}

			bWinFlag = false ;

			return 0 ;

        case IDM_PIC_OPEN:
			// 显示打开文件对话框
			if (!GetOpenFileName (&ofn))
				return 0 ;
			
			// 如果已经有一个DIB,删除它
			if (hBitmap)
			{
				DeleteObject (hBitmap) ;
				hBitmap = NULL ;
			}
			
			// 从DIB创建DDB
			SetCursor (LoadCursor (NULL, IDC_WAIT)) ;	// 使用漏斗指针
			ShowCursor (TRUE) ;
			
			hdc = GetDC (hwnd) ;
			hBitmap = CreateBitmapObjectFromDibFile (hdc, szFileName) ;
			ReleaseDC (hwnd, hdc) ;
			
			ShowCursor (FALSE) ;
			SetCursor (LoadCursor (NULL, IDC_ARROW)) ;	// 恢复箭头指针
			
			// 使客户区无效以便稍后重绘
			InvalidateRect (hwnd, NULL, TRUE) ;
			
			if (hBitmap == NULL)
			{
				// 如果不能载入DIB文件,显示错误消息
				MessageBox (hwnd, TEXT ("Cannot load DIB file"), 
							szAppName, MB_OK | MB_ICONEXCLAMATION) ;
			}
			else
			{
				/*==================================================
				在调整窗口大小之前随机安排Static控件的位置,以便调整
				窗口的时候也随机产生了Static的布局。注意分割后的图像
				仍然是按照顺序(id)分配给Static的,随机的只是位置。
				==================================================*/
				srand ( (unsigned int) time (NULL));	// for random seed

				int iRanA, iRanB ;
				for (i = 0; i < 32; i++)
				{
					// 得到 0 -- 16 之间的两个随机数
					iRanA = rand( ) % 16 ;
					do
					{
						iRanB = rand( ) % 16 ;
					}
					while (iRanA == iRanB);

					// 随机调整 Note: index = id   XXX[index] = pos
					iStcBlankPos = iStcPos[iRanA / 4][iRanA % 4] ;
					iStcPos[iRanA / 4][iRanA % 4] = iStcPos[iRanB / 4][iRanB % 4] ;
					iStcPos[iRanB / 4][iRanB % 4] = iStcBlankPos ;
				}

				// 保存开始状态
				for (i = 0; i < 4; i++)
					for (j = 0; j < 4; j++)
					{
						iStcPosSave[i][j] = iStcPos[i][j] ;

						MoveWindow (hwndPic_Button[i][j], 
							(iStcPos[i][j] % 4) * cxClient / 4,
							(iStcPos[i][j] / 4) * cyClient / 4,
							cxClient / 4, cyClient / 4, TRUE);
					}


				/*==================================================
								调整窗口大小以适应图像
				==================================================*/
				GetWindowRect (hwnd, &rcWin);
				GetClientRect (hwnd, &rcClient);

				GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -