C语言 —— 贪吃蛇
参考视频:https://www.bilibili.com/video/av29580072/?p=1
GreedySnake.h
#ifndef GREEDYSNAKE_H_INCLUDED
#define GREEDYSNAKE_H_INCLUDED #define SNAKE_LENGTH 20 //蛇的长度最大为20
#define true 1
#define false 0
enum {UP = -, DOWN = , LEFT = -, RIGHT = }; typedef int bool; void FirstPage(); //设置起始游戏界面
void TestSpace(); //按空格开始游戏
void ShowBackground(); //展示游戏背景
void SetSnakeRandPos(); //为蛇产生一个随机的位置
void DrawSnake(); //画蛇
void SnakeMove(); //蛇动
void DestroySnake(); //销毁蛇
void ChangeDir(); //蛇随着方向键动起来
bool IsSnakeDie(); //判断蛇是否死亡
void ProduceFood(); //随机位置产生食物
void SnakeGrowUp(); //蛇变长
void PrintScore(); //打印分数 #endif // GREEDYSNAKE_H_INCLUDED
GreedySnake.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include "GreedySnake.h" //把所有元素置为0
//snake[0][0]表示蛇头的行,snake[0][1]表示蛇头的列,snake[0][2]表示蛇头移动的方向
int g_arrSnake[SNAKE_LENGTH][] = { }; int g_iSnakeLength = ; //初始长度为3,但数组下标从0开始,故此处为2 char g_arrBackGround[][] =
{
"████████████████████████\n", //一个█占两个字节,占两个字符的位置
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"████████████████████████\n"
}; int g_iSnakeDir = LEFT; //蛇的方向,默认向左
bool g_bIsProFood = true; //蛇产生食物的标记
int g_iRow; //食物的行坐标
int g_iCol; //食物的列坐标 int g_iScore = ; //分数 void FirstPage() //设置起始游戏界面
{
for (int i = ; i < ; ++i)
printf(" ");
for (int i = ; i < ; ++i)
printf("*");
printf("\n"); for (int j = ; j < ; ++j)
{
for (int i = ; i < ; ++i)
printf(" ");
printf("*");
for (int i = ; i < ; ++i)
printf(" ");
printf("*\n");
} for (int i = ; i < ; ++i)
printf(" ");
printf("*");
for (int i = ; i < ; ++i)
printf(" ");
printf("《 欢迎来到贪吃蛇的世界!》");
for (int i = ; i < ; ++i)
printf(" ");
printf("*\n"); for (int i = ; i < ; ++i)
printf(" ");
printf("*");
for (int i = ; i < ; ++i)
printf(" ");
printf("《 请按空格键开始游戏 》");
for (int i = ; i < ; ++i)
printf(" ");
printf("*\n"); for (int j = ; j < ; ++j)
{
for (int i = ; i < ; ++i)
printf(" ");
printf("*");
for (int i = ; i < ; ++i)
printf(" ");
printf("*\n");
} for (int i = ; i < ; ++i)
printf(" ");
for (int i = ; i < ; ++i)
printf("*");
for (int i = ; i < ; ++i)
printf("\n");
} void TestSpace() //按空格开始游戏
{
char c;
while ((c = getch()) != ' ') //getch()在头文件<conio>内
{ }
system("cls"); //清屏
} void ShowBackground() //展示游戏背景
{
for (int i = ; i < ; ++i)
printf(g_arrBackGround[i]);
} void SetSnakeRandPos() //设置蛇的初始位置,默认蛇的身子为三节,向左移动
{
int x, y;
srand((unsigned)time(NULL));
x = rand()% + ; //因为蛇的身子起始为三节,所以x的范围为1-20(蛇不能起始就撞墙)
y = rand()% + ; g_arrSnake[][] = y; //行 注意:x,y和初始背景中的行列刚好是反的
g_arrSnake[][] = x * ; //列 注意:一个█占两个字节,所以算其坐标时要乘以2
g_arrSnake[][] = LEFT; //方向 g_arrSnake[][] = y;
g_arrSnake[][] = x * + ;
g_arrSnake[][] = LEFT; g_arrSnake[][] = y;
g_arrSnake[][] = x * + ;
g_arrSnake[][] = LEFT; DrawSnake();
} void DrawSnake() //展示蛇
{
//因为一个█占两个字节,所以不能直接用strcpy(&arrBackGround[arrSnake[i][0]][arrSnake[i][1]],"█");否则会把\0拷贝进来,导致出错
//由于前面把arrSnake的所有元素都置为了0,所以当arrSnake[i][0]为0时,代表那个坐标处没有蛇的身子
for (int i = ; g_arrSnake[i][] != ; ++i)
strncpy(&g_arrBackGround[g_arrSnake[i][]][g_arrSnake[i][]], "█", ); //注意取地址符&不能漏掉!
} void DestroySnake() //销毁蛇
{
for (int i = ; g_arrSnake[i][] != ; ++i)
strncpy(&g_arrBackGround[g_arrSnake[i][]][g_arrSnake[i][]], " ", ); //注意取地址符&不能漏掉! } void SnakeMove() //蛇动
{
DestroySnake();
for(int i = SNAKE_LENGTH - ; i >= ; --i)
{
if(g_arrSnake[i][] != )
{
//把前一个节点的值,赋给当前节点
g_arrSnake[i][] = g_arrSnake[i-][];
g_arrSnake[i][] = g_arrSnake[i-][];
g_arrSnake[i][] = g_arrSnake[i-][];
}
} g_arrSnake[][] = g_iSnakeDir; //设置蛇头方向 //处理第一个节点(蛇头)
if(g_arrSnake[][] == LEFT || g_arrSnake[][] == RIGHT) //左右移动,列加减2
{
g_arrSnake[][] += g_arrSnake[][];
}
else
{
g_arrSnake[][] += g_arrSnake[][]; //上下移动,行加减1
} DrawSnake(); } void ChangeDir() //改变方向
{
//不能用getchar(), 会回显,并且要按回车之后才会开始读取
//不能用getch(), 同步检测 //异步检测
if(GetAsyncKeyState('W'))
{
if (g_arrSnake[][] != DOWN) //蛇不能回头
g_iSnakeDir = UP;
} if(GetAsyncKeyState('S'))
{
if (g_arrSnake[][] != UP)
g_iSnakeDir = DOWN;
} if(GetAsyncKeyState('A'))
{
if (g_arrSnake[][] != RIGHT)
g_iSnakeDir = LEFT;
} if(GetAsyncKeyState('D'))
{
if (g_arrSnake[][] != LEFT)
g_iSnakeDir = RIGHT;
}
} bool IsSnakeDie() //蛇死亡判断(包括撞墙和吃自己,两种情况)
{
if(g_arrSnake[][] == LEFT || g_arrSnake[][] == RIGHT) //如果蛇左右移动,则判断蛇头的左右是否是"█",如果是,则判定为蛇死亡
{
if(!strncmp(&g_arrBackGround[g_arrSnake[][]][g_arrSnake[][]+g_arrSnake[][]], "█", )) //注意取地址符&不能漏掉!
return true;
}
else //如果蛇上下移动,则判断蛇头的上下是否是"█"
{
if(!strncmp(&g_arrBackGround[g_arrSnake[][]+g_arrSnake[][]][g_arrSnake[][]], "█", ))
return true;
}
return false;
} void ProduceFood() //随机位置产生食物
{
//判断是否产生新的食物
if(g_bIsProFood == false)
return; bool bFlag = true;
srand((unsigned)time(NULL)); while() //产生合法的食物,即食物不与蛇的身子重合
{
g_iRow = rand()% + ; //行
g_iCol = rand()% + ; for (int i = ; g_arrSnake[i][] != ; i++) //遍历蛇
if (g_iRow == g_arrSnake[i][] && g_iCol == g_arrSnake[i][]) //如果在食物产生在蛇身上
{
bFlag = false;
break;
} if(bFlag == true)
break;
} strncpy(&g_arrBackGround[g_iRow][g_iCol*], "★", );
g_bIsProFood = false;
} void SnakeGrowUp() //蛇变长
{
if(g_iRow == g_arrSnake[][] && g_iCol* == g_arrSnake[][]) //注意:列要乘以2
{
if (UP == g_arrSnake[g_iSnakeLength][])
{
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][]+;
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
}
else if (DOWN == g_arrSnake[g_iSnakeLength][])
{
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][]-;
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
}
else if (LEFT == g_arrSnake[g_iSnakeLength][])
{
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][]+;
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
}
else if (RIGHT == g_arrSnake[g_iSnakeLength][])
{
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][]-;
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
}
g_iSnakeLength++;
g_bIsProFood = true;
g_iScore++;
} } void PrintScore() //打印分数
{
COORD rd;
//设置光标位置
rd.X = ;
rd.Y = ;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);
printf("分数"); rd.X = ;
rd.Y = ;
//设置光标位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);
//打印
printf ("%d", g_iScore);
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include "GreedySnake.h" int main()
{
FirstPage();
TestSpace();
system("cls");
SetSnakeRandPos();
ShowBackground(); while ()
{
system("cls");
ProduceFood();
SnakeGrowUp();
ChangeDir(); if(IsSnakeDie())
{
printf("snake die!\n");
break;
} SnakeMove();
ShowBackground();
PrintScore(); Sleep();
}
system("pause");
return ;
}
C语言 —— 贪吃蛇的更多相关文章
- c语言贪吃蛇详解3.让蛇动起来
c语言贪吃蛇详解3.让蛇动起来 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 上次 ...
- c语言贪吃蛇详解-2.画出蛇
c语言贪吃蛇详解-2.画出蛇 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 蛇的身 ...
- c语言贪吃蛇详解1.画出地图
c语言贪吃蛇详解-1.画出地图 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 首先 ...
- c语言贪吃蛇详解5.GameOver功能与显示成绩
c语言贪吃蛇详解5.GameOver功能与显示成绩 以前我们已经做出来了一个能吃东西变长的蛇.不过它好像不会死... 现在就来实现一下game over的功能吧. 写个函数判断蛇是否撞到自己或者撞到墙 ...
- c语言贪吃蛇详解4.食物的投放与蛇的变长
c语言贪吃蛇详解4.食物的投放与蛇的变长 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识 ...
- 程序游戏推荐(C语言贪吃蛇,python天天酷跑(需要安装pygame),js是狠人就坚持30s)
下面是下载位置,我把他们上传到我的文件下了. C语言贪吃蛇:https://files.cnblogs.com/files/ITXiaoAng/%E8%B4%AA%E5%90%83%E8%9B%87. ...
- C/C++编程笔记:C语言贪吃蛇源代码控制台(二),分数和食物!
接上文<C/C++编程笔记:C语言贪吃蛇源代码控制台(一),会动的那种哦!>如果你在学习C语言开发贪吃蛇的话,零基础建议从上一篇开始哦!接下来正式开始吧! 三.蛇的运动 上次我已经教大家画 ...
- C/C++编程笔记:C语言贪吃蛇源代码控制台(一),会动的那种哦!
前几天有个同学加我QQ私聊我说他们老师布置了一个贪吃蛇,他不知道怎么写所以来找我求解,我给他简单讲解了思路和一些难点之后他也能够自己独立将项目完成了!考虑到更多同学可能有贪吃蛇上的问题,今天有时间就来 ...
- c语言贪吃蛇
思路:函数gotoxy(x,y)使光标移植屏幕的x,y坐标(屏幕左上角为0,0),用来绘制蛇和界面,color()函数用来设置绘制的颜色.设有snakelong节,第i节蛇的x坐标为x[i],y坐标为 ...
- [C语言]贪吃蛇_结构数组实现
一.设计思路 蛇身本质上就是个结构数组,数组里存储了坐标x.y的值,再通过一个循环把它打印出来,蛇的移动则是不断地刷新重新打印.所以撞墙.咬到自己只是数组x.y值的简单比较. 二.用上的知识点 结构数 ...
随机推荐
- pyqt5 鼠标操作
#资料 http://blog.sina.com.cn/s/blog_6483fa330102xo6w.html import sysfrom PyQt5.QtWidgets import QAppl ...
- yolov3实践(一)
很多博友看了我的第一篇博客yolo类检测算法解析——yolo v3,对其有了一定的认识和了解,但是并没有贴出代码和运行效果,略显苍白.因此在把篇博客理论的基础上,造就了第一篇实践文章,也就是本文.只要 ...
- mysql 语句 GROUP_CONCAT
select * from blog_log;+----+---------------------+-------+--------+| id | time | level | info |+--- ...
- strong、weak、copy、assign 在命名属性时候怎么用
一直都在疑惑属性定义中在什么情况下用strong.在什么情况下用weak? 总结大致如下: 1.weak 是用来修饰代理(delegate)和UI控件. 2.strong 是用来修饰除了代理(dele ...
- retrofit 基础使用
1.先导入依赖 加上网络权限 <uses-permission android:name="android.permission.INTERNET" /> 2.创建接口 ...
- VIM for C++ 一键安装配置
执行: wget https://raw.github.com/ma6174/vim/master/setup.sh -O ma6174_vim_setup.sh && bash ma ...
- C语言函数调用栈(三)
6 调用栈实例分析 本节通过代码实例分析函数调用过程中栈帧的布局.形成和消亡. 6.1 栈帧的布局 示例代码如下: //StackReg.c #include <stdio.h> //获取 ...
- tomcat启动报错 ERROR o.a.catalina.session.StandardManager 182 - Exception loading sessions from persiste
系统:centos6.5 x86_64 jdk: 1.8.0_102 tomcat:8.0.37 tomcat 启动报错: ERROR o.a.catalina.session.StandardMan ...
- 解决报错error the @annotation pointcut expression is only supported at Java 5
eclipse搭建环境后报错 error the @annotation pointcut expression is only supported at Java 5 错误意思大致是:注释切入点表达 ...
- 源码编译安装mysql5.5.33
源码编译安装mysql5.5.33 一.安装cmake编译工具 跨平台编译器 # yum install -y gcc* # yum install -y cmake 解决依赖关系 # yum ins ...