c语言编写游戏贪吃蛇以及部分easyx函数的使用
前言
游戏贪吃蛇的主要代码可以分为三个部分:
- 绘制地图、小蛇与食物
- 游戏的初始化
- 小蛇的移动
代码与部分函数解析
1.绘制地图、小蛇与食物
void show()//绘制函数
{
cleardevice();
int i, j;
for (i = 0; i < HEIGHT; i++)
{
for (j = 0; j < WIDTH; j++)
{
if (blocks[i][j] > 0)//元素大于0表示是蛇
setfillcolor(HSVtoRGB(blocks[i][j] * 10, 0.9, 1));//设置蛇身为渐变色
else
setfillcolor(RGB(150, 150, 150));//元素为0表示为空,设置为灰色
fillrectangle(j * BLOCK_SIZE, i * BLOCK_SIZE,
(j + 1) * BLOCK_SIZE, (i + 1) * BLOCK_SIZE);
}
}
setfillcolor(RGB(0, 255, 0));//设置食物颜色为绿色
fillrectangle(food_j * BLOCK_SIZE, food_i * BLOCK_SIZE,
(food_j + 1) * BLOCK_SIZE, (food_i + 1) * BLOCK_SIZE);
if (isfailure)//判断游戏是否失败
{
setbkmode(TRANSPARENT);//设置文字字体透明
settextcolor(RGB(221, 160, 221));//设置文字颜色
settextstyle(80, 0, _T("宋体"));//设置文字大小与样式
outtextxy(240, 220, _T("游戏失败"));//输出文字内容
}
FlushBatchDraw();
}
- fillrectangle函数的使用方法如下:
void fillrectangle(
int left,
int top,
int right,
int bottom
);
其中,left等分别表示矩形框的左侧横坐标、上侧纵坐标、右侧横坐标与下侧纵坐标。
- FlushBatchDraw语句表示批量绘制,意为一次性完成所有绘图任务
2.游戏的初始化
void startup()//初始化函数
{
int i;
blocks[HEIGHT / 2][WIDTH / 2] = 1;
for (i = 1; i <= 4; i++)
blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1;//向左四个蛇身,分别为2,3,4,5
movedirection = 'd';//默认按d键,初始向右移动
food_i = rand() % (HEIGHT - 5) + 2;
food_j = rand() % (WIDTH - 5) + 2;//食物位置随机
initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE);//展开画面
setlinecolor(RGB(200, 200, 200));
BeginBatchDraw();//
}
- BeginBatchDraw语句表示批量绘制
- 展开画面部分不参与循环,属于初始化部分,因此不放入show函数中
3.小蛇的移动
首先,我们需要通过遍历blocks数组以找出小蛇(数组元素大于0,下文称此部分为“小蛇数组”)的位置,
并且确定蛇头(小蛇数组整体自加后数值为2,详见代码部分)、蛇尾(小蛇数组中值最大的元素);
其次,根据用户输入确定新蛇头的位置,如果蛇头超过边界或者蛇头碰到蛇身,则判定失败(isfailure);
如果蛇头碰到食物,则刷新食物位置,不处理蛇尾(相当于长度+1);
如果没有碰到食物,则旧蛇尾变成空白。
代码如下:
void movesnake()
{
int i, j;
for (i = 0; i < HEIGHT; i++)
for (j = 0; j < WIDTH; j++)
if (blocks[i][j] > 0)
blocks[i][j]++;//小蛇数组自加运算
int oldtail_i, oldtail_j, oldhead_i, oldhead_j;
int max = 0;//记录最大值
for (i = 0; i < HEIGHT; i++)
for (j = 0; j < WIDTH; j++)//找蛇头与蛇尾
{
if (max < blocks[i][j])
{
oldtail_i = i;
oldtail_j = j;
max = blocks[i][j];
}
if (blocks[i][j] == 2)
{
oldhead_i = i;
oldhead_j = j;
}
}
int newhead_i = oldhead_i;
int newhead_j = oldhead_j;
//根据按键确定新蛇头的位置
if (movedirection == 'w')
newhead_i = oldhead_i - 1;
else if (movedirection == 's')
newhead_i = oldhead_i + 1;
else if (movedirection == 'a')
newhead_j = oldhead_j - 1;
else if (movedirection == 'd')
newhead_j = oldhead_j + 1;
if (newhead_i >= HEIGHT || newhead_j >= WIDTH || newhead_i < 0 || newhead_j < 0
|| blocks[newhead_i][newhead_j]>0)//判断游戏是否失败
{
isfailure = 1;
return;
}
blocks[newhead_i][newhead_j] = 1;
if (newhead_i == food_i && newhead_j == food_j)//吃到食物
{
food_i = rand() % (HEIGHT - 5) + 2;
food_j = rand() % (WIDTH - 5) + 2;
}
else
blocks[oldtail_i][oldtail_j] = 0;
}
4.后期细节处理与补充
在贪吃蛇游戏中,用户不进行输入小蛇位置也会发生移动,因此我们需要分别写与输入有关的函数和与输入无关的函数。
void withoutinput()//与输入无关
{
if (isfailure)
return;
static int wait = 1;
wait++;
if (wait == 10)
{
movesnake();
wait = 1;
}
}
void withinput()//与输入有关
{
if (_kbhit() && isfailure == 0)//有输入且不失败
{
char input = _getch();
if (input == 'w' || input == 'a' || input == 's' || input == 'd')
{
movedirection = input;
movesnake();
}
}
}
- “wait”初始化为1,每10帧移动一次
- _kbhit为判断键盘有无输入的函数
最后附上主函数代码:
int main()
{
startup();
while (1)
{
show();
withoutinput();
withinput();
}
return 0;
}

浙公网安备 33010602011771号