首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从零开始手搓项目——C语言贪吃蛇(小白秒懂,含免费完整源代码及避坑指南)

从零开始手搓项目——C语言贪吃蛇(小白秒懂,含免费完整源代码及避坑指南)

作者头像
小此方
发布2025-12-24 17:36:05
发布2025-12-24 17:36:05
2710
举报
文章被收录于专栏:博客专栏博客专栏

◆ 博主名称: 小此方-CSDN博客

大家好,欢迎来到小此方的博客。

🔥个人专栏:《C语言》_小此方的博客-CSDN博客

🔥 努力成就未来,代码改变世界,相信我有一天也能成为改变世界的那个人


一,总览

一,蛇身链表与信息维护

代码语言:javascript
复制
//创建蛇身结点链表
typedef struct snakenode
{
	int x;
	int y;
	struct snakenode* next;
}snode;
//状态枚举
enum statue
{
	ok=1,
	pause,
	normal_end,
	kill_by_wall,
	kill_by_self,
	end_normal
};
//方向枚举
enum direction
{
	up,
	down,
	left,
	right
 };
enum difficulty
{
	normal,
	hard
};
//创建蛇信息维护结构体.
typedef struct sneakinfo
{
	snode* sneakhead;
	snode* sneakfood;
	int sleeptime;
	int foodweight;
	int score;
	enum statue statue;
	enum direction direction;
	enum difficulty difficulty;
}sneakinfo,*psneakinfo;

二,框架结构与开始游戏函数集

代码语言:javascript
复制
void test()
{
	//创建一个蛇数据维护变量
	char choice = 'N';
	sneakinfo sneak = { 0 };
	do
	{
		//开始游戏总函数
		startgame(&sneak);
		//运行游戏总函数
		rungame(&sneak);
		//结束游戏总函数
		endgame(&sneak);
		Setpos(16, 12);
		printf("想要再来一局吗(N/Y)");
		Setpos(38, 12);
		scanf("%c", &choice);
		getchar();
	} while (choice=='Y'||choice=='y');
}
int main()
{
	srand((unsigned int)time(NULL));
	setlocale(LC_ALL, "");
	test();
	Setpos(0, 27);
	return 0;
}
代码语言:javascript
复制
void startgame(psneakinfo sneak)
{
	//准备工作;
	//修改控制台属性
	change_the_con();
	//隐藏光标
	hide_the_cursor();
	//打印欢迎界面
	welcome_to_game(sneak);
	//打印地图
	gamemap();
	//初始化蛇
	Initsneak(sneak);
	//创造食物
	Createfood(sneak);
}

三,修改控制台属性

代码语言:javascript
复制
//修改控制台属性
void change_the_con()
{
	system("mode con cols=100lines=30");//30行,100列
	system("title 贪吃蛇");
}

四,隐藏光标

代码语言:javascript
复制
void hide_the_cursor()
{
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(houtput,&CursorInfo);
	CursorInfo.bVisible = false;
	SetConsoleCursorInfo(houtput ,&CursorInfo);
}

五,定位函数

代码语言:javascript
复制
void Setpos(int x,int y)//x列  y行
{
	COORD POS = { x,y };
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(houtput, POS);
}

六,打印欢迎界面

代码语言:javascript
复制
void welcome_to_game(sneakinfo* sneak)
{
	Setpos(36, 13);
	wprintf(L"%ls", L"◆欢迎来到贪吃蛇游戏◆");
	Setpos(73, 27);
	system("pause");
	system("cls");
	Setpos(36, 10);
	wprintf(L"%ls", L"◆更新日志◆");
	Setpos(30, 11);
	printf("11月2日2025年下午:开始制作");
	Setpos(28, 12);
	printf("11月6日2025年凌晨:基础工作完成");
	Setpos(19, 13);
	printf("11月6日2025年下午:添加了难度初步选项,增加穿墙功能");
	Setpos(73, 27);
	system("pause");
	system("cls");
	Setpos(36, 12);
	wprintf(L"%ls", L"◆按↑↓←→键移动◆");
	Setpos(36, 14);
	wprintf(L"%ls", L"◆按F3 ,F4键加减速◆");
	Setpos(36, 16);
	wprintf(L"%ls", L"◆按空格键暂停游戏◆");
	Setpos(36, 18);
	wprintf(L"%ls", L"◆按Esc键结束游戏 ◆");
	Setpos(26, 20);
	wprintf(L"%ls", L"◆hard难度撞墙即死 normal难度撞墙不会死  ◆");
	system("cls");
	Setpos(30, 12);
	wprintf(L"◆请选则难度normal请按N,hard请按H◆");
	char choice = 0;
	Setpos(67, 12);
	scanf("%c", &choice);
	Setpos(67, 12);
	printf(" ");
	getchar();
	if (choice == 'N' || choice == 'n')
	{
		sneak->difficulty = normal;
	}
	else if(choice == 'H' || choice == 'h')
	{
		sneak->difficulty = hard;
	}
	Setpos(73, 27);
	system("pause");
	system("cls");

}

