贪吃蛇c语言源代码:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<conio.h>
#include<graphics.h>
#define SNAKE_NUM 604//蛇的最大节数
#define HIGH 480//窗口高
#define WIDE 640//窗口宽
#define RE 5//蛇身小球半径
int score = 0;//蛇吃掉的食物的个数
int flag;//flag为游戏是否暂停的标志
enum DIR {//蛇的方向(枚举体)
UP,//上(为枚举常量不是变量)
DOWN,//下(每一个枚举元素都代表一个整数,编译时默认其值为0)
LEFT,//左
RIGHT,//右
};
//蛇的结构
struct Snake {
int size;//蛇的长度(节数)
int dir;//蛇的方向
int speed;//蛇的速度
POINT coor[SNAKE_NUM];//坐标
}snake;
struct Other {//得分部分的蛇身
POINT coor[SNAKE_NUM];//坐标
}other;
struct FOOD {
int x;
int y;
//食物坐标
int r;//食物半径
bool flag;//判断这个食物有没有被吃了,要不要更新食物
DWORD color;//食物颜色
}food;
void food_create() {//随机生成食物坐标结点
//rand()随机函数
//一般把时间作为随机函数种子
food.x = rand() % (WIDE - RE);//取余,限制随机坐标范围
food.y = rand() % (HIGH - RE);
food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
food.r = RE + 2;
food.flag = true;
}
//数据的初始化
void Gameinit() {
//播放背景音乐
//mciSendString("open ./res/snake_bgm.mp3 alias BGM",0,0,0);//打开音乐文件并命名
//mciSendString("play BGM repeat",0,0,0);
//init初始化graph图形窗口
initgraph(WIDE, HIGH);
//得分清0
score = 0;
//游戏开始
flag = 1;
//设置随机数种子
srand(GetTickCount());//GetTickCount()获取系统开机时间毫秒数
//初始化蛇
snake.size = 3;//初始化长度
snake.speed = 2 * RE;//初始化速度
snake.dir = RIGHT;//初始化方向
snake.coor[snake.size - 1].x = (2 * RE + 2) * (snake.size - 1) + (2 * RE - 2);//蛇头结点
snake.coor[snake.size - 1].y = 2 * RE;
for (int i = snake.size - 2; i >= 0; i--) {//生成一个个蛇的身体的结点坐标
snake.coor[i].x = 2 * RE * i + 2 * RE;
snake.coor[i].y = 2 * RE;
}
//食物初始化
food_create();
}
//形成蛇
void GameDraw() {
//双缓冲绘图,防止闪屏
BeginBatchDraw();
//设置颜色背景
setbkcolor(RGB(28, 15, 123));
cleardevice();
//绘制蛇
setfillcolor(RED);//设置蛇头的颜色
solidcircle(snake.coor[snake.size - 1].x, snake.coor[snake.size - 1].y, RE + 1);//绘制蛇头
setfillcolor(YELLOW);//设置蛇身的颜色
for (int i = 0; i < snake.size - 1; i++) {//绘制蛇身
solidcircle(snake.coor[i].x, snake.coor[i].y, RE);
}
for (int i = 0; i < score; i++) {//绘制得分部分长度
solidcircle(other.coor[i].x, other.coor[i].y, RE);
}
//绘制食物
if (food.flag) {//食物存在
solidcircle(food.x, food.y, food.r);
}
EndBatchDraw();
}
//移动蛇
void snakemove() {//size为当前结点长度
//蛇的结点坐标发生改变
if (score > 0) {//得分不为0
for (int i = 0; i < score - 1; i++) {
other.coor[i] = other.coor[i + 1];
}
other.coor[score - 1] = snake.coor[0];
}
for (int i = 0; i < snake.size - 1; i++) {//蛇身跟着蛇头移动
snake.coor[i] = snake.coor[i + 1];
}
switch (snake.dir) {//判断当前蛇的方向
case RIGHT://当前往右移动
snake.coor[snake.size - 1].x += snake.speed;//每次移动1格//移动蛇头
/*实现蛇穿墙
if(snake.coor[snake.size - 1].x>=WIDE){
snake.coor[snake.size - 1].x=RE;
}
*/
break;
case UP://当前往上移动
snake.coor[snake.size - 1].y -= snake.speed;//每次移动1格
break;
case DOWN://当前往下移动
snake.coor[snake.size - 1].y += snake.speed;//每次移动1格
break;
case LEFT://当前往左移动
snake.coor[snake.size - 1].x -= snake.speed;//每次移动1格
break;
}
}
//通过按键改变蛇的移动方向
void keyControl() {
//判断用户有没有使用按键
if (_kbhit()) {//判断用户有没有使用按键
switch (_getch()) {//用户通过按键进行交互,不需要按回车
//72 80 75 77为上下左右键的键值
case 'W':
case 'w':
case 72:
if (snake.dir != DOWN) {//蛇原来的方向不是向下
snake.dir = UP;//蛇的方向改为向上
}
break;
case 'S':
case 's':
case 80:
if (snake.dir != UP) {//蛇原来的方向不是向上
snake.dir = DOWN;//蛇的方向改为向下
}
break;
case 'A':
case 'a':
case 75:
if (snake.dir != RIGHT) {//蛇原来的方向不是向右
snake.dir = LEFT;//蛇的方向改为向左
}
break;
case 'D':
case 'd':
case 77:
if (snake.dir != LEFT) {//蛇原来的方向不是向左
snake.dir = RIGHT;//蛇的方向改为向右
}
break;
case 32://32为空格的键值,控制游戏是否暂停
flag = -flag;
}
}
}
void Eatfood() {
if (food.flag == true && abs(snake.coor[snake.size - 1].x - food.x) <= 13 && abs(snake.coor[snake.size - 1].y - food.y) <= 13) {//蛇头移动之后吃到了食物
food.flag = false;//标记食物被吃
score++;//得分增加
food_create();//重新生成食物
}
}
int main() {
Gameinit();
while (1) {
snakemove();
GameDraw();
keyControl();
if (flag == -1) {//游戏暂停
while (1) {
keyControl();
if (flag == 1) {//游戏继续
break;
}
}
}
Eatfood();
Sleep(100);//延迟100毫秒,防止蛇移动速度过快
}
return 0;
}