这其实算是一个补档,因为这个项目是我在大一完成的,但是当时没有存档的习惯,今天翻以前代码的时候翻到了,于是乎补个档,以此怀念和志同道合的网友一起做项目的日子 ₍ᐢ ›̥̥̥ ༝ ‹̥̥̥ ᐢ₎♡
这里面我主要负责service层,网友负责view层
目录
1.需求文档

2.流程图
processon是一个很好的流程图、思维导图等等的制作网站
设计一

设计二

权衡之后我们使用了第二种方案
3.产品构思图
这里我记得我们用的是墨刀

4.可行性分析
我找不到了ฅ(꒪˙꒳˙꒪ )ฅ ,不过肯定是可行性更大的doge
5.源代码
python
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#pragma warning(disable: 4996)
#define YH_W 20
#define YH_H 20
// 传入坐标, 将光标移动到指定坐标
int zhuozi;//自动生成食物参数
int score;//得分
char dir;//蛇的当前方向
int len;//蛇长(不计蛇头)
void gotoXY(int x, int y)
{
COORD c;
c.X = x - 1;
c.Y = y - 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void clear(int x, int y, int w, int h)
{
for (int i = 0; i < h; i++) {
gotoXY(x, y + i);
for (int j = 0; j < w; j++) putchar(' ');
}
}
void setPrintColor(int color) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
/*
贪吃蛇:
菜单界面:
展示选项: 进入游戏 排行榜 设置 退出
用户ws移动光标
回车确认选项
进入游戏: 进入游戏界面
排行榜: 敬请期待
设置: 敬请期待
退出: 结束游戏
游戏界面:
展示地图: 展示蛇 地图
用户wasd移动
蛇定时移动
移动后:
撞墙/撞自己: 死亡 结束游戏
吃到食物: 长度+1 食物消失 生成新的食物 移动一格
空地: 移动一格
*/
//-----------------数据设计------------------
/*
-1表示横墙
-2表示竖墙
-3 -4 -5 -6分别代表四个角落
0表示空地
1表示蛇
2表示食物
map[3][5] = 2// 坐标(3,5)是食物
*/
int map[YH_H][YH_W];
/*
s[i][j]
i表示第i节身体
j表示坐标 0表示x坐标 1表示y坐标
s[2][0] = 5; 第[2]节身体x坐标 = 5
s[2][1] = 3; 第[2]节身体y坐标 = 3
蛇的第[2]节身体 坐标是(5,3)
*/
int s[YH_H * YH_W][2];//s[0][0] s[0][1]
//-----------------数据设计------------------
//---------------view-------------------
/*
功能:
while(1)}{
1. 展示界面
2. 接收玩家输入
如果是ws 移动光标
如果是回车 执行对应选项
进入游戏: 进入游戏界面
排行榜: 敬请期待
设置: 敬请期待
退出: 结束游戏
}
参数: void
返回值: void
*/
void menuView();
/*
功能:打印暂停界面
参数:void
返回值:void
*/
void zt();
/*
功能:
1. 初始化游戏数据: 蛇(蛇身, 长度, 方向), 地图(墙,食物) service提供初始化函数
while(1){
2. 调用map_view函数 打印/绘制界面: 蛇, 地图 view
3. 判断用户有没有输入{ view
kbhit()
如果有:
判断用户输入的类型 view
方向: 修改方向: service提供修改方向函数
判断这个方向 能不能修改
如果能修改 蛇的方向=输入方向
//空格: 暂停游戏: 展示暂停界面
}
4. 移动{
判断:
判断蛇头 前面的位置 是什么东西 service提供判断函数 判断移动后的情况
可能是墙/蛇身, 食物, 空地,
打印失败界面,退到主菜单或者退出程序
执行:
如果是墙/蛇身: 游戏结束
如果是空地/食物: 游戏继续 service提供修改函数 修改移动后的数据情况
空地: 正常移动一格
食物: 蛇长度+1, 正常移动一格, 去掉食物,生成一个新的食物
}
}
参数: void
返回值: void
*/
void gameView();
/*
功能:打印/绘制界面: 蛇, 地图
参数:void
返回值:void
*/
void map_view();
//---------------view-------------------
//---------------service-------------------
//service提供初始化函数
/*
地图 蛇长度 蛇位置
地图:
地图周围一圈墙(1)
地图中间初始化为空地(0)
蛇位置:
地图下方左边
朝右走
蛇方向: d
食物:
在地图中随机生成一个食物
注意 食物不能和蛇身重叠
参数: void
返回值: void
*/
void init(void);
//service提供修改方向函数
/*
注意: service不接收输入 不打印界面
功能:
1. 判断用户输入的方向 和蛇的方向 是否冲突
如果冲突: 返回0
2. 蛇的方向 = 用户输入方向
返回1
参数:
userInput: 用户输入的方向
返回值:
0表示方向修改失败
1表示方向修改成功
*/
int updateDir(char userInput);
//service提供判断函数 判断蛇头前面是什么
/*
功能:
1. 根据蛇头坐标 和蛇的方向 获取蛇头前一格的坐标
2. 判断 地图中 这个坐标是什么内容
如果是墙: 返回0
如果是食物: 返回1
3. (如果是空地)
遍历蛇身 判断这个坐标 是否和蛇身重复
如果是: 返回0
如果不是 返回2
参数: void
返回值:
0表示前面是蛇身/墙
1表示前面是食物
2表示前面是空地
*/
int before();
//service提供修改函数 蛇移动后的数据情况
/*
功能:
1. 判断是吃到食物的情况 还是空地的情况
2. 如果是食物:
1. 蛇长度+1
2. 去掉地图上的食物
3. 随机生成新的食物
4. 蛇移动一格
3. 如果是空地:
1. 蛇移动一格
参数:
result:
1 表示吃到食物的数据修改
2: 表示空地的数据修改
返回值: void
*/
void move(int result);
void food();
/*
功能:
打印设置 排行榜界面(拓展功能 暂未实现)
参数:void
返回值:void
*/
void more();
/*
功能:
打印结束界面及得分 跳回主界面
参数:void
返回值:void
*/
void end();
//---------------service-------------------
int main() {
menuView();
}
void more() {
system("cls");
gotoXY(60, 5);
printf("敬请期待!");
gotoXY(58, 8);
system("pause");
system("cls");
menuView();
}
void menuView() {
int userChoose = 0;
while (1) {
// ----------------- 打印界面 -----------------
gotoXY(64, 3);
printf("贪吃蛇");
if (userChoose == 0) setPrintColor(0x6f);
gotoXY(64, 6);
printf("开始游戏");
if (userChoose == 0) setPrintColor(0x0f);
if (userChoose == 1) setPrintColor(0x6f);
gotoXY(65, 9);
printf("排行榜");
if (userChoose == 1) setPrintColor(0x0f);
if (userChoose == 2) setPrintColor(0x6f);
gotoXY(64, 12);
printf("游戏设置");
if (userChoose == 2) setPrintColor(0x0f);
if (userChoose == 3) setPrintColor(0x6f);
gotoXY(64, 15);
printf("退出游戏");
if (userChoose == 3) setPrintColor(0x0f);
gotoXY(56, 19);
printf("制作团队:发际线与我作队");
gotoXY(54, 23);
printf("提示:1.WASD进行上下左右移动\n 2.长按WASD或者Esc可加速\n 3.游戏中按空格可以暂停\n ?.请自行眨眼补帧(狗头)");
gotoXY(58, 21);
printf("特别鸣谢:启动小学长");
// ---------------- 接收用户输入 --------------
char input = _getch();
// -------------判断是方向上下还是回车------------
switch (input) {
case 'w':
userChoose -= 1;
if (userChoose == -1) userChoose = 3;
break;
case 's':
userChoose = (userChoose + 1) % 4;
break;
case '\r':
clear(3, 2, 80, 20);
switch (userChoose) {
case 0:
gameView();
break;
case 1:
more();
break;
case 2:
more();
break;
case 3:
exit(0);
break;
}
clear(3, 2, 36, 20);
break;
}
}
}
void gameView()
{
score = 0;
int k = 0;
init();//初始化地图
system("cls");
gotoXY(0, 0);
while (1)
{
map_view();//打印地图
k = 10000;
while (k--)
{
if (kbhit())
{
break;
}
}
if (k > 0)
{
char input = getch();
if (input == 's' || input == 'w' || input == 'a' || input == 'd')
{
if (updateDir(input)) dir = input;//若输入有效,则更新方向
}
else if (input == ' ') zt();
}
//判断前面
if (before() == 1 || before() == -1 || before() == -2) end();//前面是墙或蛇身,结束游戏
else if (before() == 0) move(0);//前面是空地,蛇尾往前,蛇头往前
else if (before() == 2)//前面是食物,吃掉食物
{
move(2);//蛇尾不变,蛇头往前
}
}
}
int updateDir(char userInput)
{
int cha[2];
if (len != 1)
{
cha[0] = s[0][0] - s[1][0];
cha[1] = s[0][1] - s[1][1];//蛇头反方向
if (userInput == 'w' && cha[0] == 1 || userInput == 's' && cha[0] == -1 || userInput == 'a' && cha[1] == 1 || userInput == 'd' && cha[1] == -1)
{
return 0;//枚举失败的情况
}
}
return 1;
}
void map_view()
{
system("cls");
gotoXY(0, 0);
for (int i = 0; i <= 19; i++)
{
for (int j = 0; j <= 19; j++)
{
if (i == s[0][0] && j == s[0][1]) {
setPrintColor(6);//黄色
printf(" ● ");
}
else {
switch (map[i][j]) {
case -1:
setPrintColor(9);//浅蓝色
printf("═══");
break;
case -2:
setPrintColor(9);//浅蓝色
printf(" ║ ");
break;
case -3:
setPrintColor(9);//浅蓝色
printf(" ╔═");
break;
case -4:
setPrintColor(9);//浅蓝色
printf("═╗ ");
break;
case -5:
setPrintColor(9);//浅蓝色
printf("═╝ ");
break;
case -6:
setPrintColor(9);//浅蓝色
printf(" ╚═");
break;
case 0:
setPrintColor(7);//白色
printf(" □ ");
break;
case 2:
setPrintColor(2);//绿色
printf(" ● ");
break;
case 1:
setPrintColor(7);//白色
printf(" ● ");
break;
}
}
}
printf("\n");
}
gotoXY(0, 0);
setPrintColor(7);
printf("分数:%2d", score);
}
int before()
{
switch (dir)
{
case'w':
return map[s[0][0] - 1][s[0][1]];
case's':
return map[s[0][0] + 1][s[0][1]];
case'a':
return map[s[0][0]][s[0][1] - 1];
case'd':
return map[s[0][0]][s[0][1] + 1];
}
}
void food() {
int food_x, food_y;
while (1) {
food_x = rand() % 18 + 1;
food_y = rand() % 18 + 1;
if (map[food_x][food_y] == 0) {
map[food_x][food_y] = 2;
break;
}
}
}
void end()
{
system("cls");
gotoXY(10, 10);
printf("游戏结束,你的得分为%d分。 ", score);
system("pause");
system("cls");
menuView();
}
void init() {
len = 2;//蛇头不计入长度
dir = 'd';//初始方向为右
for (int i = 0; i <= 19; ++i)
{
map[i][0] = -2;
map[0][i] = -1;
map[19][i] = -1;
map[i][19] = -2;
}
map[0][0] = -3;
map[0][19] = -4;
map[19][19] = -5;
map[19][0] = -6;
for (int i = 1; i <= 18; ++i)
{
for (int t = 1; t <= 18; ++t)
map[i][t] = 0;
}
s[0][0] = 10;
s[0][1] = 11;
s[1][0] = 10;
s[1][1] = 10;
map[10][10] = 1;
map[10][11] = 1;
food();
}
void move(int result) {
zhuozi %= 10;
zhuozi++;
if (zhuozi == 1) food();//每过一会刷出食物
int xx = s[0][0], yy = s[0][1];
switch (dir) {
case 'w':
xx = s[0][0] - 1;
yy = s[0][1];
break;
case 'a':
xx = s[0][0];
yy = s[0][1] - 1;
break;
case 's':
xx = s[0][0] + 1;
yy = s[0][1];
break;
case 'd':
xx = s[0][0];
yy = s[0][1] + 1;
break;
}
if (result == 2)
{
++len;
for (int i = len - 1; i >= 1; i--)
{
s[i][0] = s[i - 1][0];
s[i][1] = s[i - 1][1];
}
food();
score += 20;
}
else
{
map[s[len - 1][0]][s[len - 1][1]] = 0;
for (int i = len - 1; i >= 1; i--)
{
s[i][0] = s[i - 1][0];
s[i][1] = s[i - 1][1];
}
}
s[0][0] = xx;
s[0][1] = yy;
map[xx][yy] = 1;
}
void zt()
{
system("cls");
gotoXY(10, 10);
printf("游戏已暂停,按下空格解除暂停");
while (1)
{
char input_z = getch();
if (input_z == ' ') break;
}
map_view();
}
6.实战效果


7.心得
虽然过去有段时间了,但是我还是想得起和有同样目标方向的网友做项目的开心,大一刚进入大学不久一切还不是很适应,但是和网友一起做项目让我不再那么紧张,也慢慢开始适应大学生活,虽然现在不经常联系了,但是人生每个阶段都有各个阶段你会遇到的人,重要的是一起变得更好,一起向远方