七,地图绘制

代码语言:javascript
复制
void gamemap()
{
	for (int i = 0; i < 25; i++)
	{
		wprintf(L"■");
	}
	Setpos(0, 25);
	for (int i = 0; i < 25; i++)
	{
		wprintf(L"■");
	}
	for (int i = 1; i < 25; i++)
	{
		Setpos(0, i);
		wprintf(L"■");
	}
	for (int i = 1; i < 25; i++)
	{
		Setpos(48, i);
		wprintf(L"■");
	}
}

八,打印帮助信息

代码语言:javascript
复制
void print_help_information()
{
	Setpos(54, 16);
	wprintf(L"◆帮助信息◆");
	Setpos(54, 18);
	wprintf(L"%ls", L"按↑↓←→键移动");
	Setpos(54, 19);
	wprintf(L"%ls", L"按F3,F4键加减速,按F6放飞自我,F7恢复");
	Setpos(54, 20);
	wprintf(L"%ls", L"按空格键暂停游戏");
	Setpos(54, 21);
	wprintf(L"%ls", L"按Esc键结束游戏");
	Setpos(54, 22);
	wprintf(L"%ls", L"加速可以获得更多的分数");
	Setpos(54, 23);
	wprintf(L"%ls", L"制作人CSDN@小此方");
}

九,初始化蛇

代码语言:javascript
复制
void Initsneak(sneakinfo* sneak)
{
	sneak->sneakhead = NULL;
	snode* newnode = NULL;
	for (int j = 0; j < 5; j++)
	{
		newnode = (snode*)malloc(sizeof(snode));
		if (newnode == NULL)
		{
			perror("malloc::newnode");
			return;
		}
		newnode->next = NULL;
		newnode->x = 20 + 2 * j;
		newnode->y = 10;
		if (sneak->sneakhead ==NULL)
		{
			sneak->sneakhead = newnode;
		}
		else
		{
			newnode->next = sneak->sneakhead;
			sneak->sneakhead = newnode;
		}
	}
	int i = 5;
	snode* cur = sneak->sneakhead;
	while(i)
	{
		Setpos(cur->x ,cur->y);
		wprintf(L"●");
		cur = cur->next;
		i--;
	}
	//信息初始化
	sneak->sleeptime = 200;
	sneak->foodweight = 50;
	sneak->score = 0;
	sneak->statue = ok;
	sneak->direction = right;
}

十,创建食物

代码语言:javascript
复制
void Createfood(sneakinfo* sneak)
{
	snode* food = malloc(sizeof(snode));
	if (food == NULL)
	{
		perror("malloc_food");
		return;
	}
	again:
	do {
		food->x = rand() % 46+2;
		food->y = rand() % 24+1;
	} while (food->x % 2 != 0);//奇数进循环,偶数出循环
	snode* cur = sneak->sneakhead;
	while (cur)
	{
		if ((cur->x == food->x ) && (cur->y == food->y))
		{
			goto again;
		}
		cur = cur->next;
	}
	food->next = NULL;
	Setpos(food->x, food->y);
//	printf("food->x : %d, ");
	wprintf(L"%lc",FOOD);
	sneak->sneakfood = food;
}

十一,运行游戏总函数

