控制台做完了,剩下的就是贴图了,简单的说。
本着共享源代码的思想,文章结尾我会赋上0.0----1.4版本的代码
(名字为Popstar的为构建完成的代码,名字为*1.0----*1.4的为构建过程代码)
东西有点多,我都不知道从哪点讲起。
创建项目工程的时候选Win32项目
然后看1.0版本,在WinMain中只写了一个函数
1 int WINAPI WinMain(HINSTANCE hInstance, //当前应用程序的实例句柄HANDLE 2 HINSTANCE hPrevInstance, //win32中不用了 3 LPSTR lpCmdLine, //命令行参数 4 int nCmdShow) //窗口显示的状态 5 { 6 g_hInstance = hInstance; 7 //创建窗口 8 //1、设计窗口类 9 WNDCLASSEX wndclassex; 10 wndclassex.cbClsExtra = 0; 11 wndclassex.cbSize = sizeof(WNDCLASSEX); 12 wndclassex.cbWndExtra = 0; 13 wndclassex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0,255,0));//CreateSolidBrush(RGB(0,255,0))可以替换为(5,6,7,8,^^^^) 14 wndclassex.hCursor = LoadCursor(NULL,IDC_ARROW/*箭头样式*/); 15 wndclassex.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));//载入ico图标 16 wndclassex.hIconSm = 0; 17 wndclassex.hInstance = hInstance; 18 wndclassex.lpfnWndProc = WndProc;//重要一点 19 wndclassex.lpszClassName = ClassName;//重要一点 20 wndclassex.lpszMenuName = 0;//菜单名 21 wndclassex.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; 22 //2、注册窗口类 23 RegisterClassEx(&wndclassex); 24 //3、根据设计的窗口类创建窗口 25 int nScreenCX = GetSystemMetrics(SM_CXSCREEN);//获取屏幕的宽高 26 int nScreenCY = GetSystemMetrics(SM_CYSCREEN); 27 HWND hwnd = (HWND)CreateWindowEx( 28 WS_EX_OVERLAPPEDWINDOW, 29 ClassName,L"PopStar", 30 WS_SYSMENU|WS_MINIMIZE, 31 (nScreenCX - WND_WIDTH)/2,//窗口的位置 32 (nScreenCY - WND_HEIGHT)/2, 33 WND_WIDTH,WND_HEIGHT,NULL,0,hInstance,0); 34 //4、显示创建好的窗口 35 ShowWindow(hwnd,nCmdShow); 36 //5、刷新窗口 37 UpdateWindow(hwnd); 38 //6、进入消息循环 39 MSG msg; 40 while(1) 41 { 42 if(PeekMessage(&msg,0,0,0,PM_REMOVE)) 43 { 44 if(msg.message == WM_QUIT) 45 { 46 break; 47 } 48 DispatchMessage(&msg); 49 } 50 else 51 { 52 g_currTime = GetTickCount(); 53 if(g_currTime - g_preTime > 60) 54 { 55 DrawGame(); 56 } 57 } 58 } 59 return 0; 60 61 }
用于创建窗口,是windows编程的主函数
定义了游戏状态
1 typedef enum game_state 2 { 3 GAME_READY, 4 GAME_START, 5 GAME_PAUSE, 6 GAME_OVER, 7 }enumGAME_STATE;
然后就是画整个游戏的状态
1 void DrawGame(void) 2 { 3 if(g_game_state == GAME_READY) 4 { 5 StickReadyPics(); 6 7 } 8 else if(g_game_state == GAME_START) 9 { 10 StickStartPics(); 11 12 } 13 14 BitBlt(g_hdc,0,0,WND_WIDTH,WND_HEIGHT, 15 g_hBuffer2,0,0,SRCCOPY); 16 //TransparentBlt(); 17 g_preTime = GetTickCount(); 18 19 }
再有就是回调函数
1 //回调函数---->用于处理消息:产生消息的时候自动调用 2 //所有的消息都要被这个函数处理,所以default不能省略 3 LRESULT _stdcall WndProc(HWND hwnd, 4 UINT message, 5 WPARAM wParam,//消息的附加参数 6 LPARAM lParam//消息的附加参数 7 ) 8 { 9 switch(message) 10 { 11 case WM_CREATE: 12 { 13 InitGame(hwnd); 14 break; 15 } 16 case WM_PAINT: 17 { 18 PAINTSTRUCT ps; 19 HDC hdc = BeginPaint(hwnd,&ps); 20 DrawGame(); 21 22 EndPaint(hwnd,&ps); 23 break; 24 } 25 case WM_DESTROY: 26 { 27 CleanGame(hwnd); 28 PostQuitMessage(0); 29 break; 30 } 31 case WM_LBUTTONDOWN: 32 { 33 OnBtnClick(LOWORD(lParam),HIWORD(lParam)); 34 break; 35 } 36 case WM_ERASEBKGND: 37 { 38 ; 39 } 40 break; 41 default: 42 { 43 return DefWindowProc(hwnd,message,wParam,lParam); 44 } 45 } 46 return 0; 47 }
用了双缓冲,不至于游戏卡屏
但是个人觉得CPU还是占用了50%,效率不高
1 void InitGame(HWND hwnd) 2 { 3 g_hdc = GetDC(hwnd);//设备环境---->绘图工具集 4 g_hBuffer1 = CreateCompatibleDC(g_hdc); 5 g_hBuffer2 = CreateCompatibleDC(g_hdc); 6 g_cptBitmap = CreateCompatibleBitmap(g_hdc,WND_WIDTH,WND_HEIGHT); 7 SelectObject(g_hBuffer2,g_cptBitmap); 8 //初始化位图 9 InitBitmap(); 10 11 //初始化数据对象 12 InitDataObj(); 13 //逻辑变量赋初值 14 g_game_state = GAME_READY; 15 }
接着处理鼠标单击事件
1 //看鼠标单击的位置是否位于相应的坐标范围内,如果在,就改变当前游戏的状态值 2 void OnBtnClick(int x,int y) 3 { 4 POINT pt = {x,y}; 5 RECT rect; 6 if(g_game_state == GAME_READY) 7 { 8 //游戏开始 9 rect.left = g_ready_btn_start._pos.x; 10 rect.top = g_ready_btn_start._pos.y; 11 rect.right = rect.left + g_ready_btn_start._size.cx; 12 rect.bottom = rect.top + g_ready_btn_start._size.cy; 13 if(PtInRect(&rect,pt)) 14 { 15 g_game_state = GAME_START; 16 } 17 //游戏退出 18 rect.left = g_ready_btn_exit._pos.x; 19 rect.top = g_ready_btn_exit._pos.y; 20 rect.right = rect.left + g_ready_btn_exit._size.cx; 21 rect.bottom = rect.top + g_ready_btn_exit._size.cy; 22 if(PtInRect(&rect,pt)) 23 { 24 PostQuitMessage(0); 25 } 26 27 } 28 else if(g_game_state == GAME_PAUSE) 29 { 30 31 } 32 else if(g_game_state == GAME_START) 33 { 34 //判断当前鼠标是否与星星位置触碰 35 for (int row = 0; row < ROW; row++) 36 { 37 for (int column = 0; column < COLUMN; column++) 38 { 39 rect.left = g_arrStars[row][column]._pos.x; 40 rect.top = g_arrStars[row][column]._pos.y; 41 rect.right = rect.left + g_arrStars[row][column]._size.cx; 42 rect.bottom = rect.top + g_arrStars[row][column]._size.cy; 43 if(PtInRect(&rect,pt)) 44 { 45 SelectStar(g_arrStars[row][column]); 46 //Beep(500,500); 47 } 48 } 49 } 50 } 51 }
至于载入图片,第一步就是先定义数据对象,第二步用LoadImage载入图片,第三步初始化数据对象
这样的一个基本窗口就构建好了,就相当于整个游戏的游戏框架构建完成。以后的工作就是根据需要添砖加瓦。
文件有点大,因为有音频文件
Popstar源代码:http://pan.baidu.com/s/1qWmPFVA
Code:21pv
扫雷是自己写的一个程序,盗用了这位:http://blog.csdn.net/chenpeijie0_0/article/details/7171284的图,未引用源代码,望原著见谅!
扫雷源代码:http://pan.baidu.com/s/1mgMPAwK
Code:mnu9