一周的课余时间看了贪吃蛇教程,写了第一个小游戏,建议刚学完c语言的小伙伴学校,(小声bb:虽然影响不大,但其实还有两个小bug,等有缘人去发现…)后续有时间会发一下各个函数的实现过程和详细操作,毕竟学到了不少新东西。尽管万事开头难,然后中间难,最后结尾更难。但不管怎么说,算是实现了第一个,处女作(手动滑稽)
使用工具:vs2017,win32控制台,c语言。

效果:

源代码:

#define _CRT_SECURE_NO_WARNINGS
#include<time.h>
#include<string.h>
#include<stdio.h>
#include <stdlib.h>
#include<conio.h>
#include<windows.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
//定义bool类型
typedef int bool;
//定义行列
int g_nHang, g_nLie;
#define true 1 
#define false 0
#define DEF_SNAKE_LONG 300
char g_strGameBack[20][48] = {  "■■■■■■■■■■■■■■■■■■■■■■■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■ ■\n",
								"■■■■■■■■■■■■■■■■■■■■■■■\n"
};
//枚举方向
enum { to_east=2, to_west=-2, to_north=-1, to_south=1 };	//枚举方向
//蛇数组
int g_arrSnake[DEF_SNAKE_LONG][3] = { 0 };	//定义蛇数组
//控制蛇方向
int g_nSnakeDir = to_west;
//定义蛇死与活
bool g_bIsProFood = true;
//dingyi 蛇长度
int g_nSnakelen = 2;
//定义分数

int g_nScore = 0;
//显示首页
void Firstpage();
//检测space
void TestSpace();
//播放音乐
void MyPlaySound();
//停止播放
void StopMyMusic();
//画背景
void ShowBackground();
//为蛇设置一个随机位置
void SetSnakeRandPos();
//画蛇
void DrawSnake();
//蛇动
void SnakeMove();
//销毁蛇
void Destroy();
//蛇随方向动起来
void ChangeDir();
//蛇死亡判断
bool IsSnakeDie();
//产生新的食物
void ProduceFood();
//蛇变长
void SnakeGrowUp();
//计分
void Score();

int main(void) 
{
	//显示首页
	Firstpage();

	//播放音乐
	MyPlaySound();

	//按空格键
	TestSpace();

	//停止播放
	//StopMyMusic();

	//清空
	system("cls");

	//为蛇设置一个随机位置
	SetSnakeRandPos();

	//画蛇
	DrawSnake(); 

	//游戏界面/画背景
	while (1)
	{
		system("cls");
		//产生食物
		ProduceFood();
		//蛇边变
		SnakeGrowUp();
		//改变方向
		ChangeDir();
		//判断死亡
		if (false == IsSnakeDie())
		{
			printf("\n\n\n\n\n\n\n\t\t\tGameOver!\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
			break;
		}
		//蛇动
		SnakeMove();
		//显示背景
		ShowBackground();
		//显示计分
		Score();
		Sleep(500);
	}

	//蛇动
	SnakeMove();

	system("pause");
	return 0;
}


//显示首页
void Firstpage()
{
	printf("\n\n\n\n");
	printf("\t\t\t《 欢 迎 进 入 贪 吃 蛇 世 界 》\n\n\n");
	printf("\t\t\t 《 按 空 格 开 始 游 戏 》\n\n\n");
	printf("\t\t\t《 w a s d 控 制 蛇 的 方 向 》\n\n\n\n\n\n\n\n\n");
}

//播放音乐
void MyPlaySound()
{
	//绝对路径
	//PlaySound("E:\\倾尽天下.wav",NULL,SND_FILENAME | SND_ASYNC);
	//相对路径
	PlaySound("倾尽天下.wav", NULL, SND_FILENAME | SND_ASYNC);
}

//检测space
void TestSpace()
{
	char chInput;
	while (1)
	{
		chInput = _getch();
		if (' ' == chInput)
		{
			break;
		}
	}
}

//停止播放
void StopMyMusic()
{
	PlaySound(NULL, 0, 0);
}

//蛇动
void SnakeMove()
{
	int i = DEF_SNAKE_LONG - 1;
	//销毁蛇
	Destroy();
	for (i;i >= 1;i--)
	{
		//过滤掉非法蛇
		if (0 == g_arrSnake[i][1])
		{
			continue;
		}
		//把前一个节点的值,赋值给当前节点
		g_arrSnake[i][0] = g_arrSnake[i - 1][0];
		g_arrSnake[i][1] = g_arrSnake[i - 1][1];
		g_arrSnake[i][2] = g_arrSnake[i - 1][2];
	}

	//处理蛇头
	g_arrSnake[0][2] = g_nSnakeDir;

	if (to_west == g_arrSnake[0][2] || to_east == g_arrSnake[0][2])
	{
		g_arrSnake[0][1] += g_arrSnake[0][2];
	}
	else
	{
		g_arrSnake[0][0] += g_arrSnake[0][2];
	}
	//画蛇
	DrawSnake();
}

//销毁蛇
void Destroy()
{
	int i = 0;
	for (i = 0;g_arrSnake[i][0] != 0;i++)
	{
		strncpy(&g_strGameBack[g_arrSnake[i][0]][g_arrSnake[i][1]], " ", 2);
	}
}

//为蛇设置一个随机位置
void SetSnakeRandPos()
{
	int nX = -1;
	int nY = -1;

	//产生随机数
	srand((unsigned int)time(NULL));
	nX = rand()%19 + 1;
	nY = rand()%18 + 1;

	//初始化蛇的三个节点
	g_arrSnake[0][0] = nY;	//行 (蛇头)
	g_arrSnake[0][1] = nX * 2;	//列
	g_arrSnake[0][2] = to_west;	//方向

	g_arrSnake[1][0] = nY;
	g_arrSnake[1][1] = nX * 2 + 2;
	g_arrSnake[1][2] = to_west;

	g_arrSnake[2][0] = nY;
	g_arrSnake[2][1] = nX * 2 + 4;
	g_arrSnake[2][2] = to_west;
}

//画蛇
void DrawSnake()
{
	int i = 0;
	for (i = 0;g_arrSnake[i][0] != 0;i++)
	{
		strncpy(&g_strGameBack[g_arrSnake[i][0]][g_arrSnake[i][1]], "■", 2);
	}
}

//画背景
void ShowBackground()
{

	int i = 0;
	for (i = 0;i < 20;i++)
	{
		printf(g_strGameBack[i]);
	}
}

//改变方向
void ChangeDir()
{
	//_getch();同步检测

	//short 两个字节 高字节 低字节
	if (GetAsyncKeyState('W'))
	{
		if (to_south != g_arrSnake[0][2])
		{
			g_nSnakeDir = to_north;
		}
	}
	else if (GetAsyncKeyState('S'))
	{
		if (to_north != g_arrSnake[0][2])
		{
			g_nSnakeDir = to_south;
		}
	}
	else if (GetAsyncKeyState('A'))
	{
		if (to_east != g_arrSnake[0][2])
		{
			g_nSnakeDir = to_west;
		}
	}
	else if (GetAsyncKeyState('D'))
	{
		if (to_west != g_arrSnake[0][2])
		{
			g_nSnakeDir = to_east;
		}
	}
}

//蛇死亡判断
bool IsSnakeDie()
{
	if (to_west == g_arrSnake[0][2] || to_east == g_arrSnake[0][2])
	{
		//蛇头的下一个 是方块就死亡
		if (0 == strncmp(&g_strGameBack[g_arrSnake[0][0]][g_arrSnake[0][1] + g_arrSnake[0][2]], "■", 2))
		{
			return false;
		}
	}
	else
	{
		if (0 == strncmp(&g_strGameBack[g_arrSnake[0][0]+ g_arrSnake[0][2]][g_arrSnake[0][1]], "■", 2 ))
		{
			return false;
		}
	}
	return true;
}

//产生食物
void ProduceFood()
{
	//判断是否产生新的食物
	if (false == g_bIsProFood)//否
	{
		return;
	}
	//产生随机坐标
	srand((unsigned)time(NULL));


	 g_nHang = rand() % 18 + 1;
	 g_nLie = rand() % 20 + 1;

	while (1)
	{
		bool Flag = true;

		for (int i = 0;g_arrSnake[i][0] != 0;i++)
		{
			if (g_nHang == g_arrSnake[i][0] && g_nLie == g_arrSnake[i][1])
			{
				Flag == false;
				break;
			}
		}
		if (true == Flag)
		{
			break;
		}

	}
	//坐标画食物
	strncpy(&g_strGameBack[g_nHang][g_nLie * 2], "★", 2);
	g_bIsProFood = false;
}

//蛇变长
void SnakeGrowUp()
{
	//蛇头坐标和食物坐标相等
	if (g_nHang==g_arrSnake[0][0]&& g_nLie*2==g_arrSnake[0][1])
	{
		//蛇长大
		if (to_east == g_arrSnake[g_nSnakelen][2])
		{
			g_arrSnake[g_nSnakelen + 1][0] = g_arrSnake[g_nSnakelen][0];
			g_arrSnake[g_nSnakelen + 1][1] = g_arrSnake[g_nSnakelen][0] - 2;
			g_arrSnake[g_nSnakelen + 1][2] = g_arrSnake[g_nSnakelen][0];
		}
		else if (to_west == g_arrSnake[g_nSnakelen][2])
		{
			g_arrSnake[g_nSnakelen + 1][0] = g_arrSnake[g_nSnakelen][0];
			g_arrSnake[g_nSnakelen + 1][1] = g_arrSnake[g_nSnakelen][0] + 2;
			g_arrSnake[g_nSnakelen + 1][2] = g_arrSnake[g_nSnakelen][0];
		}
		else if (to_north == g_arrSnake[g_nSnakelen][2])
		{
			g_arrSnake[g_nSnakelen + 1][0] = g_arrSnake[g_nSnakelen][0] + 1;
			g_arrSnake[g_nSnakelen + 1][1] = g_arrSnake[g_nSnakelen][0];
			g_arrSnake[g_nSnakelen + 1][2] = g_arrSnake[g_nSnakelen][0];
		}
		else if (to_south == g_arrSnake[g_nSnakelen][2])
		{
			g_arrSnake[g_nSnakelen + 1][0] = g_arrSnake[g_nSnakelen][0] - 1;
			g_arrSnake[g_nSnakelen + 1][1] = g_arrSnake[g_nSnakelen][0];
			g_arrSnake[g_nSnakelen + 1][2] = g_arrSnake[g_nSnakelen][0];
		}
		g_nSnakelen++;
		g_bIsProFood = true;
		g_nScore++;
	}
}

//计分
void Score()
{
	COORD rd;
	rd.X = 46;
	rd.Y = 3;
	//设置光标位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);
	//打印
	printf("分数");

	rd.X = 47;
	rd.Y = 4;
	//设置光标位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);
	//打印
	printf("%d",g_nScore);
}