代码语言:javascript
复制
void rungame(psneakinfo sneak)
{
	//打印帮助信息
	print_help_information();
	do
	{
		//打印动态帮助信息
		Setpos(54, 8);
		printf("#目前总得分: %d #",sneak->score );
		Setpos(54, 10);
		printf("当前食物分数:%5d\n", sneak->foodweight);
		//上下左右暂停退出加速减速
		if (KEY_PRESS(VK_UP) && sneak->direction != down)
		{
			sneak->direction = up;
		}
		if (KEY_PRESS(VK_DOWN) && sneak->direction != up)
		{
			sneak->direction = down;
		}
		if (KEY_PRESS(VK_LEFT) && sneak->direction != right)
		{
			sneak->direction = left;
		}
		if (KEY_PRESS(VK_RIGHT) && sneak->direction != left)
		{
			sneak->direction = right;
		}
		if (KEY_PRESS(VK_SPACE))
		{
			sneak->statue = pause;
			_pause(sneak);
		}
		if (KEY_PRESS(VK_F3))//加速
		{
			if (sneak->foodweight >= 10 && sneak->foodweight < 100)
			{
				sneak->sleeptime -= 20;
				sneak->foodweight += 10;
			}
		}
		if (KEY_PRESS(VK_F4))//减速
		{
			if (sneak->foodweight > 10 && sneak->foodweight <= 100)
			{
				sneak->sleeptime += 20;
				sneak->foodweight -= 10;
			}
		}
		if (KEY_PRESS(VK_F6))
		{
			sneak->sleeptime = 1;
			sneak->foodweight = 9999;
		}
		if (KEY_PRESS(VK_F7))
		{
			sneak->sleeptime = 200;
		}
		if (KEY_PRESS(VK_ESCAPE))
		{
			sneak->statue = normal_end;
			break;
		}
		movesneak(sneak);
		Sleep(sneak->sleeptime);
	} while (sneak->statue==ok);
}

十二,蛇的移动

代码语言:javascript
复制
void movesneak(psneakinfo sneak)
{
	snode* nextnode = malloc(sizeof(snode));
	if (nextnode == NULL)
	{
		perror("malloc::nextnode");
		return;
	}
	switch (sneak->direction)
	{
	case up:
	{
		nextnode->x = sneak->sneakhead->x;
		nextnode->y = sneak->sneakhead->y - 1;
		break;
	}
	case down:
	{
		nextnode->x = sneak->sneakhead->x;
		nextnode->y = sneak->sneakhead->y + 1;
		break;
	}
	case left:
	{
		nextnode->x = sneak->sneakhead->x - 2;
		nextnode->y = sneak->sneakhead->y;
		break;
	}
	case right:
	{
		nextnode->x = sneak->sneakhead->x + 2;
		nextnode->y = sneak->sneakhead->y;
		break;
	}
	}
	if (nextisfood(nextnode,sneak))
	{
		eatfood(nextnode, sneak);
	}
	else
	{
		nofood(nextnode,sneak);
	}
	if (sneak->difficulty == normal)
	{
		through_the_wall(sneak);
	}
	if (sneak->difficulty == hard)
	{
		killbywall(sneak);
	}
	killbyself(sneak);
}

十三,撞墙,穿墙,自杀

代码语言:javascript
复制
void killbywall(psneakinfo sneak)
{
	if (sneak->sneakhead->x == 0 || sneak->sneakhead->x == 48 || sneak->sneakhead->y == 0 || sneak->sneakhead->y == 25)
	{
		sneak->statue = kill_by_wall;
	}
}
void through_the_wall(psneakinfo sneak)
{
	if (sneak->sneakhead->x == 0)
	{
		sneak->sneakhead->x = 46;
	}
	if (sneak->sneakhead->x == 48)
	{
		sneak->sneakhead->x = 2;
	}
	if (sneak->sneakhead->y == 0)
	{
		sneak->sneakhead->y = 24;
	}
	if (sneak->sneakhead->y == 25)
	{
		sneak->sneakhead->y = 1;
	}
}
void killbyself(psneakinfo sneak)
{
	snode* cur = sneak->sneakhead->next;
	while (cur)
	{
		if (sneak->sneakhead->x== cur->x && sneak->sneakhead->y== cur->y)
		{
			sneak->statue = kill_by_self;
			break;
		}
		cur = cur->next;
	}
}

十四,前方有无食物

