做一个普通的贪吃蛇出来,首先看下我们要实现的功能:
- 会移动的球
- 随机生成吃的食物
- 球吃了食物会变大
首先是球的移动
int x,y;
case WM_CREATE:
SetTimer(hwnd, 1, 100, NULL); // 设置定时器的刷新时间
return 0;
case WM_PAINT: // 可以理解为绘制窗口用
hdc = BeginPaint(hwnd, &ps); // 必须要有BeginPaint 和 EndPaint。 hdc 是设备上下文
Ellipse(hdc, x, y, x + Ballsize, y + Ballsize); // 画圆的api , 2到4的参数分别是左上xy坐 标和右下坐标,Ballsize可以理解为球的直径
EndPaint(hwnd, &ps);
return 0;
case WM_TIMER: // 定时器
x+=speed,y+=speed;
InvalidateRect(hwnd, NULL, TRUE); //刷新窗口用
return 0;
通过时时刷新窗口,每次刷新时,圆的坐标都相较上次移动了speed的距离,这也就实现了球的移动。
通过上下左右控制球的移动
case WM_KEYDOWN: //按键消息
switch (wParam)
{
case VK_UP:
p = 0;
return 0;
case VK_DOWN:
p=1
return 0;
case VK_LEFT:
p = 2;
return 0;
case VK_RIGHT:
p = 3;
return 0;
}
//在 WM_PAINT中增加
if (p == 0)
y -= 10;
else if (p == 1)
y += 10;
else if (p == 2)
x -= 10;
else if (p == 3)
x += 10;
通过获得按键消息,改变P的值 从而确定圆的行走方向。以上 也就是基本实现了 通过上下左右控制圆球的移动功能。
而实现随机产生食物的功能就更简单了。
srand((unsigned)time(NULL));//设置时间种子 防止伪随机
for(int i=0;i<number;i++)
{
x = rand() % 700;
y = rand() % 700;
Ellipse(hdc, x, y, x + FoodSize, y + FoodSize);
}
//画很多很多的圆就ok了!
//吃了食物会变大
vector<Food> foodvector // 装有食物的数组
void Grow()
{
bool Eat()
{
while(foodvector)
{
// 判断每个食物的中心坐标是否在圆的左上坐标和右下坐标之间,如果是,则认为圆吃了食物
}
}
if(吃掉了食物)
{
// 重新分配食物的x,y的坐标
Ballsize += Growsize; //球长大
}
}
难点在于如何判断圆是否吃了食物,我的方法就如上所说是通过坐标判断的。之后的很多判断都是通过坐标,所以坐标判断的函数可以抽出来,这样就不用每次都写了。
突然觉得Unity3D中的碰撞检测好方便啊。
基本的实现就是这样了。我之前说过我将会用C++的封装。
- CCoordinate //坐标类 所有拥有坐标的物体都继承该类,左上右下和中心点坐标
- CBallProPerty //球的属性类
- CFood //食物坐标
- CControl // 球的移动以及其他操作
- CSimpleAI // 智障AI类 这是我下一章要写的内容