上代码!!!
void gameExit()
{
initgraph(width, heigth);
loadimage(&img2, “图2.jpg”, width, heigth);
putimage(0, 0, &img2);
}
-
首先我们要初始化一个新的界面
-
我们要初始化蛇的参数。先通过结构体定义蛇的各类参数,看看我的代码吧!
struct Snake
{
int size; //蛇的长度
int speed; //蛇的速度
int dir; //蛇的方向
POINT coor[SNAKE_MAX]; //蛇的最大长度
}snake;
其中 POINT 本身就是一个结构体,它里面包含了 x 和 y 坐标
- 我们再初始化食物的参数。
struct Food
{
int x;
int y;
int r;
bool flag; //1 没有吃掉 0 吃掉了
DWORD color;
}food;
//typedef unsigned long DWORD;
//DWORD 表示 32bit 无符号整数
- 接下来我们则对以上参数进行初始化,上代码!
void gameInit1()
{
initgraph(width, heigth);
//小蛇初始化
snake.size = 3;
snake.speed = 10;
snake.dir = LEFT;
for (int i = snake.size - 1; i >= 0; i–)
{
snake.coor[i].x = 10 * i + 400;
snake.coor[i].y = 30;
}
//食物初始化
food.r = rand() % 16 + 5; //食物半径控制在5~15
food.x = rand() % width; //初始化x
food.y = rand() % heigth; //初始化y
food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
food.flag = true;
}
这也是很容易实现的部分,既然有了参数,我们只要对参数通过 EasyX 图形库进行绘制就行
void gameDraw1()
{
loadimage(&img4, “图4.png”, width, heigth);
putimage(0, 0, &img4);
//设置绘图填充颜色
setfillcolor(RGB(61, 89, 171));
for (int i = 0; i < snake.size; i++)
{
//将每个坐标绘制成半径为5的园
solidcircle(snake.coor[i].x, snake.coor[i].y, 5);
}
//将绘图填充色修改成食物的颜色
setfillcolor(food.color);
//判断食物存在则在坐标处绘制出半径为食物半径的圆
if (food.flag)
solidcircle(food.x, food.y, food.r);
//结束批量绘制
EndBatchDraw();
}
-
我们该怎么让小蛇移动呢?是不是蛇其实都是跟着蛇头走的,再具体一点,每一节都是跟着前一节移动。所以我们只要从最后一节到第二节开始循环,每节的坐标等于前一节就行,而蛇头坐标则要靠此时小蛇前进的方向进行改变。可以使用一个 switch 语句进行改变。
-
我们要思考当蛇头遇到边界了该怎么办。
-
如果蛇头的坐标等于蛇身的坐标,那也就失败了。我们直接上代码吧!
bool snakeMove1()
{
for (int i = snake.size - 1; i > 0; i–)
{
snake.coor[i] = snake.coor[i - 1];
}
switch (snake.dir)
{
case UP:
snake.coor[0].y -= snake.speed;
if (snake.coor[0].y <= 0)
return false;
break;
case DOWN:
snake.coor[0].y += snake.speed;
if (snake.coor[0].y >= heigth)
return false;
break;
case LEFT:
snake.coor[0].x -= snake.speed;
if (snake.coor[0].x <= 0)
return false;
break;
case RIGHT:
snake.coor[0].x += snake.speed;
if (snake.coor[0].x >= width)
return false;
break;
}
for (int i = snake.size - 1; i > 0; i–)
{
if (snake.coor[0].x == snake.coor[i].x && snake.coor[0].y == snake.coor[i].y)
return false;
}
return true;
}
这里当蛇头遇到边界时,我直接在改变后进行边界判断。而蛇头碰到蛇身则是用一个循环进行判断,碰到了就返回 false。因为我各个功能都是模块化的,在使用这条函数时,用一个判断语句就行。所以我只要返回 false ,其实就会实现该局失败的函数,你们则会看到这张图

首先我们要先简单知道两个函数
- kbhit() 函数
- 功能及返回值:检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
- 包含头文件:
<conio.h>
- getch() 函数
- 功能:从控制台读取一个字符,但不显示在屏幕上
- 包含头文件:
<conio.h>
所以首先要判断我们的键盘上是否有输入,没有就下一步,有就将从键盘上读取的字符进行判断,可以使用一个 switch 语句。上代码!
void keyControl()
{
if (_kbhit())
{
switch (_getch())
{
case ‘W’:
case ‘w’:
case 72:
if (snake.dir != DOWN)
snake.dir = UP;
break;
case ‘S’:
case ‘s’:
case 80:
if (snake.dir != UP)
snake.dir = DOWN;
break;
case ‘A’:
case ‘a’:
case 75:
if (snake.dir != RIGHT)
snake.dir = LEFT;
break;
case ‘D’:
case ‘d’:
case 77:
if (snake.dir != LEFT)
snake.dir = RIGHT;
break;
case ’ ':
while (_getch() != ’ '); //给读入的空格一个死循环,卡住程序
break;
}
}
}
其中我们会发现每个方向都加了一个 if 条件语句,理由很简单,小蛇本来是向左移动的,那我们能直接改变方向让他向右移动吗?程序是可以的,嘿嘿,但是逻辑上确不行,所以需要加一个判断语句。
这里我们只要蛇挨着食物的范围就可以吃掉呗。如果吃了就重新生成新的食物的参数。就直接上代码啦!
void Eat()
{
if (food.flag && snake.coor[0].x >= food.x - food.r && snake.coor[0].x <= food.x + food.r && snake.coor[0].y >= food.y - food.r && snake.coor[0].y <= food.y + food.r)
{
food.flag = false;
//根据食物的大小不同,蛇吃了增加到长度也将不同
switch (food.r / 5)
{
case 1:
snake.size += 1;
break;
case 2:
snake.size += 2;
break;
case 3:
snake.size += 3;
break;
default:
break;
}
}
if (!food.flag)
{
food.x = rand() % width;
food.y = rand() % heigth;
food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
food.r = rand() % 15 + 5;
food.flag = true;
}
}
这就可以直接上代码啦!
void gameOver()
{
initgraph(width, heigth);
loadimage(&img3, “图3.jpg”, width, heigth);
putimage(0, 0, &img3);
}