C语言小游戏 ---- 贪吃蛇

贪吃蛇是一个生活中很常见的小游戏,相信大家都玩过吧,下面我来说说具体的实现步骤。完整代码在文章最后

实现环境:VS2017

贪吃蛇具有以下功能:
1.按F1加速,F2减速。加速食物的分数增高,减速食物的分数降低
2.按空格暂停
3.按ESC退出游戏

下面有两种贪吃蛇:

  1. 撞墙会死
  2. 撞墙不会死

撞墙会死版贪吃蛇

1.首先实现刚开始的游戏界面,如下图

这里写图片描述
这里写图片描述

这里需要知道怎么控制光标的位置,以及怎样设定窗口的大小

设定窗口的大小
使用system库函数和DOS命令设置控制台窗口

system(“mode con cols=100 lises=30”);
//mode 为DOS命令
//cols —- 设置控制台的列数
//lines —- 设置控制台的行数

控制光标的位置
HANDLE GetStdHandle( DWORD nStdHandle );

//返回标准的输入、输出或错误的设备的 句柄,也就是获得输入、输出/错误的屏幕 缓冲区的句柄。
参数为三种
STD_INPUT_HANDLE //标准输入的句柄
STD_OUTPUT_HANDLE //标准输出的句柄
STD_ERROR_HANDLE //标准错误的句柄

BOOL SetConsoleCursorPosition( HANDLE hConsoleOutput, COORD dwCursorPosition );

如果用户定义了COORD pos,那么pos其实是一个结构体变量,其中X和Y是它的成员,通过修改pos.X和pos.Y的值就可以实现光标的位置控制
用例:SetConsoleCursorPosition(handle, pos);

知道了这两个函数我们的清屏就很好实现了

void SetPos(int x, int y)
{
    COORD pos = { 0 };
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取设备
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}
void WelcomeToGame()
{
    //窗口大小
    system("mode con cols=100 lines=30");
    SetPos(39, 14);
    printf("欢迎来到贪吃蛇游戏");
    Sign();
    SetPos(39, 25);
    system("pause");//暂停
    system("cls");//清屏
    SetPos(25, 14);
    printf("用↑,↓,←,→来控制蛇的移动,F1为加速,F2为减速");
    SetPos(35, 15);
    printf("提示:加速获得的分数更高");
    Sign();
    SetPos(39, 25);
    system("pause");
    system("cls");

}

2.绘制地图

这里写图片描述

因为上图的小方框是输入法中的特殊字符,一个小方框站两个X单位一个Y单位。

根据上图,实现代码如下:

void CreateMap()
{
    int i = 0;
    //上
    for (i = 0; i <= 58; i+=2)
    {
        SetPos(i, 0);
        printf(WALL);
    }
    //下
    for (i = 0; i <= 58; i += 2)
    {
        SetPos(i, 29);
        printf(WALL);
    }
    //左
    for (i = 1; i <= 28; i++)
    {
        SetPos(0, i);
        printf(WALL);
    }
    //右
    for (i = 1; i <= 28; i++)
    {
        SetPos(58, i);
        printf(WALL);
    }
}

3.绘制蛇

这里的蛇使用链表保存,所以需要蛇身体节点,以及维护整条蛇的数据,另外蛇的前进放向以及游戏的运行状态我们定义成枚举。

typedef struct SnakeNode
{
    int x;
    int y;
    struct SnakeNode* next;
}SnakeNode,*pSnakeNode;

enum Dirction { UP = 1, DOWN, LEFT, RIGHT};
enum GameStatus { OK, NORMAL_END, KILL_BY_WALL,  KILL_BY_SELF};

typedef struct Snake
{
    pSnakeNode _pSnake;//维护蛇身
    pSnakeNode _pFood;//食物的位置
    int ToTalScore;//总分数
    int _AddScore;//每次增加分数
    int _SleepTime;//休眠时间
    enum Dirction _Dir;//方向
    enum GameStatus _Status;//游戏状态
}Snake,*pSnake;

pSnakeNode BuyNode()
{
    pSnakeNode NewNode = (pSnakeNode)malloc(sizeof(SnakeNode));
    if (NewNode == NULL)
    {
        perror("BuyNode::malloc( )");
        exit(EXIT_FAILURE);
    }
    NewNode->x = 0;
    NewNode->y = 0;
    NewNode->next = NULL;
    return NewNode;
}

void InitSnake(pSnake snake)
{
    int i = 0;
    pSnakeNode Cur = NULL;
    pSnakeNode first = BuyNode();
    first->x = INIT_X;
    first->y = INIT_Y;
    for (i = 0; i < 4; i++)
    {
        Cur = BuyNode();
        Cur->x = first->x - 2;
        Cur->y = first->y;
        Cur->next = first;
        first = Cur;
    }
    while (Cur)
    {
        SetPos(Cur->x, Cur->y);
        printf(Food);
        Cur = Cur->next;
    }
    snake->_pSnake = first;
    Sign();
}

4.产生食物

这里会用到随机函数,注意食物不能出现在墙以及墙以外和蛇身上
如下图为处是状态
这里写图片描述

void CreateFood(pSnake snake)
{

    pSnakeNode pFood = NULL;
    pFood = BuyNode();
    pSnakeNode Cur = snake->_pSnake;
    pFood->y = rand() % 28 + 1;
    do 
    {
        pFood->x = rand() % 55 + 2;
    } while (pFood->x % 2 != 0);
    while (Cur)
    {
        if (Cur->x == pFood->x && Cur->y == pFood->y)
        {
            CreateFood(snake);
            return;
        }
        Cur = Cur->next;
    }
    snake->_pFood = pFood;
    SetPos(pFood->x, pFood->y);
    printf(Food);
}

4.让蛇动起来

根据pSnake中定义的方向,进行移动,如果有食物,就吃掉,并且身体长长

int NextHasFood(pSnakeNode pn, pSnakeNode pf)
{
    return ((pn->x == pf->x) && (pn->y == pf->y));
}

void EatFood(pSnakeNode pn,pSnake ps)
{
    pn->next = ps->_pSnake;
    ps->_pSnake = pn;
    SetPos(ps->_pSnake->x, ps->_pSnake->y);
    printf(Food);
    ps->ToTalScore += ps->_AddScore;
    CreateFood(ps);
}

void NoFood(pSnakeNode pn, pSnake ps)
{
    pSnakeNode Cur = NULL;
    pn->next = ps->_pSnake;
    ps->_pSnake = pn;
    SetPos(pn->x, pn->y);
    printf(Food);
    Cur = ps->_pSnake;
    while (Cur->next->next)
    {
        Cur = Cur->next;
    }
    SetPos(Cur->next->x, Cur->next->y);
    printf(" ");

    free(Cur->next);
    Cur->next = NULL;
}

void SnakeMove(pSnake ps)
{
    pSnakeNode pNextNode = BuyNode();
    switch (ps->_Dir)
    {
    case UP:
    {
        pNextNode->x = ps->_pSnake->x;
        pNextNode->y = ps->_pSnake->y - 1;
        if (NextHasFood(pNextNode, ps->_pFood))
        {
            //下一个节点是食物
            EatFood(pNextNode,ps);
        }
        else
        {
            //下一个节点不是食物
            NoFood( pNextNode, ps);
        }
    }
    break;
    case DOWN:
    {
        pNextNode->x = ps->_pSnake->x;
        pNextNode->y = ps->_pSnake->y + 1;
        if (NextHasFood(pNextNode, ps->_pFood))
        {
            //下一个节点是食物
            EatFood(pNextNode, ps);
        }
        else
        {
            //下一个节点不是食物
            NoFood(pNextNode, ps);
        }
    }break;
    case LEFT:
    {
        pNextNode->x = ps->_pSnake->x - 2;
        pNextNode->y = ps->_pSnake->y;
        if (NextHasFood(pNextNode, ps->_pFood))
        {
            //下一个节点是食物
            EatFood(pNextNode, ps);
        }
        else
        {
            //下一个节点不是食物
            NoFood(pNextNode, ps);
        }
    }break;
    case RIGHT:
    {
        pNextNode->x = ps->_pSnake->x + 2;
        pNextNode->y = ps->_pSnake->y;
        if (NextHasFood(pNextNode, ps->_pFood))
        {
            //下一个节点是食物
            EatFood(pNextNode, ps);
        }
        else
        {
            //下一个节点不是食物
            NoFood(pNextNode, ps);
        }
    }
    break;
    }
}