代码语言:javascript
复制
int nextisfood(snode* nextnode, psneakinfo sneak)
{
	if (nextnode->x == sneak->sneakfood->x && nextnode->y == sneak->sneakfood->y)
		return 1;
	else
		return 0;
}
void eatfood(snode* nextnode,psneakinfo sneak)
{
	//头插接入
	sneak->sneakfood ->next = sneak->sneakhead;
	sneak->sneakhead  = sneak->sneakfood;
	free(nextnode);
	nextnode = NULL;
	snode* cur = sneak->sneakhead;
	while (cur)
	{
		Setpos(cur->x, cur->y);
		wprintf(L"●");
		cur = cur->next;
	}
	sneak->score += sneak->foodweight;
	Createfood(sneak);
}
void nofood(snode* nextnode, psneakinfo sneak)
{
	nextnode->next = sneak->sneakhead;
	sneak->sneakhead = nextnode;
	snode* cur = sneak->sneakhead;
	while (cur->next->next)
	{
		Setpos(cur->x, cur->y);
		wprintf(L"●");
		cur = cur->next;
	}
	Setpos(cur->x, cur->y);
	wprintf(L"●");
	Setpos(cur->next->x, cur->next->y);
	printf("  ");
	free(cur->next);
	cur->next = NULL;
}

十五,暂停游戏

代码语言:javascript
复制
void _pause(sneakinfo* sneak)
{
	
	while (1)
	{
		Sleep(3000);
		if (KEY_PRESS(VK_SPACE))
		{
			sneak->statue = ok;
			break;
		}
	}
}

十六,结束游戏

代码语言:javascript
复制
void endgame(psneakinfo sneak)
{
	if (sneak->statue == normal_end)
	{
		Setpos(19,12);
		printf("正常退出游戏");
	}
	if (sneak->statue == kill_by_self)
	{
		Setpos(16, 12);
		printf("你死了,凶手是你自己");
	}
	if (sneak->statue == kill_by_wall)
	{
		Setpos(16, 12);
		printf("你死了,凶手是墙壁");
	}
	snode* cur = sneak->sneakhead;
	while (cur)
	{
		snode* del = cur;
		cur = cur->next;
		free(del);
	}
}

十七,声明与引用

代码语言:javascript
复制
void startgame(psneakinfo sneak);//总函数一:开始游戏
void rungame(psneakinfo sneak);//总函数二:运行游戏
void endgame(psneakinfo sneak);//总函数三:结束游戏
void welcome_to_game(sneakinfo* sneak);//打印欢迎界面
void Setpos(int x, int y);//定位函数
void hide_the_cursor();//隐藏光标
void change_the_con();//修改控制台属性
void gamemap();//打印地图
void print_help_information();	//打印帮助信息
void Initsneak(sneakinfo* sneak);//初始化蛇
void Createfood(sneakinfo* sneak);//创建食物
void _pause(sneakinfo* sneak);//暂停游戏
void movesneak(psneakinfo sneak);//游戏运行
int nextisfood(snode* nextnode, psneakinfo sneak);//下一个结点是食物
void eatfood(snode* nextnode, psneakinfo sneak);//吃食物
void nofood(snode* nextnode, psneakinfo sneak);//不是食物
void killbywall(psneakinfo sneak);//被墙壁杀死
void killbyself(psneakinfo sneak);//被自己杀死
void through_the_wall(psneakinfo sneak);//穿墙逻辑
代码语言:javascript
复制
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define KEY_PRESS(VK) ((GetAsyncKeyState(VK)&0x1)?1:0)
#define COLS 100//x,列
#define LINE 30//y,行
#define FOOD L'★'//食物
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<locale.h>
#include<stdbool.h>
#include<time.h>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-04,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一,总览
  • 一,蛇身链表与信息维护
  • 二,框架结构与开始游戏函数集
  • 三,修改控制台属性
  • 四,隐藏光标
  • 五,定位函数
  • 六,打印欢迎界面
  • 七,地图绘制
  • 八,打印帮助信息
  • 九,初始化蛇
  • 十,创建食物
  • 十一,运行游戏总函数
  • 十二,蛇的移动
  • 十三,撞墙,穿墙,自杀
  • 十四,前方有无食物
  • 十五,暂停游戏
  • 十六,结束游戏
  • 十七,声明与引用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档