#include<stdio.h>
#include<graphics.h>//easyx库
#include <time.h>
#include<malloc.h>
#define Width 800//游戏画布宽
#define Heigh 800//游戏画布高
#define FOOD_SIZE 10//食物大小
#define SNAKE_SIZE 16//蛇身大小
#define SPEED 4 //速度 数字越大速度越快
/*
1、可以穿墙
2、只有自己咬到自己才能死掉
3、可以自己修改功能
没有找到合适的贪吃蛇贴图,所以没有上贴图用单调的颜色代替的,当然如果自己有的话可以置换成自己喜欢的贴图
用到easyx图形库,如果编译器上没有easyx库请去easyx官网下载自行安装
*/
typedef struct Food
{//食物坐标
int x, y;
}Food;
typedef struct Body
{//双链表 蛇体
int x, y;
int direct;
struct Body * pnext;
struct Body* prenext;
} Body;
typedef struct Snake
{//蛇头
Body *body;
int length;
} Snake;
enum Direct {//控制的按键
Up='W',
Down='S',
Left='A',
Right='D'
};
Food food;
//移动设置
void Remove(Snake* S, int direct) {
int x, y;
Body* temp = S->body, *pnext =NULL;
//蛇身移动
while (!temp->pnext == NULL)//找到蛇尾
temp = temp->pnext;
pnext = temp->prenext;
for (;!pnext==NULL;pnext=pnext->prenext)
{//先让蛇尾一步步向前移
temp->x = pnext->x;
temp->y = pnext->y;
temp = pnext;
}
//蛇头移动
switch (direct)
{
case Up:
S->body->y -= SPEED;
S->body->direct = direct;
break;
case Down:
S->body->y += SPEED;
S->body->direct = direct;
break;
case Left:
S->body->x -= SPEED;
S->body->direct = direct;
break;
case Right:
S->body->x += SPEED;
S->body->direct = direct;
break;
}
//穿墙设置
S->body->y = (S->body->y+ Heigh) % Heigh;
S->body->x = (S->body->x + Width) % Width;
//设置蛇头方向
direct = S->body->direct;
}
//方向判断
void Direct(Snake* S, int direct)
{
bool flat = false;
int directs = S->body->direct;
//判断方向是否为当前方向的反向,如果为当前方向的反方向就不接受新的方向
switch (direct)
{
case Up:
if (S->body->direct != Down)
flat = true;
break;
case Down:
if (S->body->direct != Up)
flat = true;
break;
case Left:
if (S->body->direct != Right)
flat = true;
break;
case Right:
if (S->body->direct != Left)
flat = true;
break;
}
if (flat)
directs = direct;
Remove(S, directs);
}
//判断是否吃到食物或者死了
bool Determine(Snake* S)
{
Body* temp = NULL;
Body* temp_Pnext = S->body;
int x = S->body->x - food.x;
int y = S->body->y - food.y;
if (x < 0)
x = -x;
if (y < 0)
y = -y;
//判断是否吃到食物
if (x<(FOOD_SIZE+ SNAKE_SIZE) &&y<(FOOD_SIZE+ SNAKE_SIZE))
{//设置新增长度
temp = (Body*)malloc(sizeof(Body));
while (!temp_Pnext->pnext == NULL)
temp_Pnext = temp_Pnext->pnext;
temp_Pnext->pnext = temp;
temp->prenext = temp_Pnext;
temp->pnext = NULL;
//设置新增身体
switch (temp_Pnext->direct)
{//新增身体坐标
case Up:
temp->x = temp_Pnext->x;
temp->y = temp_Pnext->y + SNAKE_SIZE;
break;
case Down:
temp->x = temp_Pnext->x;
temp->y = temp_Pnext->y - SNAKE_SIZE;
break;
case Left:
temp->x = temp_Pnext->x + SNAKE_SIZE;
temp->y = temp_Pnext->y;
break;
case Right:
temp->x = temp_Pnext->x - SNAKE_SIZE;
temp->y = temp_Pnext->y;
break;
}
temp->x = (temp->x + Width) % Width;
temp->y = (temp->x + Heigh) % Heigh;
temp->direct = temp_Pnext->direct;
S->length++;
food.x = rand() % Width;
food.y = rand() % Heigh;
printf("吃到食物\n");
}
//判断是否吃到自身
temp = S->body->pnext;
while (!temp == NULL)
{
if ((S->body->x == temp->x) && (S->body->y == temp->y))
{
printf("一不小心咬到了自己 游戏结束\n");
return true;
}
temp = temp->pnext;
}
return false;
}
//绘制图案
void DrawSnake(Snake *S)
{
Body* temp = S->body->pnext;
BeginBatchDraw();
cleardevice();
setbkcolor(RGB(0xE6, 0xE6, 0xFA));
printf("开始\n");
//绘制蛇头
setfillcolor(RGB(0x00,0x64,0x00));
solidcircle(S->body->x, S->body->y, SNAKE_SIZE/2);
//绘制蛇身
for (; !temp == NULL; temp = temp->pnext)
{
setfillcolor(RGB(0x00, 0xEE, 0x76));
solidcircle(temp->x , temp->y, SNAKE_SIZE/2);
}
printf("结束\n");
setfillcolor(RGB(0xEE, 0xDD, 0x82));
solidcircle(food.x, food.y, FOOD_SIZE);
}
//接收按键
char Press_Key( )
{
ExMessage kebody;
peekmessage(&kebody, EM_KEY | EM_MOUSE);
if (kebody.message == WM_KEYDOWN)
{
if (kebody.vkcode == 'W')
return Up;
if (kebody.vkcode == 'S')
return Down;
if (kebody.vkcode == 'A')
return Left;
if (kebody.vkcode == 'D' )
return Right;
}
return 0;
}
//开始游戏
bool play_Snake(Snake* S)
{
int direct = 0;
DrawSnake(S);
if(!(direct= Press_Key()))
direct = S->body->direct;
Direct(S, direct);
EndBatchDraw();
Sleep(10);
if (Determine(S))
return false;
return true;
}
//初始化游戏
Snake* Init_Snake()
{
srand(time(NULL));
Snake* S = (Snake*)malloc(sizeof(Snake));
if (S == NULL)
return NULL;
S->body = (Body*)malloc(sizeof(Body));
S->body->x = 0;
S->body->y = 0;
S->body->direct = Right;
S->body->pnext = NULL;
S->body->prenext = NULL;
S->length=1;
food.x = rand() % 800;
food.y = rand() % 800;
return S;
}
//主函数
void main()
{
initgraph(Width, Heigh);
Snake* S = Init_Snake();
while (play_Snake(S))
{
printf("蛇头坐标x:%d 坐标y:%d 长度为:%d\n", S->body->x, S->body->y,S->length);
}
system("pause");
closegraph();
}
贪吃蛇实现
于 2024-05-01 22:40:26 首次发布