#include "stdafx.h" #include "MyGameFrame.h" #include <stdio.h> //子弹结构体 struct Bird { int x, y; }; //全局变量 HWND hWnd; HINSTANCE hInst; HDC hdc, mdc, bufdc; HBITMAP bg, ship, bullet, bird; int x, y, nowX, nowY; int bcount; //子弹数目; int w = 0; DWORD tPre, tNow; Bird p[3]; // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitWindow(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); VOID AIGamePaint(HDC hdc); int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 初始化全局字符串 MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitWindow(hInstance, nCmdShow))//初始化窗口 { return FALSE;//如果不成功则返回FALSE,并退出程序 } MSG msg; //创建消息类对象 // TODO: 在此放置运行代码。 //定义局部变量 HBITMAP bmp; POINT pt, lt, rb; /* typedef struct tagRECT { LONG left; LONG top; LONG right; LONG bottom; } RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT; RECT结构定义了一个矩形框左上角以及右下角的坐标 */ RECT rect; //建立内存DC和窗口DC hdc = GetDC(hWnd); mdc = CreateCompatibleDC(hdc); bufdc = CreateCompatibleDC(hdc); //建立适用位图 bmp = CreateCompatibleBitmap(hdc, 640, 480); SelectObject(mdc, bmp); //加载图片 bg = (HBITMAP)LoadImage(NULL, "sky.bmp", IMAGE_BITMAP, 640, 480, LR_LOADFROMFILE); ship = (HBITMAP)LoadImage(NULL, "ship.bmp", IMAGE_BITMAP, 100, 148, LR_LOADFROMFILE); bullet = (HBITMAP)LoadImage(NULL, "bullet.bmp", IMAGE_BITMAP, 10, 20, LR_LOADFROMFILE); bird = (HBITMAP)LoadImage(NULL, "bird.bmp", IMAGE_BITMAP, 122, 122, LR_LOADFROMFILE); //定义鼠标初始位置 x = 300; y = 300; //定义飞机初始位置 nowX = 300; nowY = 300; //定义鼠标光标位置 pt.x = 300; pt.y = 300; //把窗口坐标转换为屏幕坐标 ClientToScreen(hWnd, &pt); //设定光标位置 //SetCursorPos该函数把光标移到屏幕的指定位置(参数均为屏幕坐标)。 //如果新位置不在由 ClipCursor()函数设置的屏幕矩形区域之内,则系统自动调整坐标,使得光标在矩形之内。 SetCursorPos(pt.x, pt.y); //不显示光标 ShowCursor(false); //限制鼠标光标仅仅在游戏窗口内移动 //GetClientRect用于取得指定窗口的客户区域大小 //每个窗口区域可分为两部分,用于显示内容的区域叫Client区(客户区),NonClient(非客户区)用于显示命令按钮及窗口标题等。 //非客户区的绘图是由WM_NCPAINT发出的。 GetClientRect(hWnd, &rect); lt.x = rect.left; lt.y = rect.top; rb.x = rect.right; rb.y = rect.bottom; //转化坐标 ClientToScreen(hWnd, <); ClientToScreen(hWnd, &rb); rect.left = lt.x; rect.top = lt.y; rect.right = rb.x; rect.bottom = rb.y; //设置区域大小 ClipCursor(&rect); p[0].x = 30; //第一个小鸟的位置 p[0].y = 100; p[1].x = 250; //第二个小鸟的位置 p[1].y = 250; p[2].x = 500; //第三个小鸟的位置 p[2].y = 400; //绘图 AIGamePaint(hdc); // 主消息循环: PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);//赋初值 while (msg.message != WM_QUIT) //进入游戏消息循环: { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); //获得游戏玩家输入的消息; DispatchMessage(&msg);//分配玩家消息并响应用户消息。 } else { tNow = GetTickCount(); if (tNow - tPre >= 40) AIGamePaint(hdc); } } return (int)msg.wParam; } // // 函数: MyRegisterClass() // // 注册Windows类,一款游戏有且仅有一个主窗口,与游戏程序唯一对应。创建游戏窗口前要填写窗口类结构体WNDCLASSEX // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex = { wcex.cbSize = sizeof(WNDCLASSEX), CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW, WndProc,0,0, hInstance, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYGAMEFRAME)), LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1),NULL, _T("GameFrame"), LoadIcon(NULL,MAKEINTRESOURCE(IDI_SMALL)) }; return RegisterClassEx(&wcex); } // // 函数: InitInstance(HINSTANCE, int) // // 目的: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // BOOL InitWindow(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow ( _T("GameFrame"), _T("游戏框架"), WS_OVERLAPPEDWINDOW^WS_THICKFRAME^WS_MAXIMIZEBOX,//普通样式,不能改变大小,不能最大化 CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, nullptr, nullptr, hInstance, nullptr ); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: 处理主窗口的消息。 // // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { switch (msg) //判断消息 { case WM_CREATE: //执行初始化代码 return(0); break; //esc退出程序 case WM_KEYDOWN: if (wparam == VK_ESCAPE) PostQuitMessage(0); break; case WM_MOUSEMOVE: //获取鼠标X坐标 x = LOWORD(lparam); if (x > 530) x = 530; else if (x < 0) x = 0; //获取鼠标Y坐标 y = HIWORD(lparam); if (y > 380) y = 380; else if (y < 0) y = 0; break; case WM_DESTROY: //关闭程序,发送WM_QUIT消息 PostQuitMessage(0); return(0); break; default: break; } return (DefWindowProc(hwnd, msg, wparam, lparam)); } void AIGamePaint(HDC hdc) { int i; SelectObject(bufdc, bg); //背景移动 BitBlt(mdc, 0, 0, w, 480, bufdc, 640 - w, 0, SRCCOPY); BitBlt(mdc, w, 0, 640 - w, 480, bufdc, 0, 0, SRCCOPY); //根据光标点击位置进行X位置修正 if (nowX < x) { nowX += 10; if (nowX > x) nowX = x; } else { nowX -= 10; if (nowX < x) nowX = x; } //根据光标点击位置进行Y位置修正 if (nowY < y) { nowY += 10; if (nowY > y) nowY = y; } else { nowY -= 10; if (nowY < y) nowY = y; } //贴飞机 SelectObject(bufdc, ship); //透明处理 BitBlt(mdc, nowX, nowY, 100, 74, bufdc, 0, 74, SRCAND); BitBlt(mdc, nowX, nowY, 100, 74, bufdc, 0, 0, SRCPAINT); //贴小鸟 SelectObject(bufdc, bird); for (i = 0; i<3; i++) { if (rand() % 3 != 1) { //设定追逐几率 if (p[i].y > nowY - 16) p[i].y -= 5; else p[i].y += 5; if (p[i].x > nowX - 25) p[i].x -= 5; else p[i].x += 5; } if (p[i].x > nowX - 25) { //判断小鸟移动方向 BitBlt(mdc,p[i].x,p[i].y,61,61,bufdc,61,61,SRCAND); BitBlt(mdc,p[i].x,p[i].y,61,61,bufdc,0,61,SRCPAINT); } else { BitBlt(mdc, p[i].x, p[i].y, 61, 61, bufdc, 61, 0, SRCAND); BitBlt(mdc, p[i].x, p[i].y, 61, 61, bufdc, 0, 0, SRCPAINT); } } BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY); tPre = GetTickCount(); //背景移动 w += 10; if (w >= 640) w = 0; }
结果如图所示: