基于easyx和C语言的简易贪吃蛇游戏源码
程序员文章站
2024-03-18 10:04:10
...
一、描述
基于easyx和C语言的简易贪吃蛇游戏源码。
二、程序要求
1、蛇可以穿墙移动
2、随机生成食物
3、显示分数
4、蛇撞到身体即死亡
三、程序设计及思路
根据上图,我们需要:
1、创建图形窗口并设置背景颜色(根据个人选择,可以使用默认黑色背景)。
2、蛇的结构体
3、食物的结构体
4、蛇的移动、吃食物变长
5、食物重新生成
6、死亡判定
7、绘制分数等
一)蛇和食物的结构体属性
struct Snake
{
int speed; //蛇的移动速度
int dir; //蛇的方向
int r; //蛇的大小
int size; //蛇的长度
POINT num[MAX]; //每一节蛇的坐标
int score; //分数
int flag; //存在标志
}snake;
struct Food
{
int x; //食物的坐标
int y;
int r; //实物的大小
COLORREF color; //实物的颜色
二)初始化
//游戏初始化
void GameInit()
{
mciSendString("close DIE", 0, 0, 0);
mciSendString("open ./ress/snake_bgm.mp3 alias BGM", 0, 0, 0);
mciSendString("play BGM repeat", 0, 0, 0);
srand(GetTickCount()); //设置随机数种子
initgraph(WIDTH, HEIGHT);
setbkcolor(RGB(140, 186, 236)); //设置背景颜色
settextcolor(BLACK); //设置字体颜色及样式
settextstyle(30, 0, "黑体");
//蛇初始化
snake.dir = UP;
snake.speed = 16;
snake.r = 8;
snake.size = 3;
snake.num[0] = { WIDTH / 2, HEIGHT / 2 };
snake.num[1] = { WIDTH / 2, HEIGHT / 2 + 16};
snake.num[2] = { WIDTH / 2, HEIGHT / 2 + 32 };
snake.score = 0;
snake.flag = 1;
//食物初始化
food.x = rand() % WIDTH;
food.y = rand() % HEIGHT;
food.r = 8;
food.color = RGB(rand() % 255, rand() % 255, rand() % 255);
}
三)游戏绘制
//游戏绘制
void GameDraw()
{
BeginBatchDraw();
cleardevice();
//绘制分数
char score[100] = "";
sprintf(score, "分数:%d", snake.score);
outtextxy(0, 0, score);
//绘制蛇
if (snake.flag)
{
for (int i = 0; i < snake.size; i++)
{
setfillcolor(BLACK);
solidcircle(snake.num[i].x, snake.num[i].y, snake.r);
}
}
//绘制食物
setfillcolor(food.color);
solidcircle(food.x, food.y, food.r);
EndBatchDraw();
}
四)蛇的移动
//蛇移动
void SnakeMove()
{
//移动蛇身
for (int i = snake.size - 1; i > 0; i--)
{
snake.num[i] = snake.num[i - 1];
}
//移动蛇头
switch (snake.dir)
{
case UP:
snake.num[0].y -= snake.speed;
if (snake.num[0].y < 0)
{
snake.num[0].y = HEIGHT;
}
break;
case DOWN:
snake.num[0].y += snake.speed;
if (snake.num[0].y > HEIGHT)
{
snake.num[0].y = 0;
}
break;
case LEFT:
snake.num[0].x -= snake.speed;
if (snake.num[0].x < 0)
{
snake.num[0].x = WIDTH;
}
break;
case RIGHT:
snake.num[0].x += snake.speed;
if (snake.num[0].x > WIDTH)
{
snake.num[0].x = 0;
}
break;
}
}
五)方向控制
//方向控制
void SnakeDir()
{
if ((GetAsyncKeyState('w') || GetAsyncKeyState('W') || GetAsyncKeyState(VK_UP)) && snake.dir!=DOWN)
{
snake.dir = UP;
}
if ((GetAsyncKeyState('s') || GetAsyncKeyState('S') || GetAsyncKeyState(VK_DOWN)) && snake.dir != UP)
{
snake.dir = DOWN;
}
if ((GetAsyncKeyState('a') || GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT)) && snake.dir != RIGHT)
{
snake.dir = LEFT;
}
if ((GetAsyncKeyState('d') || GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)) && snake.dir != LEFT)
{
snake.dir = RIGHT;
}
}
六)吃食物和死亡判定
//吃食物
void EatFood()
{
if (snake.num[0].x > food.x - 16 && snake.num[0].x<food.x + 16 &&
snake.num[0].y>food.y - 16 && snake.num[0].y < food.y + 16)
{
mciSendString("close FOOD", 0, 0, 0);
mciSendString("open ./ress/eatfood.mp3 alias FOOD", 0, 0, 0);
mciSendString("play FOOD", 0, 0, 0);
food.x = rand() % WIDTH;
food.y = rand() % HEIGHT;
food.color = RGB(rand() % 255, rand() % 255, rand() % 255);
snake.size++;
snake.score++;
}
}
//死亡判定(蛇头撞到蛇身)
void Die()
{
for (int i = 4; i < snake.size; i++) //蛇头不可能撞到第4节(头是第一节),所以从第五节开始判定
{
if (snake.num[0].x == snake.num[i].x &&
snake.num[0].y == snake.num[i].y)
{
mciSendString("close BGM", 0, 0, 0);
mciSendString("open ./ress/die.mp3 alias DIE", 0, 0, 0);
mciSendString("play DIE", 0, 0, 0);
snake.flag = 0;
}
if (snake.flag == 0)
{
int isok=MessageBox(GetHWnd(), "你输了,垃圾!~", "提示", MB_OKCANCEL);
if (isok == IDOK)
{
GameInit();
}
else
{
exit(0);
}
}
}
}
总结
编程前,画一幅草图能帮助你理清自己的思路,将项目细分就能很好的找到切入点。另外,一定要函数专用,
绘图的函数就只干绘图的事,移动的函数就只干移动的事,这样在出现bug时才能快速的找到问题所在。
下一篇: C语言贪吃蛇—基于EasyX图形库