美文网首页
C语言贪吃蛇游戏源码

C语言贪吃蛇游戏源码

作者: 听风知细雨 | 来源:发表于2018-06-01 11:16 被阅读0次

    一、贪吃蛇小游戏简介:

            用上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,也不能咬到自己的身体,等到了一定的分数,就能过关。

    二、函数框架

    三、数据结构

    typedef struct Snake  

    {  

    size_t x;  //行  

    size_t y;  //列  

    struct Snake* next;  

    }Snake, *pSnake;  

    定义蛇的结构体,利用单链表来表示蛇,每个结点为蛇身体的一部分。

    四、代码实现(vs2010  c语言)

    1.Snake.h

    #ifndef __SNAKE_H__  

    #define __SNAKE_H__  

    #include   

    #include   

    #include   

    #include   

    #include   

    #include   

    //标识地图大小  

    #define ROW_MAP 10    //地图的行  

    #define COL_MAP 20    //地图的列  

    #define SUCCESS_SCORE 10//通关分数  

    enum Direction //蛇行走的方向  

    {  

    R,//右  

    L,//左  

    U,//上  

    D//下  

    }Direction;  

    enum State  

    {  

    ERROR_SELF,//咬到自己  

    ERROR_WALL,//撞到墙  

    NORMAL,//正常状态  

    SUCCESS//通关  

    }State;  

    typedef struct Snake  

    {  

    size_t x;  //行  

    size_t y;  //列  

    struct Snake* next;  

    }Snake, *pSnake;  

    void StartGame();  

    void RunGame();  

    void EndGame();  

    #endif  


    2.Snake.c

    #include "Snake.h"  

    pSnake head = NULL;//定义蛇头指针  

    pSnake Food = NULL;//定义食物指针  

    int sleeptime = 500;//间隔时间,用来控制速度  

    int Score = 0;  //总分  

    int everyScore = 1; //每步得分  

    //定义游戏中用到的符号  

    const char food = '#';  

    const char snake = '*';  

    void Pos(int x, int y)   //控制输出光标  

    {  

    COORD pos;//pos为结构体  

    pos.X = x;//控制列  

    pos.Y = y;//控制行  

    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);//读取标准输出句柄来控制光标为pos  

    }  

    void Face()  

    {  

    system("color 0C");  

    printf("*******************************************************\n");  

    printf("*                Welcome to Snake Game!               *\n");  

    printf("*                                                     *\n");  

    printf("*             ->开始游戏请按 enter键                  *\n");  

    printf("*             ->退出游戏请按 esc键                    *\n");  

    printf("*             ->暂停游戏请按 space键                  *\n");  

    printf("*             ->通过上下左右键来控制蛇的移动          *\n");  

    printf("*             ->通过F1键减速        F2键加速          *\n");  

    printf("*******************************************************\n");  

    }  

    void Map()   //初始化地图  

    {  

    int i = 0;  

    for(i = 0; i

        {  

            Pos(i, 0);  

    printf("■");  

            Pos(i, ROW_MAP-1);  

    printf("■");  

        }  

    for(i = 0; i

        {  

            Pos(0, i);  

    printf("■");  

            Pos(COL_MAP-2, i);  

    printf("■");  

        }  

    }  

    void PrintSnake()  //打印蛇  

    {  

        pSnake cur = head;  

    while(cur)  

        {  

            Pos(cur->y, cur->x);  

    printf("%c", snake);  

            cur = cur->next;  

        }  

    }  

    void InitSnake()    //初始化蛇身  

    {  

    int initNum = 3;  

    int i = 0;  

        pSnake cur;  

    head = (pSnake)malloc(sizeof(Snake));  

        head->x = 5;  

        head->y = 10;  

        head->next = NULL;  

        cur = head;  

    for(i = 1; i < initNum; i++)  

        {  

    pSnake newNode = (pSnake)malloc(sizeof(Snake));  

            newNode->x = 5+i;  

            newNode->y = 10;  

            newNode->next = NULL;  

            cur->next = newNode;  

            cur = cur->next;  

        }  

        PrintSnake();  

    }  

    void CreateFood()  //在地图上随机产生一个食物  

    {  

        pSnake cur = head;  

    Food = (pSnake)malloc(sizeof(Snake));  

    //产生x~y的随机数 k=rand()%(Y-X+1)+X;  

        srand((unsigned)time(NULL));  

        Food->x = rand()%(ROW_MAP-2 - 1 + 1)+1;  

        Food->y = rand()%(COL_MAP-3 - 2 + 1)+2;  

        Food->next = NULL;  

    while(cur)   //检查食物是否与蛇身重合  

        {  

    if(cur->x == Food->x && cur->y == Food->y)  

            {  

                free(Food);  

                Food = NULL;  

                CreateFood();  

    return;  

            }  

            cur = cur->next;  

        }  

        Pos(Food->y, Food->x);  

    printf("%c", food);  

    }  

    void StartGame()  //游戏开始的所有设置  

    {  

        Face();  

    system("pause");  

    if(GetAsyncKeyState(VK_RETURN))  

        {  

    system("cls");  

            Pos(COL_MAP+5, 1);  

    printf("当前分数/通关分数:");  

            Pos(COL_MAP+20, 1);  

    printf("%d/%d", Score, SUCCESS_SCORE);  

            Pos(COL_MAP+5, 2);  

    printf("当前分每步得分:");  

            Pos(COL_MAP+20, 2);  

    printf("%d", everyScore);  

            Pos(COL_MAP+5, 3);  

    printf("\n");  

            Pos(COL_MAP+5, 4);  

    printf("速度越快 得分越高哦!!\n");  

            Map();  

            InitSnake();  

            CreateFood();  

        }  

    else if(GetAsyncKeyState(VK_ESCAPE))  

        {  

            exit(0);  

        }  

    }  

    int IsCrossWall()             //判断是否碰到墙  

    {  

    if(head->x <= 0 || head->x >= ROW_MAP-1  

            ||head->y <= 1 || head->y >= COL_MAP-2)  

        {  

            State = ERROR_WALL;  

    return 0;  

        }  

    return 1;  

    }  

    int IsEatSelf(pSnake newHead)  //判断是否咬到自己  

    {  

        pSnake cur = head;  

        assert(newHead);  

    while(cur)  

        {  

    if(cur->x == newHead->x && cur->y == newHead->y)  

            {  

                State = ERROR_SELF;  

    return 0;  

            }  

            cur = cur->next;  

        }  

    return 1;  

    }  

    int IsFood(pSnake pos)  //判断该位置是不是食物  

    {  

        assert(pos);  

    if(pos->x == Food->x && pos->y == Food->y)  

        {  

    return 1;  

        }  

    return 0;  

    }  

    void SnakeMove()   //蛇移动一次  

    {  

        pSnake newHead = NULL;  

    newHead = (pSnake)malloc(sizeof(Snake));  

    if(Direction == R)  

        {  

            newHead->x = head->x;  

            newHead->y = head->y+1;  

            newHead->next = head;  

        }  

    else if(Direction == L)  

        {  

            newHead->x = head->x;  

            newHead->y = head->y-1;  

            newHead->next = head;  

        }  

    else if(Direction == U)  

        {  

            newHead->x = head->x-1;  

            newHead->y = head->y;  

            newHead->next = head;  

        }  

    else if(Direction == D)  

        {  

            newHead->x = head->x+1;  

            newHead->y = head->y;  

            newHead->next = head;  

        }  

    if(IsFood(newHead))  

        {  

            head = newHead;  

            PrintSnake();  

            CreateFood();  

            Score += everyScore;  

            Pos(COL_MAP+20, 1);  

    printf("%d/%d", Score, SUCCESS_SCORE);  

    if(Score >= SUCCESS_SCORE)  

            {  

                State = SUCCESS;  

            }  

        }  

    else   

            {  

    if(IsCrossWall() && IsEatSelf(newHead))  

                {  

                    pSnake cur = NULL;  

                    head = newHead;  

                    cur = head;  

    //删除蛇尾并打印  

    while(cur->next->next != NULL)  

                    {  

                        Pos(cur->y, cur->x);  

    printf("%c", snake);  

                        cur = cur->next;  

                    }  

                    Pos(cur->y, cur->x);  

    printf("%c", snake);  

                    Pos(cur->next->y, cur->next->x);  

    printf(" ");  //打印空格来覆盖频幕上的蛇尾  

                    free(cur->next);  

                    cur->next = NULL;  

                }  

    else  

                {  

                    free(newHead);  

                    newHead = NULL;  

                }  

        }  

    }  

    void Pause()  

    {  

    while(1)  

        {  

            Sleep(sleeptime);  

    if(GetAsyncKeyState(VK_SPACE))  

            {  

    break;  

            }  

        }  

    }  

    void ControlSnake() //用键盘控制游戏  

    {  

    if(GetAsyncKeyState(VK_UP) && Direction!=D)  

        {  

            Direction = U;  

        }  

    else if(GetAsyncKeyState(VK_DOWN) && Direction!=U)  

        {  

            Direction = D;  

        }  

    else if(GetAsyncKeyState(VK_LEFT) && Direction!=R)  

        {  

            Direction = L;  

        }  

    else if(GetAsyncKeyState(VK_RIGHT) && Direction!=L)  

        {  

            Direction = R;  

        }  

    else if(GetAsyncKeyState(VK_F1))  

        {  

    if(sleeptime != 500)  

            {  

                sleeptime = 500;  

                everyScore = 1;  

                Pos(COL_MAP+20, 2);  

    printf("%d", everyScore);  

            }  

        }  

    else if(GetAsyncKeyState(VK_F2))  

        {  

    if(sleeptime != 300)  

            {  

                sleeptime = 300;  

                everyScore = 2;  

                Pos(COL_MAP+20, 2);  

    printf("%d", everyScore);  

            }  

        }  

    else if(GetAsyncKeyState(VK_SPACE))  

        {  

            Pause();  

        }  

    else if(GetAsyncKeyState(VK_ESCAPE))  

        {  

            exit(0);  

        }  

    }  

    void StateGame() //判断游戏失败或成功  

    {  

    if(State == ERROR_SELF)  

        {  

    system("cls");  

    printf("很遗憾,蛇咬到自己,游戏失败!\n");  

        }  

    else if(State == ERROR_WALL)  

        {  

    system("cls");  

    printf("很遗憾,蛇碰到墙壁,游戏失败!\n");  

        }  

    else if(State == SUCCESS)  

        {  

    system("cls");  

    printf("恭喜您,已通关!!!\n");  

        }  

    }  

    void RunGame()  

    {  

    Direction = R;//蛇初始行走方向为右  

    State = NORMAL;//游戏初始为正常状态  

    while(1)  

        {  

            ControlSnake();  

            SnakeMove();  

    if(State != NORMAL)  

            {  

                StateGame();  

    break;  

            }  

            Sleep(sleeptime);  

        }  

    }  

    void EndGame()  //释放链表并恢复默认值  

    {  

        pSnake cur = head;  

    while(cur)  

        {  

            pSnake del = cur;  

            cur = cur->next;  

            free(del);  

            del = NULL;  

        }  

        head = NULL;  

    if(Food != NULL)  

        {  

            free(Food);  

            Food = NULL;  

        }  

        Score = 0;  

        everyScore = 1;  

        sleeptime = 500;  

    }  


    3.Test.c

    #include "Snake.h"  

    int main()  

    {  

    while(1)  

        {  

            StartGame();  

            RunGame();  

            EndGame();  

        }  

    system("pause");  

    return 0;  

    }  


    五、运行界面展示

    1.欢迎界面

    相关文章

      网友评论

          本文标题:C语言贪吃蛇游戏源码

          本文链接:https://www.haomeiwen.com/subject/obnnjftx.html