C语言学习 18-11-12

Win32贪吃蛇游戏开发
本文介绍如何使用Win32 API开发一个简单的贪吃蛇游戏,包括图像资源的导入、位图的加载和显示、游戏逻辑的实现以及键盘事件的处理。详细讲解了从设计窗口、注册窗口类、创建窗口到显示窗口的过程,以及如何使用定时器控制游戏速度。

1.画两个矩形并使其移动

需要在定时器处理消息中进行绘制图像。

case WM_TIMER:
	hdc = GetDC(h_wnd);
	a += 5;									// 需要设置a为静态变量
	b += 10;								// 需要设置b为静态变量
	Ellipse(hdc, a, 50, a+50, 100);
	Ellipse(hdc, b+50, 200, b+100, 250);
	ReleaseDC(h_wnd, hdc);*/
	break;

2.设置两个矩形的移动速率不同

设置两个定时器,通过定时器的ID来区分定时器。

case WM_TIMER:
	hdc = GetDC(h_wnd);
	brush = CreateSolidBrush(RGB(255, 255, 255));
	SelectObject(hdc, brush);
	if(1 == w_param)
	{
		a += 5;
		Ellipse(hdc, a, 50, a+50, 100);
	}
	if(2 == w_param)
	{
		b += 10;
		Ellipse(hdc, b+50, 200, b+100, 250);
	}

	ReleaseDC(h_wnd, hdc);
	break;

3.设置按A键使得其中一个矩形停止

1.在 KETDOWN 中设置,矩形停止运动也即定时器停止;

2.定时器停止使用函数 KillTimer(h_wnd, timer id)

case WM_KEYDOWN:
	if(65 == w_param)				// A键使得第二个停止
	{
		KillTimer(h_wnd, 2);
	}
	if(66 == w_param)				// B键使得第二个停止
	{
		KillTimer(h_wnd, 1);
	}

	break;

4.贪吃蛇项目

1.在 右侧->资源文件->添加->资源->bitmap->导入 已有的图像文件,需要注意的是,我们添加的bitmap文件所在的位置应该在当前c文件所在的文件夹下。

2.当我们完成第一步后会在资源文件中产生位图文件和一个**.rc文件,在头文件中会生成一个resource.h**头文件,其中所储存的信息是位图的名字。

3.导入位图文件到Win32项目中,需要使用函数 LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP)),该函数返回一个 Bitmap 的句柄,因此需要一个句柄来接受该函数的返回值,句柄的类型是 HBITMAP。

4.将背景图片显示到窗口中,需要获得h_dc句柄,在WM_PAINT消息中,除了获得h_dc句柄,还需要获得一个兼容句柄来保存图像。

5.使用兼容句柄来选择图像,SelectObject(image_dc, image_backageground)。

6.将选中的图像传输到hdc中,使用函数 BitBlt(目标句柄 hdc,起始 x值,起始 y值,要传输的宽度,要传输的高度,城防图像的句柄 image_dc,盛放的图片的起始 x值,盛放的图片的起始 y值,SRCCOPY)。

7.删除生成的image_dc

8.程序:

#include "Windows.h"
#include "stdlib.h"
#include "stdio.h"
#include "resource.h"				// 添加图像资源之后的生成的包含图像名称的头文件,自动生成

LRESULT CALLBACK my_wndproc(HWND h_wnd, UINT message_flag, WPARAM w_param, LPARAM l_param);
static int a = 50;
static int b = 100;

// 定义图像句柄
HBITMAP image_background;
HBITMAP image_snack_head_up;
HBITMAP image_snack_head_down;
HBITMAP image_snack_head_left;
HBITMAP image_snack_head_right;
HBITMAP image_snack_body;
HBITMAP image_apple;



int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
					 LPSTR IpCmdLine, int nCmdShow)
{
	HWND h_wnd;
	MSG my_msg;
	// 1.设计窗口
	WNDCLASSEX ex;
	ex.style = CS_HREDRAW/* | CS_VREDRAW*/;			// 窗口的刷新方式,当水平刷新时,改变窗口的高度会重绘;当垂直刷新时,改变窗口的宽度会重绘;
	ex.cbSize = sizeof(WNDCLASSEX);				// 当前结构体的大小
	ex.cbClsExtra = 0;							// 为结构体开辟附加空间存储结构体的附加信息
	ex.cbWndExtra = 0;							// 注册窗口时申请的空间大小存放此窗口的特有数据,通常为0
	ex.hInstance = hInstance;					// 应用程序句柄,此结构体在哪个应用程序中使用
	ex.hIcon = NULL;							// 指定窗口类图标的句柄
	ex.hCursor = NULL;							// 加载鼠标为空使用系统默认图标
	ex.hbrBackground = CreateSolidBrush(RGB(0, 0, 255));	// 指定背景画刷句柄
	ex.hIconSm = NULL;							// 窗体图标,最左上角的小图标
	ex.lpfnWndProc = &my_wndproc;						// 消息处理函数指针
	ex.lpszMenuName = NULL;						// 加载菜单名,为空则没有菜单
	ex.lpszClassName = "aa";					// 字符集,默认为unicode,可在项目中修改为多字符

	// 2.注册窗口
	RegisterClassEx(&ex);

	// 3.创建窗口
	h_wnd = CreateWindow(ex.lpszClassName, "hahaah", WS_OVERLAPPEDWINDOW, 50, 50, 616, 638, NULL, NULL, hInstance, NULL);

	// 4.显示窗口
	ShowWindow(h_wnd, SW_SHOW);

	// 读入图像
	image_background = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
	image_apple = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP2));
	image_snack_body = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP3));
	image_snack_head_up = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP7));
	image_snack_head_down = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP5));
	image_snack_head_left = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP4));
	image_snack_head_right = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP6));


	// 设置刷新时间
	SetTimer(h_wnd, 1, 500, NULL);
	SetTimer(h_wnd, 2, 200, NULL);

	// GetMessage(指向一个MSG指针,指向接受哪个窗口的消息 为NULL接收所有窗口,指定要获取的消息的最小值 通常为0,指定要获取的消息的最小值 最大最小都为0则接收所有)
	while(GetMessage(&my_msg, NULL, 0, 0))
	{
		TranslateMessage(&my_msg);				// 翻译消息
		DispatchMessage(&my_msg);				// 分发消息
	}

	return 0;
}

LRESULT CALLBACK my_wndproc(HWND h_wnd, UINT message_flag, WPARAM w_param, LPARAM l_param)
{
	HDC hdc;
	HDC image_dc;

	switch (message_flag)
	{
	case WM_CLOSE:
		PostQuitMessage(0);
		break;

	case WM_KEYDOWN:
		break;

	case WM_PAINT:
		hdc = BeginPaint(h_wnd, &ps);
		image_dc = CreateCompatibleDC(hdc);
		SelectObject(image_dc, image_background);
		BitBlt(hdc, 0, 0, 600, 600, image_dc, 0, 0, SRCCOPY);
		DeleteDC(image_dc);
		ReleaseDC(h_wnd, hdc);
		break;

	case WM_LBUTTONUP:
		break;

	case WM_TIMER:
		break;

	default:
		break;
	}

	return DefWindowProc(h_wnd, message_flag, w_param, l_param);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值