5.获取键盘上的方向键,控制蛇

Windows下的int GetAsyncKeyState(int vkey)函数,自上次调用以来,如果对应 的键被按下,则返回1,否则返回0。


void PrintfHelpInfo(pSnake ps)
{
    SetPos(70, 9);
    printf("总分:%d  ", ps->ToTalScore);
    SetPos(70, 10);
    printf("单次吃食物得分:%d  ", ps->_AddScore);
    SetPos(70, 15);
    printf("用↑,↓,←,→来控制蛇的移动");
    SetPos(70, 16);
    printf("F1为加速,F2为减速");
    SetPos(70, 17);
    printf("按空格暂停");
    SetPos(70, 18);
    printf("按Esc退出");

}

void KillBySelf(pSnake ps)
{
    pSnakeNode Cur = NULL;
    Cur = ps->_pSnake->next;
    while (Cur)
    {
        if (ps->_pSnake->x == Cur->x && ps->_pSnake->y == Cur->y)
        {
            ps->_Status = KILL_BY_SELF;
            break;
        }
        Cur = Cur->next;
    }

}

void KillByWall(pSnake ps)
{
    if (ps->_pSnake->x == 0 || ps->_pSnake->x == 58//蛇撞墙会死
        || ps->_pSnake->y == 0 || ps->_pSnake->y == 29)
    {
        ps->_Status = KILL_BY_WALL;

    }

}
void GameRun(pSnake ps)
{
    do
    {
        PrintfHelpInfo(ps);
        //确定方向
        if (GetAsyncKeyState(VK_UP) && ps->_Dir != DOWN)
            ps->_Dir = UP;
        else if (GetAsyncKeyState(VK_DOWN) && ps->_Dir != UP)
            ps->_Dir = DOWN;
        else if (GetAsyncKeyState(VK_LEFT) && ps->_Dir != RIGHT)
            ps->_Dir = LEFT;
        else if (GetAsyncKeyState(VK_RIGHT) && ps->_Dir != LEFT)
            ps->_Dir = RIGHT;
        else if (GetAsyncKeyState(VK_SPACE))//暂停
            pause();
        else if (GetAsyncKeyState(VK_ESCAPE))//退出
        {
            ps->_Status = NORMAL_END;
            break;
        }
        else if (GetAsyncKeyState(VK_F1)) //加速
        {
            if (ps->_SleepTime >= 100)
            {
                ps->_AddScore += 2;
                ps->_SleepTime -= 20;
            }
        }
        else if (GetAsyncKeyState(VK_F2))//减速
        {
            if (ps->_SleepTime <= 300)
            {
                if (ps->_AddScore > 2)
                {
                    ps->_AddScore -= 2;
                }

                ps->_SleepTime += 20;
            }
        }
        Sleep(ps->_SleepTime);
        SnakeMove(ps);
        //蛇移动
        KillBySelf(ps);
        KillByWall(ps);
    } while (ps->_Status == OK);
}

6.判断游戏结束

