这个击球游戏是我码下来的第一个可以运行的游戏虽然只有一个击球动作,但其中的GDI绘图以及windows消息循环的使用以后还是可以借鉴的,这里记录下来以做参考。
// --------------------------程序说明---------------------------- -
//程序名称:GDIdemo
//描述:GDI绘图模版
//---------------------------------------------------------------
//------------------------头文件部分------------------------------
#include<Windows.h>
#include"Inite.h"
//可以在此区域继续添加头文件
//--------------------------------------------------------------------
//------------------------宏定义-------------------------------------
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define WINDOW_TITLE L"GDI程序框架"
//-------------------------------------------------------------------
//----------------------全局变量声明部分-----------------------------
HDC g_hdc = NULL;//全局设备环境句柄
//----------------全局函数声明部分---------------------------------------
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);//窗口过程函数
BOOL Game_Init(HWND hwnd);//在此函数进行资源初始化
VOID Game_Paint(HWND hwnd);//在此函数进行绘图代码的书写
BOOL Game_CleanUp(HWND hwnd);//在此函数进行资源的清理
void DrawBkground(HWND hWnd);//画背景
void DrawAround(HWND hWnd);//画场地围边
void DrawFiled(HWND hWnd);//画场地
void DrawNet(HWND hWnd);//画球网
void DrawMan(HWND hWnd);
void DrawNPC(HWND hWnd);
//--------------------WinMain---------------------------------------
//Windows应用程序的入口函数
//---------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//[1]窗口创建四部曲之一:开始设计一个完整的窗口类
WNDCLASSEX wc = {};//用WNDCLASSEX定义了一个窗口类
wc.cbSize = sizeof(WNDCLASSEX);//设置结构体的字节数大小
wc.style = CS_HREDRAW | CS_VREDRAW;//设置窗口的样式
wc.lpfnWndProc = WndProc;//设置指向窗口过程的指针
wc.cbClsExtra = 0;//窗口类的附加内存
wc.cbWndExtra = 0;//窗口的附加内存
wc.hInstance = hInstance;//制定包含窗口过程的程序的实例句柄
wc.hIcon = (HICON)::LoadImage(NULL, L"", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);//本地加载自定义图标“”
wc.hCursor = LoadCursor(NULL, IDC_ARROW);//指定窗口类的光标句柄
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);//指定一个灰色画刷句柄
wc.lpszClassName = L"WINDOW";//用一个空终止的字符串,指定窗口类的名字
wc.lpszMenuName = NULL;//用一个空终止的字符串,指定菜单资源的名字
//[2]窗口的创建四部曲之二:注册窗口类
if (!RegisterClassEx(&wc))//设计完窗口,需要对窗口类进行注册,这样才能创建该类型的窗口
return -1;
//[3]窗口创建四部曲之三:正式创建窗口
HWND hwnd = CreateWindow(L"WINDOW", WINDOW_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
//窗口创建四部曲之四:窗口的移动,显示与更新
MoveWindow(hwnd, 250, 80, WINDOW_WIDTH, WINDOW_HEIGHT, true);//调整窗口显示時的位置位于(250,80)处
ShowWindow(hwnd, nShowCmd);//调用showwindow来显示窗口
UpdateWindow(hwnd);//队窗口进行更新
//游戏资源的初始化,若初始化失败弹出一个消息框并返回FALSE
HDC hdc;
hdc = GetDC(hwnd);
char buffer[80];
const short INITHEIGHT = 85;
short ball_x = 600;
short ball_y = 420;
short ball_height = INITHEIGHT;
short ball_size = 20;
short ball_yv = 2;
short ball_xv = -2;
short count = 0;
short ball_speed = 1;
bool direct = true;
short bat_x = 600;
short bat_y = 600;
short strength = 80;
bool alive = true;
srand(GetTickCount());
if (!Game_Init(hwnd))
{
MessageBox(hwnd, L"初始化资源失败", L"消息窗口", 0);//使用MESSASGEBOX创建一个消息窗口
return FALSE;
}
//【5】消息循环
MSG msg = { 0 };//定义并初始化msg
while (alive)//使用while循环,如果消息不是wm-quit消息,就继续循环
{
DWORD start_time = GetTickCount();
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))//查看应用程序消息队列,有消息時就将队列中的消息派发出去
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);//将虚拟消息转换为字符消息
DispatchMessage(&msg);//分发一个消息给窗口程序
}
else{
if (KEYDOWN(VK_LEFT) && (MANPPOINT[0].x > 20))
{
MANPPOINT[0].x -= 12;
MANPPOINT[1].x -= 12;
MANPPOINT[2].x -= 12;
MANPPOINT[3].x -= 12;
}
if (KEYDOWN(VK_RIGHT) && (MANPPOINT[0].x < 740))
{
MANPPOINT[0].x += 12;
MANPPOINT[1].x += 12;
MANPPOINT[2].x += 12;
MANPPOINT[3].x += 12;
}
if (KEYDOWN(VK_UP) && (MANPPOINT[0].x > 350))
{
MANPPOINT[0].y -= 12;
MANPPOINT[1].y -= 12;
MANPPOINT[2].y -= 12;
MANPPOINT[3].y -= 12;
}
if (KEYDOWN(VK_DOWN) && (MANPPOINT[0].x > 470))
{
MANPPOINT[0].y += 12;
MANPPOINT[1].y += 12;
MANPPOINT[2].y += 12;
MANPPOINT[3].y += 12;
}
//--------------------------渲染部分
DrawBkground(hwnd);
DrawAround(hwnd);
DrawFiled(hwnd);
DrawNPC(hwnd);
if (ball_y >= 270)
{
DrawNet(hwnd);
ball_size = 20;
}
SelectObject(hdc, black_pen);
//画影子
SelectObject(hdc, black_brush);
Ellipse(hdc, ball_x, ball_y + ball_height, ball_x + ball_size - 3, ball_y + ball_size + ball_size - 5);
//画球
SelectObject(hdc, yellow_brush);
Ellipse(hdc, ball_x, ball_y, ball_x + ball_size, ball_y + ball_size);
SelectObject(hdc, black_pen);
SelectObject(hdc, yellow_brush);
if (ball_y < 270)
{
DrawNet(hwnd);
ball_size = 18;
}
DrawMan(hwnd);
ball_x += ball_xv;
ball_y += ball_yv;
if (direct)
{
strength -= 3;
if (strength<=0)
{
ball_height -= ball_speed++;
strength = 0;
}
if (ball_height<=0)
{
ball_height = 0;
count++;
if (ball_xv <= 0)
{
ball_xv++;
}
else{
ball_xv--;
}
if (ball_yv)
{
ball_yv++;
}
else{
ball_yv--;
}
direct = !direct;
}
}
else{
ball_speed -= 2;
ball_height += ball_speed;
if (ball_speed<=0)
{
direct = !direct;
}
}
if (count>=2)
{
alive = false;
MessageBox(hwnd, L"Game Over", L"MESSAGE", MB_OK);
}
//画球结束
//碰撞检测
if (ball_x>MANPPOINT[0].x-10
&& ball_x<MANPPOINT[1].x
&& ball_y>MANPPOINT[0].y- 10
&& ball_y<MANPPOINT[3].y
&& ball_yv>0
)
{
strength = 80 + rand() % 10;
ball_height = INITHEIGHT;
if (rand() % 2 == 0)
{
ball_xv = -1 * rand() % 6;
}
else
{
ball_xv = rand() % 3;
}
ball_yv = -1 * (rand() % 8 + 4);
count = 0;
}
else
{
if (ball_x > NPCPPOINT[0].x - 10
&& ball_x<NPCPPOINT[1].x
&& ball_y>NPCPPOINT[0].y - 10
&& ball_y<NPCPPOINT[3].y
&& ball_yv>0)
{
strength = 50 + rand() % 40;
ball_height = INITHEIGHT;
if (rand() % 2 == 0)
{
ball_xv = -1 * rand() % 3;
}
else
{
ball_xv = rand() % 3;
}
ball_yv = -1 * (rand() % 8 + 4);
count = 0;
}
while (GetTickCount()-start_time<43);
}
}
}
//[6]窗口类的注销
DeleteObject(white_pen);
DeleteObject(black_pen);
DeleteObject(yellow_brush);
DeleteObject(black_brush);
DeleteObject(white_brush);
DeleteObject(bk_brush);
DeleteObject(arand_brush);
DeleteObject(field_brush);
ReleaseDC(hwnd, hdc);
UnregisterClass(L"WINDOW", wc.hInstance);//程序准备结束注销窗口类
return 0;
}
//-----------------------------WinProc函数-----------------------------------------
//对窗口消息进行处理
//---------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;//定义一个paintstruct来记录绘制信息
switch (message)//switch程序开始
{
case WM_PAINT://若是客户区重绘消息
g_hdc = BeginPaint(hwnd, &paintStruct);//指定窗口进行绘图工作的准备,并将和绘图有关的信息填充到painstruct结构体中去
Game_Paint(hwnd);
EndPaint(hwnd, &paintStruct);//指定窗口的绘画过程结束
ValidateRect(hwnd, NULL);//更新客户区的显示
break;
case WM_KEYDOWN://键盘按下消息
if (wParam == VK_ESCAPE)//如果按下esc
DestroyWindow(hwnd);//销毁窗口并发送wm-destroy消息
break;
case WM_DESTROY://若是窗口销毁信息
Game_CleanUp(hwnd);
PostQuitMessage(0);//向系统表明有个线程有终止请求。用来响应WM_DESTROY消息
break;//跳出该switch语句
default://若上述case条件都不符合,则执行default语句
return DefWindowProc(hwnd, message, wParam, lParam);//调用默认的窗口过程
}
return 0;//正常退出
}
//-------------------------------------
void DrawBkground(HWND hWnd){
HDC hdc;
hdc = GetDC(hWnd);
SelectObject(hdc, black_pen);
SelectObject(hdc, bk_brush);
Polygon(hdc, BKPOINT, 6);
SelectObject(hdc, black_pen);
SelectObject(hdc, bk_brush);
ReleaseDC(hWnd, hdc);
}
//-------------------------------------
void DrawAround(HWND hWnd)
{
HDC hdc;
hdc = GetDC(hWnd);
SelectObject(hdc, black_pen);
SelectObject(hdc, arand_brush);
Polygon(hdc, AROUNDPOINT, 6);
SelectObject(hdc, black_pen);
SelectObject(hdc, arand_brush);
ReleaseDC(hWnd, hdc);
}
//-------------------------------------
void DrawFiled(HWND hWnd)
{
HDC hdc;
hdc = GetDC(hWnd);
SelectObject(hdc, black_pen);
SelectObject(hdc, field_brush);
Polygon(hdc, FILEDPOINT, 4);
MoveToEx(hdc, 400, 150, NULL);
LineTo(hdc, 40, 550);
MoveToEx(hdc, 130, 300, NULL);
LineTo(hdc, 665, 300);
MoveToEx(hdc, 24, 551, NULL);
LineTo(hdc, 775, 551);
SelectObject(hdc, black_pen);
SelectObject(hdc, field_brush);
ReleaseDC(hWnd, hdc);
}
//--------------------------------------
void DrawNet(HWND hWnd)
{
HDC hdc;
hdc = GetDC(hWnd);
SelectObject(hdc, white_pen);
SelectObject(hdc, white_brush);
SetBkMode(hdc, TRANSPARENT);
Polygon(hdc, NETPOINT, 17);
SelectObject(hdc, white_pen);
SelectObject(hdc, white_brush);
ReleaseDC(hWnd, hdc);
}
//-------------------------------------
void DrawNPC(HWND hWnd)
{
HDC hdc;
hdc = GetDC(hWnd);
SelectObject(hdc, white_pen);
SelectObject(hdc, black_brush);
Polygon(hdc,NPCPPOINT, 4);
SelectObject(hdc, white_brush);
SelectObject(hdc, black_brush);
ReleaseDC(hWnd, hdc);
}
//-------------------------------------
void DrawMan(HWND hWnd)
{
HDC hdc;
hdc = GetDC(hWnd);
SelectObject(hdc, white_pen);
SelectObject(hdc, black_brush);
Polygon(hdc, MANPPOINT, 4);
SelectObject(hdc, white_pen);
SelectObject(hdc, black_brush);
ReleaseDC(hWnd, hdc);
}
//-------------------------【Game_Init】
BOOL Game_Init(HWND hwnd)
{
g_hdc = GetDC(hwnd);
Game_Paint(hwnd);
ReleaseDC(hwnd, g_hdc);
return TRUE;
}
//-------------------------【Game_Paint】
VOID Game_Paint(HWND hwnd)
{
}
//-----------------------------[Game_CleanUp]
BOOL Game_CleanUp(HWND hwnd)
{
return TRUE;
}