经典版:
要求:
1碰到四周和自身游戏结束;
2迟到食物蛇身增长;
3食物吃得越多游戏越快;
4通过w,a,s,d可控制蛇头的方向;
5蛇身颜色不一致。
源码(需要easy-x)
// 贪吃蛇.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include
#include
#include
#include
#define BLOCK_SIZE 20
#define HEIGHT 30
#define WIDTH 40
int blocks[HEIGHT][WIDTH] = { 0 },cs=0;//储存地图信息和记录吃的食物数量,来控制速度;
char moveDirection;//控制舍身运动方向;
int food_i,food_j;//食物的坐标
int isfailure=0;//是否失败的标识符
void startup() {//初始化函数
int i;
blocks[HEIGHT / 2][WIDTH / 2] = 1; //1代表蛇头,给蛇头位置
for (i = 1; i < 5; i++) {
blocks[HEIGHT/2][WIDTH/2-i] = i+1;
}//初始化一个长度为5的蛇身;
moveDirection ='d';//初始化蛇身方向为"d";
// srand(time(0));//给srand()时间种子,防止随机有规律有寻;
food_i = rand() % (HEIGHT - 5) + 2;//初始化食物坐标
food_j = rand() % (WIDTH - 5) + 2;
initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE);//初始化窗体
setlinecolor(RGB(200, 200, 200));//设置地图中每个方块的边界颜色
BeginBatchDraw();//开始批量绘制,防止闪屏,必须与FlushBatchDraw()一起使用;
}
void show() {//绘制函数
cleardevice();//清屏与绘画搭配使用,做到动画的效果;
int i, j;
for (i = 0; i < HEIGHT; i++) {
for (j = 0; j < WIDTH; j++) {//整个地图遍历
if (blocks[i][j] > 0) {
setfillcolor(HSVtoRGB(blocks[i][j] * 10, 0.9, 0.7));//蛇身的绘制,并用到HSVTORBG(),使蛇身颜色不一样;
}
else {
setfillcolor(RGB(150, 150, 150));//绘制非蛇身的场景;
}
fillrectangle(j *BLOCK_SIZE, i * BLOCK_SIZE, (j + 1) * BLOCK_SIZE, (i + 1) * BLOCK_SIZE);//真正的绘制函数;
}
}
setfillcolor(RGB(0, 255, 0));//设置食物颜色
fillrectangle(food_j * BLOCK_SIZE, food_i * BLOCK_SIZE, (food_j+ 1) * BLOCK_SIZE, (food_i+ 1) * BLOCK_SIZE);//在食物地址绘制食物;
if (isfailure ) {//如果游戏失败,绘制游戏失败标题;
setbkmode(TRANSPARENT);
settextcolor(RGB(255, 0, 0));
settextstyle(80, 0, _T("宋体"));
outtextxy(240, 220, _T("游戏失败"));
}
FlushBatchDraw();//按从BeginBatchDraw()开始的绘制要求绘制
}
void moveSnake() {//控制蛇身动作反应的内在函数
int i, j;
for (i = 0; i < HEIGHT; i++) {//给所有的蛇身的数组加一
for (j = 0; j < WIDTH; j++) {
if (blocks[i][j] > 0) {
blocks[i][j]++;
}
}
}
int oldtial_i, oldtial_j, oldHead_i, oldHead_j;
int max = 0;
for (i = 0; i < HEIGHT; i++) {
for (j = 0; j < WIDTH; j++) {
if (max=HEIGHT || newHead_i <= 0 || newHead_j >=WIDTH || newHead_j <= 0 || blocks[newHead_i][newHead_j]>0) {//蛇头蛇尾出界,以及检查到新蛇头在蛇身上,也就是蛇咬到自己为游戏失败;
isfailure = 1;
return ;
}
blocks[newHead_i][newHead_j] = 1;//给新蛇头的位置赋值1;
if (newHead_i==food_i && newHead_j==food_j) {//如果新蛇头位置在食物的地方,也就是蛇吃到了食物,并给食物重新给一个位置;
food_i = rand() % (HEIGHT - 5) + 2;
food_j = rand() % (WIDTH - 5) + 2;
cs++;//吃的次数加一;
}
else
blocks[oldtial_i][oldtial_j] = 0;//如果没迟到食物,把旧蛇尾赋值为
}
void updateWithoutInput() {
if (isfailure) {//游戏未失败继续
return;
}
if (cs > 7) {
cs = 7;//防止cs过大而过快
}
int sx = 10 - cs ;//通过cs来控制刷新率,从而控制速度。
static int waitIndex = 1;//设置静态变量,防止调用完该函数调用完后此变量内存空间被舍弃(效果和全局一样)。
waitIndex++;
if (waitIndex==sx) {//sx帧显示一次;
moveSnake();
waitIndex = 1;//循环重新开始
}
}
void updateWithInput() {
if (kbhit() && isfailure == 0) {//如果有输入,且未失败
char input = _getch();
if (input == 'a' || input == 's' || input == 'w' || input == 'd') {
moveDirection = input;
moveSnake();
}
}
}
int main()
{
startup();//初始化;
while (1) {//不断调用;
show();
updateWithoutInput();//更新与输入无关的参数;
updateWithInput();//更新与输入有关的参数;
}
return 0;
}
运行结果: