#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>
#define MAP_HEIGHT 30
#define MAP_WIDE 30
#define SIZE 16
#define SPEED 200
//定义蛇的结点
typedef struct Snakes
{
int x;//蛇的结点的位置坐标
int y;
struct Snakes *next;
}snake;
snake *head, *tail;
//定义食物的结构
struct Food
{
int x;
int y;
}food;
int grow = 0; //grow =0 表示没吃到食物,grow = 1表示吃到食物
int score = 0;
char ch = 'a';//初始方向向左
void DrawMap()//打印地图
{
setbkcolor(YELLOW);
cleardevice(); //调用清屏cleardevice用背景色刷新背景
for (int i = 0; i < MAP_WIDE; i++)
{
setfillcolor(BLUE);
//上边框
fillrectangle(i*SIZE, 0, (i + 1)*SIZE, SIZE);
//下边框
fillrectangle(i*SIZE, (MAP_HEIGHT - 1)*SIZE, (i + 1)*SIZE, MAP_HEIGHT*SIZE);
}
for (int i = 0; i < MAP_HEIGHT; i++)
{
setfillcolor(BLUE);
//左边框
fillrectangle(0, i*SIZE, SIZE, (i + 1)*SIZE);
//右边框
fillrectangle((MAP_WIDE - 1)*SIZE, i*SIZE, MAP_WIDE*SIZE, (i + 1)*SIZE);
}
}
//打印结点
void PrintNode(int x, int y)
{
setfillcolor(RED);
fillcircle(x*SIZE, y*SIZE, SIZE / 2);
setcolor(WHITE);
circle(x*SIZE, y*SIZE, SIZE / 2);
}
//删除结点
void DeleteNode(int x,int y)
{
setfillcolor(YELLOW);
fillcircle(x*SIZE, y*SIZE, SIZE / 2);
setcolor(YELLOW);
circle(x*SIZE, y*SIZE, SIZE / 2);
}
void InitMap()
{
//初始化蛇
head = (snake*)malloc(sizeof(snake));
head->x = (MAP_WIDE) / 2 ;
head->y = (MAP_HEIGHT) / 2 ;
snake *p = (snake*)malloc(sizeof(snake));
snake *q = (snake*)malloc(sizeof(snake));
p->x = head->x+1;
p->y = head->y;
q->x = head->x + 2;
q->y = head->y;
head->next = p;
p->next = q;
tail = q;
tail->next = NULL;
snake *temp = head;
while (temp != NULL)//打印出所有结点
{
PrintNode(temp->x, temp->y);
temp = temp->next;
}
//初始化食物
srand((int)time(NULL));
food.x = rand() % (MAP_WIDE - 2) + 2;
food.y = rand() % (MAP_HEIGHT - 2) + 2;
PrintNode(food.x, food.y);
}
void UpdataFood()
{
//如果蛇的结点与食物的坐标相等了,则需要创造新的食物
snake *judge = head;
while(judge->next != NULL)//遍历所有结点
{
if (judge->x == food.x&&judge->y == food.y)
{
food.x = rand() % (MAP_WIDE - 2) + 2; //生成2~MAP_WIDE - 2的随机数
food.y = rand() % (MAP_HEIGHT - 2) + 2; //生成2~MAP_HEIGHT - 2的随机数
PrintNode(food.x, food.y);
score++;
grow = 1;
break;
}
judge = judge->next;
}
}
void ChangeBody()
{
snake *p = head;
int midx, midy, _midx, _midy;
midx = p->x;
midy = p->y;
while (p->next != NULL)
{
_midx = p->next->x;
_midy = p->next->y;
p->next->x = midx;
p->next->y = midy;
midx = _midx;
midy = _midy;
p = p->next;
}
}
void MoveSnake()
{
char oldch = ch;//记录原来的方向
if (_kbhit())
{
ch = _getch();//新的方向
}
//控制方向:向左的时候不能向右转,向上的时候不能向下,向右不能向左,向下不能向上
if ((ch == 'd'||ch == 'D')&&(oldch == 'a'||oldch == 'A'))
//保持原来的方向不变
ch = oldch;
if ((oldch == 'w' || oldch == 'W') && (ch == 'S' || ch == 's'))
ch = oldch;
if ((oldch == 'd' || oldch == 'D') && (ch == 'A' || ch == 'a'))
ch = oldch;
if ((oldch == 'S' || oldch == 's' && ch == 'w' || ch == 'W'))
ch = oldch;
if (ch != 's'&& ch != 'S'&&ch != 'W'&&ch != 'w'&&ch != 'a'&&ch != 'A'&&ch != 'd'&&ch != 'D')
ch = oldch;
//先清空所有结点,再打印,实现动态效果
snake *p = head;
while (p != NULL)
{
DeleteNode(p->x, p->y);
p = p->next;
}
//记录下尾结点的坐标,为吃到食物生成新结点做准备
int a = tail->x, b = tail->y;
//除头结点外 ,剩余结点前面结点的坐标赋值给后面的结点
ChangeBody();
//更新头结点的坐标
switch (ch)
{ //向右边转
case 'd':
case 'D':
head->x += 1;
break;
//左转
case 'a':
case 'A':
head->x -=1;
break;
//向上
case 'w':
case 'W':
head->y--;
break;
//向下
case 's':
case 'S':
head->y++;
break;
default:
break;
}
//如果吃到食物,就用尾插法插入一个结点
if (grow)
{
snake *newnode;
newnode = (snake*)malloc(sizeof(snake));
newnode->x = a;
newnode->y = b;
tail->next = newnode;
tail = newnode;//更新尾结点
tail->next = NULL;
grow = 0;//更新grow的值
}
//重新打印所有结点
p = head;
while (p != NULL)
{
PrintNode(p->x, p->y);
p = p->next;
}
Sleep(SPEED);//控制速度
}
bool Finish()//判断是否结束
{
//蛇撞墙,或者蛇头撞到身上,则游戏结束
if (head->x <= 1 || head->x >= (MAP_WIDE - 1) || head->y <=1 || head->y >= (MAP_HEIGHT-1))
return 0;
snake *p = head->next;
while (p != NULL)
{
if (head->x == p->x&&head->y == p->y)
return 0;
p = p->next;
}
return 1;
}
int main()
{
initgraph(640,480);
DrawMap();
InitMap();
while (Finish())
{
MoveSnake();
UpdataFood();
}
printf("游戏结束!\n您的得分为:%d", score * 10);
_getch();
}
kvvukvkvkvkvk
最新推荐文章于 2024-09-02 16:35:28 发布
这篇文章详细描述了一个使用C语言编写的基于图形库的蛇游戏,包括地图绘制、蛇的移动、食物生成以及游戏结束条件的判断。通过控制台输入改变蛇的移动方向,游戏目标是吃到食物并尽可能避免碰撞边界或自身身体。
摘要由CSDN通过智能技术生成