C语言贪吃蛇—基于EasyX图形库
程序员文章站
2024-03-18 10:04:04
...
一、编译环境
1、VS2017(VC++6.0也可以)
2、EasyX库(C/C++的图形库)
EasyX Library for C++ (Ver:2018春分版)
http://www.easyx.cn
graphics.h
二、代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
typedef struct body {
int x, y; //每节蛇身坐标
struct body *pre, *next; //双向链表
}SnakeBody;
typedef struct snake { //用线性表存储蛇的资料
SnakeBody *head, *tail; //链式线性表
char headDirection; // sedf 四个键表示左上下右四个方向
char tailDirection;
int len; //表长
} Snake;
Snake * createsanke() //生成空的蛇
{
Snake * s;
s = (Snake *)malloc(sizeof(Snake));
s->head = NULL;
s->tail = NULL;
s->len = 0;
return s;
}
void initbeginmap(int width, int height) //绘制背景
{
int i = 0, j = 0;
setlinestyle(PS_SOLID, 1);
setcolor(BLUE);
for (i = 0; i <= height; i++)
line(0, i * 10, 640, i * 10);
for (i = 0; i <= width; i++)
line(i * 10, 0, i * 10, 480);
setcolor(BLACK);
setfillcolor(BLACK);
solidrectangle(140,130,150,300);
solidrectangle(200,80,350,90);
solidrectangle(400,300,410,130);
solidrectangle(200,340,350,350);
}
void initSnake(Snake *s, int x, int y, int len) //生成长度为3,x,y为起点的蛇
{
int i;
SnakeBody *newbody;
s->len = len;
s->headDirection = 'e';
//s->tailDirection='e';
setlinestyle(PS_SOLID, 1);
setcolor(YELLOW);
setfillcolor(GREEN);
for (i = 0; i < len; i++)
{
//尾插法创建双向链表(蛇身的数据:坐标)
newbody = (SnakeBody *)malloc(sizeof(SnakeBody));
newbody->next = NULL;
newbody->pre = NULL;
newbody->x = x;
newbody->y = y + i;
if (i == 0)
{ //第一个节点创建
s->head = s->tail = newbody;
}
else
{ //其他节点创建
newbody->pre = s->tail;
s->tail->next = newbody;
s->tail = newbody;
}
//根据蛇身坐标绘图
fillrectangle(x * 10 + 1, (y + i) * 10 + 1, x * 10 + 10 - 1, (y + i) * 10 + 10 - 1);
}
}
void putApple(int x, int y) //在指定x,y位置放一个苹果
{
setcolor(BLUE);
setfillcolor(RED);
int p = x * 10 + 5,q=y*10+5;
fillcircle(x * 10 + 5, y * 10 + 5, 5);
}
int eatTest(Snake *s, int m, int n) //判断前进路上是否碰到苹果
{
switch (s->headDirection) //探测下个位置是否是苹果
{
case 's': //蛇向左运动,则前一个位置如果是苹果,则可以吃到,返回1
if (s->head->x - 1 == m && s->head->y == n)
return 1;
break;
case 'e':
if (s->head->x == m && s->head->y - 1 == n)
return 1;
break;
case 'd':
if (s->head->x == m && s->head->y + 1 == n)
return 1;
break;
case 'f':
if (s->head->x + 1 == m && s->head->y == n)
return 1;
break;
}
return 0;
}
int moveSnake(Snake *s, int m, int n) {
//按照蛇的运行方向移动一个位置
SnakeBody * p;
int flag = 0;
if (eatTest(s, m, n) == 1)
{ //创建新的蛇头节点
p = (SnakeBody *)malloc(sizeof(SnakeBody));
p->x = m;
p->y = n;
flag = 1;
}
else
{
p = s->tail; //删除尾节点
s->tail = p->pre;
s->tail->next = NULL;
setcolor(YELLOW);
setfillcolor(GREEN);
fillrectangle(p->x * 10 + 1, (p->y) * 10 + 1, p->x * 10 + 10 - 1, (p->y) * 10 + 10 - 1);
}
s->head->pre = p;
p->pre = NULL;
p->next = s->head;
s->head = p;
// p->derect=s->headDirection;
//根据蛇的运动方向,设置蛇头(p指向的节点)坐标
if (s->headDirection == 's')
{
p->x = p->next->x - 1;
p->y = p->next->y;
}
else if (s->headDirection == 'e')
{
p->x = p->next->x;
p->y = p->next->y - 1;
}
else if (s->headDirection == 'd')
{
p->x = p->next->x;
p->y = p->next->y + 1;
}
else if (s->headDirection == 'f')
{
p->x = p->next->x + 1;
p->y = p->next->y;
}
//画蛇头
setcolor(YELLOW);
setfillcolor(GREEN);
fillrectangle(p->x * 10 + 1, (p->y) * 10 + 1, p->x * 10 + 10 - 1, (p->y) * 10 + 10 - 1);
return flag;
}
int issnakedead(Snake *s)
{
int x = s->len;
SnakeBody * p;
p = s->head->next;
if (s->head->x >= 64 || s->head->x < 0 || s->head->y >= 48 || s->head->y < 0 //判断是否碰到了边框
|| (s->head->x >= 14 && s->head->x < 15 && s->head->y >= 13 && s->head->y < 30) //是否碰到了障碍物(下面四个都是)
|| (s->head->x >= 40 && s->head->x < 41 && s->head->y >= 13 && s->head->y < 30)
|| (s->head->x >= 20 && s->head->x < 35 && s->head->y >= 8 && s->head->y < 9)
|| (s->head->x >= 20 && s->head->x < 35 && s->head->y >= 34 && s->head->y < 35))
return 1;
else if(x!=0){
while (p)
{
if (s->head->x == p->x&&s->head->y ==p-> y) //判断是否头尾相撞
return 1;
p = p->next;
x--;
}
}
else return 0;
}
int main()
{
Snake *snake = NULL;
int score = 0;
int k = 0;
int m, n, flag = 0;
char fenshu[50];
initgraph(640, 600);
srand((int)time(0));
setbkcolor(YELLOW);
cleardevice();
initbeginmap(64, 48); //设置背景
setwritemode(R2_XORPEN); // 设置 XOR 绘图模式
m = rand() % 32 + 1;
n = rand() % 20 + 1;
snake = createsanke(); //创建空蛇
initSnake(snake, 32, 24, 3); // 初始化长度为3的蛇
putApple(m, n); //设定一个固定的苹果
char c = ' ';
int speed = 250;
outtextxy(0, 550, "当前速度:");
outtextxy(300, 550, "s:向左");
outtextxy(380, 550, "f:向右");
outtextxy(460, 550, "e:向上");
outtextxy(540, 550, "d:向下");
outtextxy(300, 520, "1-7:变速");
outtextxy(380, 520, "空格:暂停");
outtextxy(480, 520, "ESC:结束游戏");
settextcolor(RED);
outtextxy(80, 550, '3');
int pause = 0;
while (1) //27为ESC键
{
// 获取按键
if (_kbhit())
{
c = _getch();
if (c == 27) break;
// 根据按键设置蛇的运动方向
switch (c)
{
case 's': //向左,原方向为上下才可以变
if (snake->headDirection == 'e' || snake->headDirection == 'd') snake->headDirection = c; break;
case 'f': //向右,原方向为上下才可以变
if (snake->headDirection == 'e' || snake->headDirection == 'd') snake->headDirection = c; break;
case 'e': //向上,原来为左右才变化
if (snake->headDirection == 's' || snake->headDirection == 'f') snake->headDirection = c; break;
case 'd': //向下,原来为左右才变化
if (snake->headDirection == 's' || snake->headDirection == 'f') snake->headDirection = c; break;
case ' ': //向下,原来为左右才变化
outtextxy(200, 500, "已暂停,按任意键继续...");
system("pause");
outtextxy(200, 500, " ");
break;
//改变蛇的移动速度(1-7)
case '1': speed = 350; outtextxy(80, 550, '1'); break;
case '2': speed = 300; outtextxy(80, 550, '2'); break;
case '3': speed = 250; outtextxy(80, 550, '3'); break;
case '4': speed = 200; outtextxy(80, 550, '4'); break;
case '5': speed = 150; outtextxy(80, 550, '5'); break;
case '6': speed = 100; outtextxy(80, 550, '6'); break;
case '7': speed = 50; outtextxy(80, 550, '7'); break;
}
}
flag = moveSnake(snake, m, n); //按照蛇的运动方向移动
settextcolor(BLUE);
outtextxy(0, 520, "得分:");
sprintf(fenshu, "%d", k);
settextcolor(RED);
outtextxy(80, 520, fenshu);
if (flag == 1)
{
setcolor(BLUE);
setfillcolor(RED);
fillcircle(m * 10 + 5, n * 10 + 5, 5);
m = rand() % 62;
n = rand() % 30;
if ((m == 14 && n >= 13 && n <= 30)
|| (m == 40 && n >= 13 && n <= 30)
|| (n == 8 && m >= 20 && m <= 35)
|| (n == 34 && m >= 20 && m <= 35))
{
m = m + 1;
n = n + 1;
}
putApple(m, n);
flag = 0;
k++;
sprintf(fenshu, "%d", k--);
settextcolor(YELLOW);
outtextxy(80, 520, fenshu);
sprintf(fenshu, "%d", k++);
settextcolor(RED);
outtextxy(80, 520, fenshu);
}
// 延时
Sleep(speed - k * 10);
if (issnakedead(snake) == 1)
{
outtextxy(200, 500, "Game Over!");
outtextxy(200, 550, "按任意键退出");
_getch();
break;
if (_kbhit())
exit(0);
}
}
closegraph();
return 0;
}
下一篇: MySQL性能分析命令