首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >贪吃蛇小游戏!童年的回忆

贪吃蛇小游戏!童年的回忆

作者头像
Ynchen
发布2025-12-21 13:40:22
发布2025-12-21 13:40:22
1290
举报

肝了一晚上终于做出来了!不容易呀

代码语言:javascript
复制
#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; // 蛇头不在食物位置
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档