void GameEnd(pSnake ps)
{
    switch (ps->_Status)
    {
    case KILL_BY_SELF:
    {
        SetPos(24, 15);
        printf("撞身体");
        SetPos(22, 16);
        printf("GAME OVER!!!");
    }
    break;
    case KILL_BY_WALL://撞墙会死
    {
        SetPos(24, 15);
        printf("撞墙");
        SetPos(22, 16);
        printf("GAME OVER!!!");
    }
    break;
    }
    pSnakeNode Cur = ps->_pSnake;
    pSnakeNode Del = NULL;
    while (Cur)
    {
        Del = Cur;
        Cur = Cur->next;
        free(Del);
    }
    Del = NULL;
    free(ps->_pFood);
    ps->_pFood = NULL;
}

以上就是基本原理,下面是源代码

//snake.h

#pragma once
#include<Windows.h>
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

#define WALL "■"
#define Food "□"
#define SIGN "@"
#define INIT_X 30
#define INIT_Y 10

typedef struct SnakeNode
{
    int x;
    int y;
    struct SnakeNode* next;
}SnakeNode,*pSnakeNode;

enum Dirction { UP = 1, DOWN, LEFT, RIGHT};
enum GameStatus { OK, NORMAL_END, KILL_BY_WALL,  KILL_BY_SELF};

typedef struct Snake
{
    pSnakeNode _pSnake;//维护蛇身
    pSnakeNode _pFood;//食物的位置
    int ToTalScore;//总分数
    int _AddScore;//每次增加分数
    int _SleepTime;//休眠时间
    enum Dirction _Dir;//方向
    enum GameStatus _Status;//游戏状态
}Snake,*pSnake;


void  GameStart(pSnake snake);
void SetPos(int x, int y);
void WelcomeToGame();
void CreateMap();
void InitSnake(pSnake snake);
void CreateFood(pSnake snake);



void GameRun(pSnake ps);
void EatFood(pSnakeNode pn, pSnake ps);
void NoFood(pSnakeNode pn, pSnake ps);
void SnakeMove(pSnake ps);
void PrintfHelpInfo(pSnake ps);
void KillBySelf(pSnake ps);
void KillByWall(pSnake ps);


void GameEnd(pSnake ps);
//snake.c
#include"snake.h"

void SetPos(int x, int y)
{
    COORD pos = { 0 };
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取设备
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}

void Sign()
{
    SetPos(88, 27);
    printf(SIGN);
    printf("阿巴卡");
}

void WelcomeToGame()
{
    //窗口大小
    system("mode con cols=100 lines=30");
    SetPos(39, 14);
    printf("欢迎来到贪吃蛇游戏");
    Sign();
    SetPos(39, 25);
    system("pause");
    system("cls");//清屏
    SetPos(25, 14);
    printf("用↑,↓,←,→来控制蛇的移动,F1为加速,F2为减速");
    SetPos(35, 15);
    printf("提示:加速获得的分数更高");
    Sign();
    SetPos(39, 25);
    system("pause");
    system("cls");

}

void CreateMap()
{
    int i = 0;
    //上
    for (i = 0; i <= 58; i+=2)
    {
        SetPos(i, 0);
        printf(WALL);
    }
    //下
    for (i = 0; i <= 58; i += 2)
    {
        SetPos(i, 29);
        printf(WALL);
    }
    //左
    for (i = 1; i <= 28; i++)
    {
        SetPos(0, i);
        printf(WALL);
    }
    //右
    for (i = 1; i <= 28; i++)
    {
        SetPos(58, i);
        printf(WALL);
    }
}

pSnakeNode BuyNode()
{
    pSnakeNode NewNode = (pSnakeNode)malloc(sizeof(SnakeNode));
    if (NewNode == NULL)
    {
        perror("BuyNode::malloc( )");
        exit(EXIT_FAILURE);
    }
    NewNode->x = 0;
    NewNode->y = 0;
    NewNode->next = NULL;
    return NewNode;
}

