用C语言设计贪吃蛇

来源:互联网 发布:html5手机框架 apache 编辑:程序博客网 时间:2024/05/20 04:27

  贪吃蛇是每个接触过游戏的人一定玩过的游戏之一,其经典性与可玩性使得这款游戏经久不衰,近些年随着各种贪吃蛇手游的上线,使得这款游戏又重新回到了我们的视线。那么下面我们就来看看如何用C语言设计一款贪吃蛇游戏。


设计前的思考


需要实现的功能:
  1、地图设计
  2、贪吃蛇的初始化及自动移动
  3、如何实现用WASD四个键位控制贪吃蛇的方向
  4、随机在地图上生成食物
  5、蛇吃掉食物时蛇身可以增长
  6、在蛇头撞到蛇身或障碍物时,游戏结束

初步的构思
  1、首先定义一个二维数组,并为其赋值,包括地图与蛇的初始位置
  2、用while(1)循坏实现蛇的持续行走:用两个数组分别记录蛇的X,Y坐标,每次循坏时把蛇身的坐标数组向前进,蛇头另外考虑。利用system(“cls”)函数实现清屏,并在循环重新开始时再次打印二维数组,实现蛇的前进
  3、利用kbhit()函数检测键盘是否有敲击,若有敲击,利用getch()获取值,并改变蛇头的移动方向(及坐标)
  3、利用srand()函数随即在地图空位置生成食物
  4、当检测到之前生成的食物消失时,给蛇身坐标数组重新赋值,使蛇身重新增长
  5、当检测到地图中下一步蛇头坐标位置不为空时,结束游戏


