
肝了一晚上终于做出来了!不容易呀
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<time.h>
typedef struct _SNAKE
{
int x;
int y;
struct _SNAKE* next;
}Snake;
typedef struct FOOD
{
int x;
int y;
}food;
extern Snake* g_phead = NULL;
extern food* Food = NULL;
volatile int gamePaused = 0;
void GameStart();
void Welcome();
void creatmap();
void gotoxy(int x,int y);
void initsnake();
void movesnake(int dir);
void rungame();
void initfood(int n);
void drawfood();
int isSnakeAt(int x, int y);
enum Direction { UP = 72, DOWN = 80, LEFT = 75, RIGHT = 77 };
int main()
{
srand((unsigned int)time(NULL));
GameStart();
rungame();
return 0;
}
void GameStart()
{
system("mode con cols=300 lines=200");
Welcome();
creatmap();
initsnake();
initfood(20); // 初始化食物
}
void Welcome()
{
printf("\n\n\n\n\n\n");
printf("\t\t\t\t ================================================= \n");
printf("\t\t\t\t = \t\t\t\t\t\t = \n");
printf("\t\t\t\t = \t\t\t\t\t\t = \n");
printf("\t\t\t\t = \t\t欢迎来到贪吃蛇世界\t\t = \n");
printf("\t\t\t\t = \t\t\t\t\t\t = \n");
printf("\t\t\t\t = \t\t游戏开发者:Ynchen.\t\t = \n");
printf("\t\t\t\t = \t\t\t\t\t\t = \n");
printf("\t\t\t\t = \t\t\t\t\t\t = \n");
printf("\t\t\t\t ================================================= \n");
system("pause");
system("cls");
}
void creatmap()
{
int n;
printf("请输入你要创建的地图大小n,输入30体验最佳:");
// system("cls");
if (scanf("%d", &n) != 1)
{
printf("creatmap");
return;
}
initfood(n);
for (int i = 0;i < 2*(n+6); i+=2)
{
gotoxy(i, 0);
printf("■");
gotoxy(i, n-1);
printf("■");
}
for (int i = 0; i < n; i ++)
{
gotoxy(0,i);
printf("■");
gotoxy(2*(n-1),i);
printf("■");
}
for (int i = 0; i < n; i++)
{
gotoxy(0, i);
printf("■");
gotoxy(2 * (n +5), i);
printf("■");
gotoxy(60, 10);
printf("加速:+");
gotoxy(60, 14);
printf("减速:-");
gotoxy(60, 2);
printf("分数:");
gotoxy(60, 6);
printf("暂停:p");
gotoxy(60, 17);
printf("这是一条神");
gotoxy(60, 18);
printf("奇的小蛇能");
gotoxy(60, 19);
printf("够随时退后");
gotoxy(60, 20);
printf("还可以吃墙");
gotoxy(60, 21);
printf("壁(不建议)");
}
}
void gotoxy(int x,int y)
{
COORD pos = { (SHORT)x, (SHORT)y };
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
}
void initsnake()//链表的应用
{
Snake*temp = (Snake*)malloc(sizeof(Snake));
if (temp == NULL) {
printf("内存分配失败\n");
return;
}
temp->x = 20;
temp->y = 15;
temp->next = NULL;
g_phead = temp;
for (int i = 1; i <= 3; i++)
{
Snake*p = (Snake*)malloc(sizeof(Snake));
if (p == NULL) {
printf("内存分配失败\n");
return;
}
p->x = 20 + 2 * i;
p->y = 15;
p->next = NULL;
temp->next = p;
temp=p;
}
temp = g_phead;
while (temp != NULL)
{
gotoxy(temp->x,temp->y);
printf("●");
temp = temp->next;
}
}
void movesnake(int dir) {
Snake* p = g_phead;
while (p->next != NULL) { // 找到蛇尾
p = p->next;
}
Snake* temp = (Snake*)malloc(sizeof(Snake));
if (temp == NULL) {
printf("内存分配失败\n");
return;
}
temp->next = NULL;
if (dir == UP) {
temp->x = p->x;
temp->y = p->y - 1;
}
else if (dir == DOWN) {
temp->x = p->x;
temp->y = p->y + 1;
}
else if (dir == LEFT) {
temp->x = p->x - 2;
temp->y = p->y;
}
else if (dir == RIGHT) {
temp->x = p->x + 2;
temp->y = p->y;
}
p->next = temp;
gotoxy(g_phead->x, g_phead->y);
printf(" "); // 清除蛇头的旧位置
gotoxy(temp->x, temp->y);
printf("●");
Snake* toDelete = g_phead;
g_phead = g_phead->next;
free(toDelete);
}
void rungame() {
int dir = RIGHT;
int score = 0;
int lastScore = 0;
int lastFoodX = -1;
int lastFoodY = -1;
int speed = 500;
while (1) {
if (_kbhit()) {
char ch = _getch();
switch (ch) {
case 'w': dir = UP; break;
case 's': dir = DOWN; break;
case 'a': dir = LEFT; break;
case 'd': dir = RIGHT; break;
case '=': speed = max(100, speed - 100); break; // 增加速度
case '-': speed = min(1000, speed + 100); break; // 减少速度
case 'p': // 按下 'P' 键暂停或恢复游戏
case 'P': gamePaused = ~gamePaused; break; // 切换暂停状态
}
}
if (!gamePaused)
{ // 如果游戏没有暂停,更新游戏状态
movesnake(dir);
Snake* current = g_phead;
while (current->next != NULL)
{
if (current->next->x == Food->x && current->next->y == Food->y) {
score += 5; // 增加分数
Snake* newTail = (Snake*)malloc(sizeof(Snake));
if (newTail == NULL) {
printf("内存分配失败\n");
return;
}
Snake* current = g_phead;
while (current->next != NULL) {
current = current->next;
}
newTail->x = current->x; // 新节点的初始位置与蛇尾相同
newTail->y = current->y;
newTail->next = NULL;
current->next = newTail; // 将新节点添加到蛇尾
initfood(30); // 重新生成食物
break;
}
current = current->next;
}
}
// 更新蛇头位置
gotoxy(g_phead->x, g_phead->y);
printf("●");
// 更新食物位置
if (Food->x != lastFoodX || Food->y != lastFoodY) {
gotoxy(lastFoodX, lastFoodY);
printf(" ");
gotoxy(Food->x, Food->y);
printf("*");
lastFoodX = Food->x;
lastFoodY = Food->y;
}
// 更新分数
if (score != lastScore)
{
gotoxy(66, 2);
printf("%d", score);
lastScore = score;
}
Sleep(speed);
}
}
void initfood(int n) {
int m = 0;
int k = 0;
do {
m = 1+rand() % (n-2); // 生成0~n-1的随机数
k = 1+rand() % (n-2); // 生成0~n-1的随机数
} while (isSnakeAt(m, k) || isSnakeAt(m + 1, k) || isSnakeAt(m, k + 1) || isSnakeAt(m + 1, k + 1));
if (Food != NULL) {
gotoxy(Food->x, Food->y); // 清除旧食物的位置
printf(" ");
free(Food); // 释放旧食物节点的内存
}
Food = (food*)malloc(sizeof(food));
if (Food == NULL) {
printf("内存分配失败\n");
return;
}
Food->x = m * 2; // 将坐标调整为实际的显示坐标
Food->y = k;
drawfood(); // 重新绘制食物
}
void drawfood() {
if (Food != NULL) {
gotoxy(Food->x, Food->y);
printf("*");
}
}
int isSnakeAt(int x, int y)
{
Snake* temp = g_phead;
while (temp != NULL)
{
if (temp->x == x && temp->y == y)
{
return 1; // 蛇头在食物位置
}
temp = temp->next;
}
return 0; // 蛇头不在食物位置
}