一周的课余时间看了贪吃蛇教程,写了第一个小游戏,建议刚学完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);
}