主要是对easyx图形库的使用。
按键说明:空格暂停,R重新开始,esc退出游戏,撞墙或头和尾相碰结束游戏。WASD和方向键都可以使用,不分大小写
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include <conio.h>//使用_getch()函数要包含的头文件
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define SNAKE_NUM 500
#define RADIUS 5 //蛇和食物半径
char cgrade[10];//转换游戏得分
int end_flag = 0;//游戏结束标志位
int main(void);
struct Snake
{
int size;//蛇的节数
int dir;//蛇的方向
int speed;//蛇的速度
POINT coor[SNAKE_NUM];//POINT是定义好的xy坐标,coor是蛇的最大节数,每一节蛇都要有坐标所以用数组
}snake;
struct Food
{
int x;
int y;
int r;//食物半径
bool flag;//食物是否被吃
DWORD color;//食物颜色
}food;
enum DIR
{
UP = 72,
DOWN = 80,
RIGHT = 77,
LEFT = 75,
ESC=27
};
//数据的初始化
void Game_Init()
{
//播放背景音乐
mciSendString("open ./res/1.mp3 alias BGM", 0, 0, 0);
mciSendString("play BGM repeat", 0, 0, 0);
//初始化图形窗口 SHOWCONSOLE显示控制台
initgraph(640, 520);
//设置随机数种子 GetTickCount()获取系统开机到现在所经过的毫秒数
srand(GetTickCount());
//初始化蛇
snake.size = 3;
snake.speed = 8;
snake.dir = RIGHT;
for (int i = 0; i < snake.size; i++)
{
snake.coor[i].x = 40-snake.speed*i;//coor[0]是蛇头
snake.coor[i].y = 10;
}
//初始化食物 rand()随机产生一个整数,如果没有设置随机数种子,每次产生的都是固定的整数
//设置种子需要头文件stdlib.h,一般把时间作为种子,因为时间在不断变化
food.x = rand() % 580+20;
food.y = rand() % 420+20;
food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
food.r = RADIUS;
food.flag = true;
}
void Key_Control()
{
if (_kbhit())//判断是否有按键按下
{
switch (_getch())//判断按下的是哪个按键
{
case 'W':
case 'w':
case UP:
if (snake.dir != DOWN)
{
snake.dir = UP;
}
break;
case 'S':
case 's':
case DOWN:
if (snake.dir != UP)
{
snake.dir = DOWN;
}
break;
case 'A':
case 'a':
case LEFT:
if (snake.dir != RIGHT)
{
snake.dir = LEFT;
}
break;
case 'D':
case 'd':
case RIGHT:
if (snake.dir != LEFT)
{
snake.dir = RIGHT;
}
break;
case ' ':
while (1)//按一次进入while里死循环,相当于暂停
{
if (_getch() == ' ')//再按一次进入这里,return退出Key_Control函数,执行行Snake_Move函数,相当于又开始游戏
{
return;
}
}
break;
case 'r':
case 'R':
system("cls");
main();//重新开始
break;
case ESC: //退出
system("cls"); //清空屏幕
exit(0);
}
}
}
void Game_Draw()
{
BeginBatchDraw();//双缓冲绘图,防止闪频
//设置背景颜色
setbkcolor(RGB(128, 128, 192));
cleardevice();//覆盖默认背景颜色
//画线段
setlinecolor(BLACK);//表示设立线段的颜色
line(0, 480, 640, 480);//绘画线段
settextstyle(20, 0, _T("微软雅黑"));
settextcolor(BLACK);//设置文字颜色
outtextxy(10, 490, "当前得分:");//设置文本起始坐标,输出文本。
sprintf(cgrade, "%d", snake.size - 3);
outtextxy(95, 490, cgrade);//设置文本起始坐标,输出文本。
if (end_flag == 1)
{
settextstyle(40, 0, _T("微软雅黑"));
settextcolor(RED);//设置文字颜色
outtextxy(200, 150, "游戏结束");//设置文本起始坐标,输出文本。
outtextxy(200, 190, "重新开始请按R");//设置文本起始坐标,输出文本。
}
for (int i = 0; i < snake.size; i++)
{
solidcircle(snake.coor[i].x, snake.coor[i].y, RADIUS);//画实心圆代表蛇的节
if (abs(snake.coor[0].x - snake.coor[i + 1].x) <= 5 && abs(snake.coor[0].y - snake.coor[i + 1].y) <= 5)
{
end_flag = 1;
}
}
//绘制食物
if (food.flag)
{
solidcircle(food.x, food.y, RADIUS);//画实心圆代表蛇的节
}
EndBatchDraw();
}
//通过按键改变蛇的方向
void Snake_Move()
{
//身体跟着头动
if (end_flag == 0)
{
for (int i = snake.size - 1; i > 0; i--)
{
snake.coor[i] = snake.coor[i - 1];
}
}
else//蛇头碰到蛇身就暂停
{
return;
}
//蛇头改变坐标,蛇身从蛇尾一个个往前
switch (snake.dir)
{
case UP:
if (snake.coor[0].y <= 5) //snake.coor[0].y是圆心,圆心等于5的时候就是碰到墙了
{
end_flag = 1;
return;
//snake.coor[0].y = 480;
}
snake.coor[0].y -= snake.speed;
break;
case DOWN:
if (snake.coor[0].y >= 475) //snake.coor[0].y是圆心,圆心等于5的时候就是碰到墙了
{
end_flag = 1;
return;
//snake.coor[0].y = 0;
}
snake.coor[0].y += snake.speed;
break;
case RIGHT:
if (snake.coor[0].x >= 635) //snake.coor[0].y是圆心,圆心等于5的时候就是碰到墙了
{
end_flag = 1;
return;
}
snake.coor[0].x += snake.speed;
break;
case LEFT:
if (snake.coor[0].x <= 5) //snake.coor[0].y是圆心,圆心等于5的时候就是碰到墙了
{
end_flag = 1;
return;
}
snake.coor[0].x -= snake.speed;
break;
}
}
void Eat_Food()
{
if (food.flag==true&&abs(snake.coor[0].x - food.x)<food.r && abs(snake.coor[0].y - food.y) <food.r)
{
food.flag = false;
snake.size++;
}
if (!food.flag)
{
food.x = rand() % 580 + 20;
food.y = rand() % 420 + 20;
food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
food.r = RADIUS;
food.flag = true;
}
}
//_getch是阻塞函数
//做界面1,创建一个窗口,图形窗口
int main(void)
{
end_flag = 0;
memset(cgrade, 0, 10);//数组清零
Game_Init();
while (1)
{
Key_Control();
Game_Draw();
Snake_Move();
Eat_Food();
Sleep(60);
}
return 0;
}