win32强化练习3.6_贪吃蛇半部

这个练习仍然是3.1键盘消息和3.3定时器消息的组合;所谓贪吃蛇半部指的是我们只做一半,因为完整的需要比较多的时间,至少是个把小时,我们的基础练习尽量在10~20分钟内能够完成,目前还不适合涉及太多的琐碎的地方。

练习主要分2大部分来完成,具体步骤如下:

1. 完成一个字符的定时移动,键盘控制方向:

1.1 定义全局变量 ,自定义格点与pix之间的比例关系,例如 20pix为1个格点,设定游戏区范围是20*16格点,从(10,10)开始,则相对坐标为 (10+20* x)

1.2 处理WM_PAINT消息,在其中先画一个边框(画笔HPEN的使用练习),再画出单个字符(在游戏区的中心位置)

1.3 在WM_CREATE中,开启定时器SetTimer

1.4 处理WM_TIMER消息,根据当前x向和y向及正负,使用字符移动一个格点

1.5 处理键盘消息,实现根据上下左右按键改变运动方向

int gx = 10, gy = 8;	//中心位置 
int vx = 1, vy = 0;		//默认向右移动 
case WM_PAINT:
		{
			PAINTSTRUCT ps;
			hdc = BeginPaint(hwnd, &ps);			
			HPEN hPen = CreatePen(0,3, RGB(0,255,0));
			HPEN hOld = (HPEN)SelectObject(hdc, hPen);
			Rectangle(hdc, 10,10, 20*20+10, 20*16+10);	//画边框 
			DeleteObject(SelectObject(hdc, hOld));
			
			TextOut(hdc, 10+ 20 *gx, 10 + 20*gy, "*",1);  //画字符 
			EndPaint(hwnd, &ps);
		}
		break;
case WM_TIMER:
		{
			gx+=vx;
			gy+=vy;
			InvalidateRect(hwnd, NULL, TRUE);	 //重绘 
		}
		break;
case WM_KEYDOWN:
		{
			switch(wParam)
			{
			case VK_LEFT: vx = -1; vy = 0; break;
			case VK_RIGHT: vx = 1; vy = 0; break;
			case VK_UP: vx = 0; vy = -1; break;
			case VK_DOWN: vx = 0; vy = 1; break;
			default:
				break;
			}
			InvalidateRect(hwnd, NULL, TRUE);
		}
		break;

2. 完成多个字符(组成一条蛇)的移动,键盘控制方向:

2.1 单个字符的键盘响应移动已经奠定了基础,在此基础上再进一步就需要把蛇的身体(几个字符)造出来,如果是想练习链表就用链表做,需要练习数组就用数组做,练习C++类就用class来做,这次的练习我们来建一个SNAKE的类,成员变量为节数,并用vector相当于建立2个动态数组,分别存放每个节点的x和y的格点值;

2.2 在主函数之前,用SNAKE(i) 创建对象并构造有i个字符的蛇;

2.3 在SNAKE类,建一个showSnake()的成员函数,传递hdc即可

2.4 在WM_PAINT处理中,将TextOut单个字符改换成调用showSnake()进行蛇身各节点的绘制

2.5 在SNAKE类,建一个moveSnake()的成员函数,由于在这个函数将在定时器消息中使用,需要把hdc声明为全局

2.6 在WM_TIMER中,调用moveSnake()函数,实现整条蛇的移动

class SNAKE
{
	int size;//蛇的节数
	vector <int> vecx, vecy; //使用vector容器 
public:
	SNAKE(){};
	SNAKE(int num)//构造蛇各节
	{
		size = num;
		int x = 10, y = 5;
		for (int i = 0; i< num; i++)
		{
			vecx.push_back(x);
			vecy.push_back(y + i);
		}
	}
};
SNAKE s(8);
void showSnake(HDC hdc)
	{
		for (int i = 0; i< size; i++)
		{
			TextOut(hdc, 10+ 20* vecx[i], 10 + 20* vecy[i], "&", 1);
		}
		
	}
case WM_PAINT:
		{
			PAINTSTRUCT ps;
			hdc = BeginPaint(hwnd, &ps);			
			HPEN hPen = CreatePen(0,3, RGB(0,255,0));
			HPEN hOld = (HPEN)SelectObject(hdc, hPen);
			Rectangle(hdc, 10,10, 20*20+10, 20*16+10);	//画边框 
			DeleteObject(SelectObject(hdc, hOld));
		//	TextOut(hdc, 10+ 20 *gx, 10 + 20*gy, "*",1);  //画字符 
			s.showSnake(hdc);	//画蛇 
			EndPaint(hwnd, &ps);
		}
void moveSnake()
	{
		for (int i = size-1; i>0;i-- )
		{
			vecx[i] = vecx[i-1];
			vecy[i] = vecy[i-1];
		}
		vecx[0] = vecx[0] + vx;
		vecy[0] = vecy[0] + vy;
	}
case WM_TIMER:
		{
			//gx+=vx;
			//gy+=vy;
			s.moveSnake(hdc);
			InvalidateRect(hwnd, NULL, TRUE);	 //重绘 
		}
		break;
至此,贪吃蛇的创建、移动以及根据按键改变方向的功能就完成了,当然完整的程序后面还有碰撞检测(包含碰边界死亡、碰自身死亡、碰豆子增加一节...)以及随机放豆子等功能就不在这里练习了。

从3.5,3.6两节练习可以看到,定时器+键盘的灵活搭配,已经可以制作简单的可玩耍的游戏了,这些立竿见影的基本功,还不多多练习?







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值