初步的代码(visual studio 2017版本)

    #include<stdio.h>    #include<windows.h>    #include<stdlib.h>    #include<time.h>    #include<string.h>    #include<conio.h>    #define SNAKE_MAX_LENGTH 20    #define SNAKE_HEAD 'H'    #define SNAKE_BODY 'X'    #define BLANK_CELL ' '    #define SNAKE_FOOD '$'    #define WALL_CELL '*'    void snakeMove(void);//蛇的移动(游戏主体)    void put_food(void);//随机在maps中生成food    void output(void);//刷新屏幕    void gameover(void);//当蛇头撞墙或者撞到身体时游戏结束    void createNewArray(void);//当蛇身边长后创建新的X、Y坐标数组    char map[12][12] =    { "************",    "*XXXXH     *",    "*          *",    "*          *",    "*          *",    "*          *",    "*          *",    "*          *",    "*          *",    "*          *",    "*          *",    "************" };    int snakeX[SNAKE_MAX_LENGTH] = { 1,2,3,4,5 };//蛇身的横坐标    int snakeY[SNAKE_MAX_LENGTH] = { 1,1,1,1,1 };//蛇身的纵坐标    int snakeLength = 5;//蛇的初始长度    int snakeLive = 1;//蛇的生命    int foodYes = 1;//是否需要重新生成事物    int foodX, foodY;//事物的横纵坐标    char dir = 'd';//定义方向    int lenthchange = 0;//判断是否需要更改蛇身坐标数组长度    int tempX, tempY;//临时变量,当蛇变长时储存蛇尾坐标    int main()    {        int i;        while (1)        {            put_food();//设置食物            output();//输出字符矩阵            if (_kbhit())//检测键盘是否有敲击            {                dir = _getch();            }            tempX = snakeX[0];//储存蛇尾坐标,在蛇身增长时需要用到            tempY = snakeY[0];            map[snakeY[0]][snakeX[0]] = BLANK_CELL;//把蛇尾变为空格            for (i = 0; i < snakeLength - 1; i++)//蛇身往前移动            {                snakeX[i] = snakeX[i + 1];                snakeY[i] = snakeY[i + 1];                map[snakeY[i]][snakeX[i]] = SNAKE_BODY;            }            switch (dir)            {                case 'w':                case 'W':snakeY[snakeLength - 1]--; break;//蛇头向上转                case 'a':                case 'A':snakeX[snakeLength - 1]--; break;//蛇头向左转                case 's':                case 'S':snakeY[snakeLength - 1]++; break;//蛇头向下转                case 'd':                case 'D':snakeX[snakeLength - 1]++; break;//蛇头向右转            }            gameover();//判断游戏是否结束            if (snakeLive == 0) break;//蛇的生命为零,跳出循环            map[snakeY[snakeLength - 1]][snakeX[snakeLength - 1]] = SNAKE_HEAD;//蛇头移动            put_food();//判断食物是否被吃            createNewArray();            Sleep(300);//设置速度            system("cls");//清空屏幕        }        return 0;    }    void output(void)    {        int i, j;        for (i = 0; i<12; i++)        {            for (j = 0; j < 12; j++)                printf("%c", map[i][j]);            printf("\n");        }    }    void gameover(void)    {        if ((snakeY[snakeLength - 1] == 0 || snakeY[snakeLength - 1] == 11) || (snakeX[snakeLength - 1] == 0 || snakeX[snakeLength - 1] == 11))        {            printf("Game Over!\n");            snakeLive--;        }        else if (map[snakeY[snakeLength - 1]][snakeX[snakeLength - 1]] == SNAKE_BODY)        {            printf("Game Over!\n");            snakeLive--;        }    }    void put_food(void)    {        srand(time(NULL));        if (foodYes == 1)        {            foodX = rand() % 10 + 1;            foodY = rand() % 10 + 1;            while ((map[foodY][foodX] == SNAKE_BODY) || (map[foodY][foodX] == SNAKE_HEAD))            {                foodX = rand() % 10 + 1;                foodY = rand() % 10 + 1;            }            map[foodY][foodX] = SNAKE_FOOD;            foodYes = 0;        }        if (map[foodY][foodX] != SNAKE_FOOD)        {            if (snakeLength < SNAKE_MAX_LENGTH)            {                snakeLength++;                lenthchange = 1;            }            foodYes = 1;        }    }    void createNewArray(void)    {        int i;        if (lenthchange == 1)        {            for (i = snakeLength - 1; i > 0; i--)            {                snakeX[i] = snakeX[i - 1];                snakeY[i] = snakeY[i - 1];            }        map[snakeY[snakeLength - 1]][snakeX[snakeLength - 1]] = SNAKE_HEAD;        snakeX[0] = tempX;        snakeY[0] = tempY;        for (i = 0; i < snakeLength - 1; i++)            map[snakeY[i]][snakeX[i]] = SNAKE_BODY;        lenthchange = 0;        }    }

程序的优化:

1、为了使游戏的难度增加,可以利用Sleep()函数,上面的代码中我们设置的是Sleep(300),可以调大这一数值,是蛇的速度更快,也可以在每次循环后逐渐增大。
2、可以看到我们在上面的代码中,只给蛇设置了一条命,若是为了增加游戏的趣味性,也可以增加蛇的生命
3、可以定义一个分数变量,每当蛇吃掉一个食物后,增加这个变量,让此游戏具有一定的竞技性。


这一版本的贪吃蛇仅仅是一个简易版,运用我们程序员的聪明才智,还可以在这基础上添加许多有趣的功能。

阅读全文
'); })();
1 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 安东阳 东阳首富 浙江东阳 林东阳 谢东阳华笙 安东阳歌曲 东阳金航辉 东阳金航晖 东阳邮编 东阳横店 东阳村 池月乔东阳 安东阳资料 东阳街道 东阳街 东阳房价 东阳卢宅 浙江省东阳 谢东阳 浙江东阳市 义乌东阳 东阳信息港 东阳吧 东阳吴梦良 于东阳 送东阳马生序 东阳首富金航辉照片 金航辉东阳首富之子照片 东阳市属于哪个市 送东阳马生序原文 东阳首富之子金航辉个人资料 林东阳严若萱 东阳首富金航辉 安东阳全部歌曲 东阳人民医院 送东阳马生序朗读 东阳市人民医院 东阳首富之子金航晖照片 东阳马生序朗读 浙江省东阳市 宋濂送东阳马生序