void InitSnake(pSnake snake)
{
    int i = 0;
    pSnakeNode Cur = NULL;
    pSnakeNode first = BuyNode();
    first->x = INIT_X;
    first->y = INIT_Y;
    for (i = 0; i < 4; i++)
    {
        Cur = BuyNode();
        Cur->x = first->x - 2;
        Cur->y = first->y;
        Cur->next = first;
        first = Cur;
    }
    while (Cur)
    {
        SetPos(Cur->x, Cur->y);
        printf(Food);
        Cur = Cur->next;
    }
    snake->_pSnake = first;
    Sign();
}

void CreateFood(pSnake snake)
{

    pSnakeNode pFood = NULL;
    pFood = BuyNode();
    pSnakeNode Cur = snake->_pSnake;
    pFood->y = rand() % 28 + 1;
    do 
    {
        pFood->x = rand() % 55 + 2;
    } while (pFood->x % 2 != 0);
    while (Cur)
    {
        if (Cur->x == pFood->x && Cur->y == pFood->y)
        {
            CreateFood(snake);
            return;
        }
        Cur = Cur->next;
    }
    snake->_pFood = pFood;
    SetPos(pFood->x, pFood->y);
    printf(Food);
}



void  GameStart(pSnake snake)
{
    //打印界面
    WelcomeToGame();

    //创建地图
    CreateMap();

    //初始化蛇
    InitSnake(snake);

    //初始化食物
    CreateFood(snake);

    snake->ToTalScore = 0;
    snake->_AddScore = 10;
    snake->_Dir = LEFT;
    snake->_SleepTime = 200;
    snake->_Status = OK;

}

void pause()
{
    while (1)
    {
        Sleep(100);
        if (GetAsyncKeyState(VK_SPACE))
            break;
    }
}

int NextHasFood(pSnakeNode pn, pSnakeNode pf)
{
    return ((pn->x == pf->x) && (pn->y == pf->y));
}

void EatFood(pSnakeNode pn,pSnake ps)
{
    pn->next = ps->_pSnake;
    ps->_pSnake = pn;
    SetPos(ps->_pSnake->x, ps->_pSnake->y);
    printf(Food);
    ps->ToTalScore += ps->_AddScore;
    CreateFood(ps);
}

void NoFood(pSnakeNode pn, pSnake ps)
{
    pSnakeNode Cur = NULL;
    pn->next = ps->_pSnake;
    ps->_pSnake = pn;
    SetPos(pn->x, pn->y);
    printf(Food);
    Cur = ps->_pSnake;
    while (Cur->next->next)
    {
        Cur = Cur->next;
    }
    SetPos(Cur->next->x, Cur->next->y);
    printf(" ");

    free(Cur->next);
    Cur->next = NULL;
}

void SnakeMove(pSnake ps)
{
    pSnakeNode pNextNode = BuyNode();
    switch (ps->_Dir)
    {
    case UP:
    {
        pNextNode->x = ps->_pSnake->x;
        pNextNode->y = ps->_pSnake->y - 1;
        if (NextHasFood(pNextNode, ps->_pFood))
        {
            //下一个节点是食物
            EatFood(pNextNode,ps);
        }
        else
        {
            //下一个节点不是食物
            NoFood( pNextNode, ps);
        }
    }
    break;
    case DOWN:
    {
        pNextNode->x = ps->_pSnake->x;
        pNextNode->y = ps->_pSnake->y + 1;
        if (NextHasFood(pNextNode, ps->_pFood))
        {
            //下一个节点是食物
            EatFood(pNextNode, ps);
        }
        else
        {
            //下一个节点不是食物
            NoFood(pNextNode, ps);
        }
    }break;
    case LEFT:
    {
        pNextNode->x = ps->_pSnake->x - 2;
        pNextNode->y = ps->_pSnake->y;
        if (NextHasFood(pNextNode, ps->_pFood))
        {
            //下一个节点是食物
            EatFood(pNextNode, ps);
        }
        else
        {
            //下一个节点不是食物
            NoFood(pNextNode, ps);
        }
    }break;
    case RIGHT:
    {
        pNextNode->x = ps->_pSnake->x + 2;
        pNextNode->y = ps->_pSnake->y;
        if (NextHasFood(pNextNode, ps->_pFood))
        {
            //下一个节点是食物
            EatFood(pNextNode, ps);
        }
        else
        {
            //下一个节点不是食物
            NoFood(pNextNode, ps);
        }
    }
    break;
    }
}

