前言
之前学了一点easyx图形库的使用,掌握一些基本用法后就用贪吃蛇来进行实战了,运行视频放在csdn视频那一栏了,之前的烟花也是。
1.头文件
#define _CRT_SECURE_NO_WARNINGS 1
#include<easyx.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include<stdbool.h>
#define NODE_HIGHT 40
#define NODE_WIDTH 40
typedef enum direction
{
up,
down,
left,
right,
}direction;
typedef struct node
{
int x, y;
}node;
2.源文件
#include"snack.h"
void Paintgrid()
{
for (int x = 0; x < 800; x += NODE_WIDTH)
line(x, 0, x, 600);
for (int y = 0; y < 600; y += NODE_WIDTH)
line(0, y, 800, y);
}
void PaintSnack(node* nodes, int n)
{
int left, right, top, bottom;
for (int i = 0; i < n; i++)
{
left = nodes[i].x * NODE_WIDTH;
top = nodes[i].y * NODE_WIDTH;
right = (nodes[i].x + 1) * NODE_WIDTH;
bottom = (nodes[i].y + 1) * NODE_WIDTH;
solidrectangle(left, top, right, bottom);
}
}
node* SnackMove(node* nodes, int length, int direction)
{
node x = nodes[length - 1];
for (int i = length - 1; i > 0; i--)
{
nodes[i] = nodes[i - 1];
}
node new_head = nodes[0];
if (direction == up)
new_head.y--;
if (direction == down)
new_head.y++;
if (direction == left)
new_head.x--;
if (direction == right)
new_head.x++;
nodes[0] = new_head;
return &x;
}
void playerchoice(direction* dir)
{
if (_kbhit())
switch (_getch())
{
case 'A':
case'a':
if (*dir != left)
*dir = left;
break;
case 'd':
case'D':
if (*dir != right)
*dir = right;
break;
case 'w':
case'W':
if (*dir != up)
*dir = up;
break;
case 's':
case'S':
if (*dir != down)
*dir = down;
break;
}
}
void setfood(node* food,node*nodes,int length,int* flag)
{
srand((unsigned)time(NULL));
if (*flag == 0)
{
again:
food->x = rand() % (800 / NODE_WIDTH);
food->y = rand() % (600 / NODE_HIGHT);
for (int i = 0; i < length; i++)
{
if (food->x == nodes[i].x && food->y == nodes[i].y)
goto again;
}
*flag= 1;
}
setfillcolor(YELLOW);
solidrectangle(food->x * NODE_WIDTH, food->y * NODE_HIGHT, (food->x + 1) * NODE_WIDTH, (food->y + 1) * NODE_HIGHT);
setfillcolor(WHITE);
}
bool isover(node* nodes,int length)
{
if (nodes->x >= 800/NODE_WIDTH || nodes->x < 0 || nodes->y < 0 || nodes->y>=600/NODE_HIGHT)
return true;
for (int i = 1; i < length; i++)
if (nodes->x == nodes[i].x && nodes->y == nodes[i].y)
return true;
return FALSE;
}
void reset(node* nodes, int* length, direction* dir,int*flag)
{
nodes[0] = { 5,7 };
nodes[1] = { 4,7 };
nodes[2] = { 3,7 };
nodes[3] = {2,7};
nodes[4] = {1,7};
*length = 5;
*dir = right;
*flag = 0;
}
int main()
{
srand((unsigned)time(NULL));
initgraph(800, 600);
setbkcolor(RGB(164, 225, 202));
direction dir = right;
int length = 5;
node nodes[100] = { {5,7},{4,7},{3,7},{2,7},{1,7} };//从蛇头到蛇尾
node food = { 0 };
int flag = 0;
while (1)
{
cleardevice();
Paintgrid();//初始化表格
setfood(&food, nodes, length, &flag);
PaintSnack(nodes, length);
Sleep(500);
playerchoice(&dir);
node* end = SnackMove(nodes, length, dir);
if (nodes[0].x == food.x && food.y == nodes[0].y)
{
length++;
nodes[length - 1].x = end->x;
nodes[length - 1].y = end->y;
flag = 0;
}
if (isover(nodes, length))
{
reset(nodes, &length, &dir,&flag);
}
}
closegraph();
return 0;
}
3.解析
0.创建环境
我使用的是vs编译环境和easyx图形库,貌似easyx也支持Dev,具体的下载方法可以去吧站搜索,easyx的使用在吧站也有相关 教程,包括vs的下载都有很详细的视频教程,所以就不再赘述了。
我们由于要用到随机数所以使用了<time.h><stdlib.h>头文件
关于随机数的使用若是不了解可以看看这篇博客
C语言rand函数,srand函数,time函数实现随机数,及猜数字小游戏-CSDN博客
图形库的使用需要<easyx.h>头文件
第一行的宏定义想必用vs的都知道,用来避免报错的
两个结构体是用来记录蛇的移动方向和坐标的。
#define _CRT_SECURE_NO_WARNINGS 1
#include<easyx.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include<stdbool.h>
#define NODE_HIGHT 40
#define NODE_WIDTH 40
typedef enum direction
{
up,
down,
left,
right,
}direction;
typedef struct node
{
int x, y;
}node;
我们只要知道以下几点就可以
1.把地图画出来
void Paintgrid()
{
for (int x = 0; x < 800; x += NODE_WIDTH)
line(x, 0, x, 600);
for (int y = 0; y < 600; y += NODE_WIDTH)
line(0, y, 800, y);
}
2.初始化并记录蛇的每个节点的坐标
void PaintSnack(node* nodes, int n)
{
int left, right, top, bottom;
for (int i = 0; i < n; i++)
{
left = nodes[i].x * NODE_WIDTH;
top = nodes[i].y * NODE_WIDTH;
right = (nodes[i].x + 1) * NODE_WIDTH;
bottom = (nodes[i].y + 1) * NODE_WIDTH;
solidrectangle(left, top, right, bottom);
}
}
3.随机产生食物
void setfood(node* food,node*nodes,int length,int* flag)
{
srand((unsigned)time(NULL));
if (*flag == 0)
{
again:
food->x = rand() % (800 / NODE_WIDTH);
food->y = rand() % (600 / NODE_HIGHT);
for (int i = 0; i < length; i++)
{
if (food->x == nodes[i].x && food->y == nodes[i].y)
goto again;
}
*flag= 1;
}
setfillcolor(YELLOW);
solidrectangle(food->x * NODE_WIDTH, food->y * NODE_HIGHT, (food->x + 1) * NODE_WIDTH, (food->y + 1) * NODE_HIGHT);
setfillcolor(WHITE);
}
4.蛇移动坐标随之变化
node* SnackMove(node* nodes, int length, int direction)
{
node x = nodes[length - 1];
for (int i = length - 1; i > 0; i--)
{
nodes[i] = nodes[i - 1];
}
node new_head = nodes[0];
if (direction == up)
new_head.y--;
if (direction == down)
new_head.y++;
if (direction == left)
new_head.x--;
if (direction == right)
new_head.x++;
nodes[0] = new_head;
return &x;
}
void playerchoice(direction* dir)
{
if (_kbhit())
switch (_getch())
{
case 'A':
case'a':
if (*dir != left)
*dir = left;
break;
case 'd':
case'D':
if (*dir != right)
*dir = right;
break;
case 'w':
case'W':
if (*dir != up)
*dir = up;
break;
case 's':
case'S':
if (*dir != down)
*dir = down;
break;
}
}
5.蛇吃到食物会长长
//主函数中
if (nodes[0].x == food.x && food.y == nodes[0].y)
{
length++;
nodes[length - 1].x = end->x;
nodes[length - 1].y = end->y;
flag = 0;
}
6.碰到边界或自己会死,并设置游戏重开功能
bool isover(node* nodes,int length)
{
if (nodes->x >= 800/NODE_WIDTH || nodes->x < 0 || nodes->y < 0 || nodes->y>=600/NODE_HIGHT)
return true;
for (int i = 1; i < length; i++)
if (nodes->x == nodes[i].x && nodes->y == nodes[i].y)
return true;
return FALSE;
}//主函数中
if (isover(nodes, length))
{
reset(nodes, &length, &dir,&flag);
}
7.主函数调用函数
srand((unsigned)time(NULL));
initgraph(800, 600);
setbkcolor(RGB(164, 225, 202));
direction dir = right;
int length = 5;
node nodes[100] = { {5,7},{4,7},{3,7},{2,7},{1,7} };//从蛇头到蛇尾
node food = { 0 };
int flag = 0;
while (1)
{
cleardevice();
Paintgrid();//初始化表格setfood(&food, nodes, length, &flag);
PaintSnack(nodes, length);
Sleep(500);
playerchoice(&dir);
node* end = SnackMove(nodes, length, dir);
if (nodes[0].x == food.x && food.y == nodes[0].y)
{
length++;
nodes[length - 1].x = end->x;
nodes[length - 1].y = end->y;
flag = 0;
}
if (isover(nodes, length))
{
reset(nodes, &length, &dir,&flag);
}
}
closegraph();
总结
一直想写个小游戏玩玩,现在也算是小小的玩了一把,可惜最近要复习,没有时间学图形库了,不然真希望继续做点东西。最后祝愿还没考的同学考出好成绩,考完的寒假快乐,工作的早点放假,
若是觉得这篇博客对你有帮助就点个赞支持一下博主吧,感谢!