赞
踩
本篇基于Esayx图形库的基础上,在Visual Studio编译器上运行,主要通过构建各个不同功能的函数(面向过程)来实现这款经典的小游戏———贪吃蛇。
//该函数用于绘制出一个网格出来
void paintGrid();//该函数用于绘制出一个蛇
void paintSnake(node* snake, int n);//该函数将依次移动蛇节头并根据前进方向设置蛇头
//以此来控制蛇的移动
node snakeMove(node* snake, int length, int direction);//该函数通过键盘输入的方式来调整蛇移动的方向
void changDirection(enum direction* p);//该函数用于在画布中创建出一个食物类型
node creatFood(node* snake, int length);//该函数用于在画布中生成一个食物
void paintFood(node* food);//该函数用于判断游戏是否结束
bool isGameover(node* snake, int length);//该函数用于将游戏数据初始化
void reset(node* snake, int* plength, enum direction* pd);
1.定义结构体以及一些枚举变量、常量
- //我们创建的画布大小是600*800大小的,将其分成宽为40的小矩形
- #define NOOD_WIDTH 40
-
- //该枚举类型分别对应四个方向,用键盘上的wsad来表示上下左右
- enum direction
- {
- eUp,
- eDown,
- eLeft,
- eRight
- };
-
- //该结构node用于记录蛇的每一个节点
- typedef struct
- {
- int x;
- int y;
- }node;
2.//该函数用于绘制出一个网格出来
void paintGrid();
- void paintGrid()
- {
- setlinecolor(WHITE);
- for (int x = 0; x < 800; x += NOOD_WIDTH)//以这个宽度为间距进行画竖线
- {
- line(x, 0, x, 600);//画竖线
- }
- for (int y = 0; y < 600; y += NOOD_WIDTH)//以这个宽度为间距进行画横线
-
- {
- line(0, y, 800, y);//画横线
- }
- }
3.//该函数用于绘制出一个蛇
void paintSnake(node* snake, int n);
- void paintSnake(node* snake, int n)
- {
- int left, top, right, bottom;
- for (int i = 0; i < n; i++)
- {
- left = snake[i].x * NOOD_WIDTH;//*(snake + i).x
- top = snake[i].y * NOOD_WIDTH;
- right = (snake[i].x + 1) * NOOD_WIDTH;
- bottom = (snake[i].y + 1) * NOOD_WIDTH;
- setlinecolor(BLACK);
- fillrectangle(left, top, right, bottom);
- }
- }
4.//该函数将依次移动蛇节头并根据前进方向设置蛇头
//以此来控制蛇的移动
node snakeMove(node* snake, int length, int direction);
- node snakeMove(node* snake, int length, int direction)
- {
- node tail = snake[length - 1];
- //用一个循环将数组中的元素从后往前依次进行覆盖
- for (int i = length - 1; i > 0; i--)
- {
- snake[i] = snake[i - 1];//将前一个节点覆盖后一个节点
- }
- node newhead = snake[0];
- if (direction == eUp)
- {
- newhead.y--;//在原蛇头的基础上进行修改
- }
- if (direction == eDown)
- {
- newhead.y++;
- }
- if (direction == eLeft)
- {
- newhead.x--;
- }
- if (direction == eRight)
- {
- newhead.x++;
- }
- snake[0] = newhead;//最后在把修改后的蛇头数据赋值给原数组的首元素
- return tail;
- }
5. //该函数通过键盘输入的方式来调整蛇移动的方向
void changDirection(enum direction* p);
- void changDirection(enum direction* p)
- {
- if (_kbhit() != 0)
- {
- char c = _getch();
- switch (c)
- {
- case 'a':
- if(*p != eRight)
- *p = eLeft;
- break;
- case 'd':
- if (*p != eLeft)
- *p = eRight;
- break;
- case 'w':
- if (*p != eDown)
- *p = eUp;
- break;
- case's':
- if (*p != eUp)
- *p = eDown;
- break;
- }
- }
- }
6.//该函数用于在画布中创建出一个食物类型
node creatFood(node* snake, int length);
- node creatFood(node* snake, int length)
- {
- //先在画布圈定的范围之内随机生成一个食物点
- node food;
- //然后用一个死循环来对食物点进行检验(不能与蛇的身体进行重合)
- while (1)
- {
- food.x = rand() % (800 / NOOD_WIDTH);
- food.y = rand() % (600 / NOOD_WIDTH);
- int i = 0;
- for (i = 0; i < length; i++)
- {
- if (food.x == snake[i].x && food.y == snake[i].y)
- break;
- }
- if (i < length)
- continue;
- else
- break;
- }
- return food;
- }
7.//该函数用于在画布中生成一个食物
void paintFood(node* food);
- void paintFood(node* food)
- {
- int left, top, right, bottom;
- left = food->x * NOOD_WIDTH;//*(snake + i).x
- top = food->y* NOOD_WIDTH;
- right = (food->x + 1) * NOOD_WIDTH;
- bottom = (food->y + 1) * NOOD_WIDTH;
- setfillcolor(YELLOW);
- solidrectangle(left, top, right, bottom);
- setfillcolor(WHITE);
- }
8.//该函数用于判断游戏是否结束
bool isGameover(node* snake, int length);
- bool isGameover(node* snake, int length)
- {
- if (snake[0].x < 0 || snake[0].x>800 / NOOD_WIDTH)
- {
- return true;
- }
- if (snake[0].y < 0 || snake[0].y>600 / NOOD_WIDTH)
- {
- return true;
- }
- for (int i = 1; i < length; i++)
- {
- if (snake[0].x == snake[i].x && snake[0].y == snake[i].y)
- return true;
- }
- return false;
- }
9. //该函数用于将游戏数据初始化
void reset(node* snake, int* plength, enum direction* pd);
- void reset(node* snake, int* plength, enum direction* pd)
- {
- for (int i = 0; i < 5; i++)
- {
- for (int j = 5; j > 0; j--)
- {
- snake[i].x = j;
- }
- snake[i].y = 7;
- }
- *plength = 5;
- *pd = eRight;
- }
三 主函数部分
- int main()
- {
- initgraph(800, 600);
- setbkcolor(RGB(164, 225, 202));
- cleardevice();
- node snake[100] = { {5,7},{4,7},{3,7},{2,7},{1,7} };
- int length = 5;
- enum direction d = eRight;
- srand(unsigned int(time(NULL)));//用当前时间作为随机数种子
- node food = creatFood(snake,length);
- while (1)
- {
- cleardevice();
- paintGrid();
- paintSnake(snake, length);
- paintFood(&food);
- Sleep(500);
-
- changDirection(&d);
- node last_tail = snakeMove(snake, length, d);
- if (snake[0].x == food.x && snake[0].y == food.y)
- {
- if (length < 100)
- {
- snake[length] = last_tail;
- length++;
- }
- food = creatFood(snake, length);
- }
- if (isGameover(snake, length) == true)
- {
- reset(snake, &length, &d);
- food = creatFood(snake, length);
- }
- }
-
- getchar();
- closegraph();
- return 0;
- }
四 完整代码
完整代码如下:
- #include <easyx.h>
- #include <stdio.h>
- #include <conio.h>
- #include <time.h>
- #define NODE_WIDTH 40
- // 节点
- typedef struct {
- int x;
- int y;
- }node;
- enum direction
- {
- eUp,
- eDown,
- eLeft,
- eRight
- };
- void paintGrid()
- {
- setlinecolor(WHITE);
- for (int x = 0; x < 800; x += NOOD_WIDTH)
- {
- line(x, 0, x, 600);//画竖直线段
- }
- for (int y = 0; y < 600; y += NOOD_WIDTH)
- {
- line(0, y, 800, y);//画竖直线段
- }
- }
-
- void paintSnake(node* snake, int n)
- {
- int left, top, right, bottom;
- for (int i = 0; i < n; i++)
- {
- left = snake[i].x * NOOD_WIDTH;//*(snake + i).x
- top = snake[i].y * NOOD_WIDTH;
- right = (snake[i].x + 1) * NOOD_WIDTH;
- bottom = (snake[i].y + 1) * NOOD_WIDTH;
- setlinecolor(BLACK);
- fillrectangle(left, top, right, bottom);
- }
- }
-
- node snakeMove(node* snake, int length, int direction)
- {
- node tail = snake[length - 1];
- //用一个循环将数组中的元素从后往前依次进行覆盖
- for (int i = length - 1; i > 0; i--)
- {
- snake[i] = snake[i - 1];//将前一个节点覆盖后一个节点
- }
- node newhead = snake[0];
- if (direction == eUp)
- {
- newhead.y--;//在原蛇头的基础上进行修改
- }
- if (direction == eDown)
- {
- newhead.y++;
- }
- if (direction == eLeft)
- {
- newhead.x--;
- }
- if (direction == eRight)
- {
- newhead.x++;
- }
- snake[0] = newhead;//最后在把修改后的蛇头数据赋值给原数组的首元素
- return tail;
- }
-
- void changDirection(enum direction* p)
- {
- if (_kbhit() != 0)
- {
- char c = _getch();
- switch (c)
- {
- case 'a':
- if(*p != eRight)
- *p = eLeft;
- break;
- case 'd':
- if (*p != eLeft)
- *p = eRight;
- break;
- case 'w':
- if (*p != eDown)
- *p = eUp;
- break;
- case's':
- if (*p != eUp)
- *p = eDown;
- break;
- }
- }
- }
-
- node creatFood(node* snake, int length)
- {
- //先在画布圈定的范围之内随机生成一个食物点
- node food;
- //然后用一个死循环来对食物点进行检验(不能与蛇的身体进行重合)
- while (1)
- {
- food.x = rand() % (800 / NOOD_WIDTH);
- food.y = rand() % (600 / NOOD_WIDTH);
- int i = 0;
- for (i = 0; i < length; i++)
- {
- if (food.x == snake[i].x && food.y == snake[i].y)
- break;
- }
- if (i < length)
- continue;
- else
- break;
- }
- return food;
- }
-
- void paintFood(node* food)
- {
- int left, top, right, bottom;
- left = food->x * NOOD_WIDTH;//*(snake + i).x
- top = food->y* NOOD_WIDTH;
- right = (food->x + 1) * NOOD_WIDTH;
- bottom = (food->y + 1) * NOOD_WIDTH;
- setfillcolor(YELLOW);
- solidrectangle(left, top, right, bottom);
- setfillcolor(WHITE);
- }
-
- bool isGameover(node* snake, int length)
- {
- if (snake[0].x < 0 || snake[0].x>800 / NOOD_WIDTH)
- {
- return true;
- }
- if (snake[0].y < 0 || snake[0].y>600 / NOOD_WIDTH)
- {
- return true;
- }
- for (int i = 1; i < length; i++)
- {
- if (snake[0].x == snake[i].x && snake[0].y == snake[i].y)
- return true;
- }
- return false;
- }
-
- void reset(node* snake, int* plength, enum direction* pd)
- {
- for (int i = 0; i < 5; i++)
- {
- for (int j = 5; j > 0; j--)
- {
- snake[i].x = j;
- }
- snake[i].y = 7;
- }
- *plength = 5;
- *pd = eRight;
- }
- int main()
- {
- initgraph(800, 600);
- setbkcolor(RGB(164, 225, 202));
- cleardevice();
- node snake[100] = { {5,7},{4,7},{3,7},{2,7},{1,7} };
- int length = 5;
- enum direction d = eRight;
- srand(unsigned int(time(NULL)));//用当前时间作为随机数种子
- node food = creatFood(snake,length);
- while (1)
- {
- cleardevice();
- paintGrid();
- paintSnake(snake, length);
- paintFood(&food);
- Sleep(500);
-
- changDirection(&d);
- node last_tail = snakeMove(snake, length, d);
- if (snake[0].x == food.x && snake[0].y == food.y)
- {
- if (length < 100)
- {
- snake[length] = last_tail;
- length++;
- }
- food = creatFood(snake, length);
- }
- if (isGameover(snake, length) == true)
- {
- reset(snake, &length, &d);
- food = creatFood(snake, length);
- }
- }
-
- getchar();
- closegraph();
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。