void PrintfHelpInfo(pSnake ps)
{
    SetPos(70, 9);
    printf("总分:%d  ", ps->ToTalScore);
    SetPos(70, 10);
    printf("单次吃食物得分:%d  ", ps->_AddScore);
    SetPos(70, 15);
    printf("用↑,↓,←,→来控制蛇的移动");
    SetPos(70, 16);
    printf("F1为加速,F2为减速");
    SetPos(70, 17);
    printf("按空格暂停");
    SetPos(70, 18);
    printf("按Esc退出");

}

void KillBySelf(pSnake ps)
{
    pSnakeNode Cur = NULL;
    Cur = ps->_pSnake->next;
    while (Cur)
    {
        if (ps->_pSnake->x == Cur->x && ps->_pSnake->y == Cur->y)
        {
            ps->_Status = KILL_BY_SELF;
            break;
        }
        Cur = Cur->next;
    }

}

void KillByWall(pSnake ps)
{
    if (ps->_pSnake->x == 0 || ps->_pSnake->x == 58//蛇撞墙会死
        || ps->_pSnake->y == 0 || ps->_pSnake->y == 29)
    {
        ps->_Status = KILL_BY_WALL;

    }

}

void GameRun(pSnake ps)
{
    do
    {
        PrintfHelpInfo(ps);
        //确定方向
        if (GetAsyncKeyState(VK_UP) && ps->_Dir != DOWN)
            ps->_Dir = UP;
        else if (GetAsyncKeyState(VK_DOWN) && ps->_Dir != UP)
            ps->_Dir = DOWN;
        else if (GetAsyncKeyState(VK_LEFT) && ps->_Dir != RIGHT)
            ps->_Dir = LEFT;
        else if (GetAsyncKeyState(VK_RIGHT) && ps->_Dir != LEFT)
            ps->_Dir = RIGHT;
        else if (GetAsyncKeyState(VK_SPACE))//暂停
            pause();
        else if (GetAsyncKeyState(VK_ESCAPE))//退出
        {
            ps->_Status = NORMAL_END;
            break;
        }
        else if (GetAsyncKeyState(VK_F1)) //加速
        {
            if (ps->_SleepTime >= 100)
            {
                ps->_AddScore += 2;
                ps->_SleepTime -= 20;
            }
        }
        else if (GetAsyncKeyState(VK_F2))//减速
        {
            if (ps->_SleepTime <= 300)
            {
                if (ps->_AddScore > 2)
                {
                    ps->_AddScore -= 2;
                }

                ps->_SleepTime += 20;
            }
        }
        Sleep(ps->_SleepTime);
        SnakeMove(ps);
        //蛇移动
        KillBySelf(ps);
        KillByWall(ps);
    } while (ps->_Status == OK);
}


void GameEnd(pSnake ps)
{
    switch (ps->_Status)
    {
    case KILL_BY_SELF:
    {
        SetPos(24, 15);
        printf("撞身体");
        SetPos(22, 16);
        printf("GAME OVER!!!");
    }
    break;
    case KILL_BY_WALL://撞墙会死
    {
        SetPos(24, 15);
        printf("撞墙");
        SetPos(22, 16);
        printf("GAME OVER!!!");
    }
    break;
    }
    pSnakeNode Cur = ps->_pSnake;
    pSnakeNode Del = NULL;
    while (Cur)
    {
        Del = Cur;
        Cur = Cur->next;
        free(Del);
    }
    Del = NULL;
    free(ps->_pFood);
    ps->_pFood = NULL;
}
//test.c

#include"snake.h"

void test()
{
    Snake snake = { 0 };
    srand((unsigned)time(NULL));
    GameStart(&snake);
    GameRun(&snake);
    GameEnd(&snake);
}

int main()
{
    test();
    SetPos(20, 20);
    system("pause");
    return 0;
}

具体实现形式:
这里写图片描述

撞墙不会死

其实撞墙不会死的情况与撞墙会死的情况以下几个函数不一样

void GameEnd(pSnake ps);
void KillByWall(pSnake ps);
void NoFood(pSnakeNode pn, pSnake ps);
代码如下:

void NoFood(pSnakeNode pn, pSnake ps)
{
    pSnakeNode Cur = NULL;
    pn->next = ps->_pSnake;
    ps->_pSnake = pn;
    SetPos(pn->x, pn->y);
    printf(Food);
    Cur = ps->_pSnake;
    while (Cur->next->next)
    {
        Cur = Cur->next;
        SetPos(Cur->x, Cur->y);
        printf(Food);
    }
    if (Cur->next->x == 0 || Cur->next->x == 58
        || Cur->next->y == 0 || Cur->next->y == 29)
    {
        SetPos(Cur->next->x, Cur->next->y);
        printf(WALL);

    }
    else
    {
        SetPos(Cur->next->x, Cur->next->y);
        printf(" ");
    }
    free(Cur->next);
    Cur->next = NULL;
}

void KillByWall(pSnake ps)
{
    pSnakeNode pn = BuyNode();
    if (ps->_pSnake->x == 0)//撞左墙
    {

        pn->x = ps->_pSnake->x + 56;
        pn->y = ps->_pSnake->y;
        if (NextHasFood(pn, ps->_pFood))
        {
            EatFood(pn, ps);
        }
        else
        {
            NoFood(pn, ps);
        }
    }

    if (ps->_pSnake->x == 58)//撞右墙
    {

        pn->x = ps->_pSnake->x - 56;
        pn->y = ps->_pSnake->y;
        if (NextHasFood(pn, ps->_pFood))
        {
            EatFood(pn, ps);
        }
        else
        {
            NoFood(pn, ps);
        }
    }

    if (ps->_pSnake->y == 0)//撞上墙
    {

        pn->x = ps->_pSnake->x;
        pn->y = ps->_pSnake->y + 28;
        if (NextHasFood(pn, ps->_pFood))
        {
            EatFood(pn, ps);
        }
        else
        {
            NoFood(pn, ps);
        }
    }

    if (ps->_pSnake->y == 29)//撞下墙
    {

        pn->x = ps->_pSnake->x;
        pn->y = ps->_pSnake->y - 28;
        if (NextHasFood(pn, ps->_pFood))
        {
            EatFood(pn, ps);
        }
        else
        {
            NoFood(pn, ps);
        }
    }

}

void GameEnd(pSnake ps)
{
    switch (ps->_Status)
    {
    case KILL_BY_SELF:
    {
        SetPos(24, 15);
        printf("撞身体");
        SetPos(22, 16);
        printf("GAME OVER!!!");
    }
    break;
    }
    pSnakeNode Cur = ps->_pSnake;
    pSnakeNode Del = NULL;
    while (Cur)
    {
        Del = Cur;
        Cur = Cur->next;
        free(Del);
    }
    Del = NULL;
    free(ps->_pFood);
    ps->_pFood = NULL;
}

要想实现不会撞墙死的贪吃蛇,只需要将这几个函数与撞墙会死中相对应的函数进行替换就可以
具体实现结果:

这里写图片描述

这里写图片描述

如果有疑问或者有什么更好的建议欢迎留言。

猜你喜欢

转载自blog.csdn.net/qq_39032310/article/details/82054447