#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, bird;
int x, y, nowX, nowY;
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);
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;
}
结果如图所示: