(C语言贪吃蛇)15.贪吃蛇吃食物

目录

前言

注意事项⚠️

效果预览

 实现方法

运行效果

新的问题🙋

最终效果 

总结


前言

        我们上一节实现了解决了贪吃蛇不合理走位的情况,不理解的再回去看看(传送门:解决贪吃蛇不合理走位),那么贪吃蛇自然是要吃食物的啊,所以我们本节来实现贪吃蛇吃食物的效果

注意事项⚠️

        贪吃蛇食物关心的是位置及符号,位置同样可以使用贪吃蛇节点结构体,食物显示为“##”。

效果预览

        

我们用“##”来表示食物,贪吃蛇的头节点碰到食物就吃掉食物。

 实现方法

        我们创建一个结构体struct Snake food(我们先来测试一下食物能不能成功生成,所以我们赋予了食物坐标的初始值)。

struct Snake food;
void initfood()
{
    int x = 4;
    int y = 5;

    food.lie = x;
    food.lie = y;
}

我们创造出了食物节点,那么要显示这个节点呢,我们需要修改gamePic()函数,增加判断,该节点位置是否为食物节点,是的话就打印“##”:

int hasSnakeNode(int i,int j)
{
    struct Snake * p;
    p = head;
    while(p != NULL)
    {
        if(p->hang == i && p->lie == j)
        {
            return 1;
        }
        p = p -> next;
    }
    return 0;    
}

void gamePic()
{
    int hang;
    int lie;

    move(0,0);

    for(hang = 0;hang < 20;hang ++)
    {

        if(hang == 0)
        {
            for(lie = 0;lie < 20;lie ++)
               {
                   printw("--");
               }
            printw("\n");
        }
        if(hang >= 0 && hang <= 19)
        {
            for(lie = 0;lie <= 20;lie ++)
            {
                if(lie == 0 || lie == 20) printw("|");
                else if(hasSnakeNode(hang,lie)) printw("[]");
                else if(hasfood(hang,lie)) printw("##");
                else printw("  ");
            }
            printw("\n");
        }
        if(hang == 19)
        {
            for(lie = 0;lie < 20;lie ++)
               {
                   printw("--");
               }
               printw("\n");
               printw("by beiweiqiuAC,%d\n",key);
        }
    }

}

我们在上面的函数中新增了一个判断函数hasfood(),是用来判断这个节点是否时食物节点,这个函数其实非常熟悉,因为我们判断蛇身节点的函数跟这个函数可以说是大同小异吧

先来看一下判断蛇身节点的函数:

int hasSnakeNode(int i,int j)
{
    struct Snake * p;
    p = head;
    while(p != NULL)
    {
        if(p->hang == i && p->lie == j)
        {
            return 1;
        }
        p = p -> next;
    }
    return 0;    
}

我们稍微修改下就变成了hasfood()函数,非常简单哈:

int hasfood(int i,int j)
{

    if(food.hang == i && food.lie == j) return 1;
    return 0;    
}

运行效果

        运行测试一下这个程序:

可以看到食物已经出现在屏幕上了。

新的问题🙋

        既然是食物,那贪吃蛇应该如何吃掉呢?

在这个贪吃蛇里面,贪吃蛇的蛇头实际上是链表的尾节点,那么尾节点的坐标和食物的坐标一样,然后消除就代表吃食物了。

最终效果 

#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define UP    1
#define DOWN  -1
#define LEFT  2
#define RIGHT -2

struct Snake
{
    int hang;
    int lie;
    struct Snake * next;
};

struct Snake * head = NULL;
struct Snake * tail = NULL;
int key;
int dir;

struct Snake food;

void initfood()
{
    static int x = 11;
    static int y = 6;

    food.hang = x;
    food.lie = y;

    x += 2;
    y += 2;
}

void initNcurse()
{
    initscr();
    keypad(stdscr,1);
    noecho();
}

int hasSnakeNode(int i,int j)
{
    struct Snake * p;
    p = head;
    while(p != NULL)
    {
        if(p->hang == i && p->lie == j)
        {
            return 1;
        }
        p = p -> next;
    }
    return 0;    
}

int hasfood(int i,int j)
{

    if(food.hang == i && food.lie == j) return 1;
    return 0;    
}

void gamePic()
{
    int hang;
    int lie;

    move(0,0);

    for(hang = 0;hang < 20;hang ++)
    {

        if(hang == 0)
        {
            for(lie = 0;lie < 20;lie ++)
               {
                   printw("--");
               }
            printw("\n");
        }
        if(hang >= 0 && hang <= 19)
        {
            for(lie = 0;lie <= 20;lie ++)
            {
                if(lie == 0 || lie == 20) printw("|");
                else if(hasSnakeNode(hang,lie)) printw("[]");
                else if(hasfood(hang,lie)) printw("##");
                else printw("  ");
            }
            printw("\n");
        }
        if(hang == 19)
        {
            for(lie = 0;lie < 20;lie ++)
               {
                   printw("--");
               }
               printw("\n");
               printw("by beiweiqiuAC,%d\n",key);
        }
    }

}

void addNode()
{
    struct Snake * new = (struct Snake *)malloc(sizeof(struct Snake));
    
    new->next = NULL;

    switch(dir)
    {
        case UP:
            new->hang = tail->hang - 1;
            new->lie = tail->lie;
            break;
        case DOWN:
            new->hang = tail->hang + 1;
            new->lie = tail->lie;
            break;
        case LEFT:
            new->hang = tail->hang;
            new->lie = tail->lie - 1;
            break;
        case RIGHT:
            new->hang = tail->hang;
            new->lie = tail->lie + 1;
            break;
    }
    tail->next = new;
    tail = new;
}

void initSnake(){
    struct Snake * p;
    dir = RIGHT;
    while(head != NULL)
    {
        p = head;
        head = head -> next;
        free(p);
    }

    initfood();

    head = (struct Snake *)malloc(sizeof(struct Snake));
    head->hang = 1;
    head->lie = 1;
    head->next = NULL;

    tail = head;
    addNode();
    addNode();
    addNode();
    addNode();
}

void deleNode()
{
 // struct Snake * p;
 // p = head;
    head = head ->next;
 // free(p);
}

void moveSnake()
{
    addNode();
    if(hasfood(tail->hang,tail->lie))
    {
        initfood();
    }else{
        deleNode();
    }
    

    if(tail ->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20)
    {
        initSnake();
    }
}

void* refreshJieMian()
{
    while(1)
        {
            moveSnake();
            gamePic();
            refresh();
            usleep(100000);
        }
}

void turn(int direction)
{
    
    if(abs(dir) != abs(direction))
    {
        dir = direction;
    }
}

void* changeDir()
{
    while (1)
        {
            key = getch();
            switch (key)
            {
            case 0402:
                    turn(DOWN);
                    break;
            case 0403:
                    turn(UP);
                    break;
            case 0404:
                    turn(LEFT);
                    break;
            case 0405:
                    turn(RIGHT);
                    break;
            }
        }
}


int main()
{
    pthread_t t1;
    pthread_t t2;
    
    initNcurse();

    initSnake();

    gamePic();
    pthread_create( &t1, NULL,refreshJieMian, NULL);
    pthread_create( &t2, NULL, changeDir, NULL);
    
    while(1);
    getch();//防止程序退出
    endwin();
    return 0;
}

 

        但其实这个程序还是有点小bug,食物到后面就跑到地图外面了,我们下一节实现食物随机出现的效果。

总结

        我们本节实现了贪吃蛇吃食物的效果,吃一个食物身体就伸长一个节点,但还是有点小bug,我们下一节来解决📨。

### 回答1: 在C语言编写的贪吃蛇游戏中,当贪吃蛇到一定分数的食物时,游戏会出现如下的加速效果。 贪吃蛇是一种经典的游戏,玩家需要控制蛇的移动方向,使其食物并不断变长。一开始,贪吃蛇的移动速度较慢,但随着贪吃蛇到越来越多的食物,分数也会逐渐增加。当分数达到一定阈值时,游戏会出现加速效果,使得贪吃蛇的移动速度变快。 实现这个功能,首先需要获得游戏中的贪吃蛇得分。在C语言中,可以使用一个整数变量来代表分数。每当贪吃蛇食物时,分数加一,并将新的分数显示在游戏界面上。 接下来,需要设置一个阈值来判断何时触发加速效果。当分数达到设定的阈值时,加速效果就会被触发。可以使用一个if语句来比较当前分数和阈值的大小,如果大于等于阈值,则加速。 在C语言中,加速效果可以通过两种方式实现。一种是改变贪吃蛇的移动速度,可以通过调整移动的时间间隔来实现加速。另一种是改变贪吃蛇的移动步长,可以通过增加每次移动的格子数来实现加速。 在游戏的循环中,需要不断检测当前分数是否达到了阈值,如果达到了,则将移动速度或步长进行调整,以实现加速效果。可以使用条件语句或循环控制语句来实现这个逻辑。 总之,通过适当设置阈值,并在达到一定分数时实现贪吃蛇的加速效果,可以增加游戏的难度和挑战性,让游戏更加有趣。 ### 回答2: 在C语言编写贪吃蛇游戏时,可以通过设置一定的分数目标来触发食物加速的功能。当贪吃蛇到的食物数量达到一定的分数时,游戏可以加速。 在游戏开始时,可以设定一个初始的游戏速度。当贪吃蛇食物时,可以通过判断当前得分是否达到设定的分数目标来确定是否进行加速操作。当得分达到目标时,可以通过减小时间延迟来加快游戏的速度。这样,在每次移动时,贪吃蛇的移动就会更加迅速。 在程序编码上,可以使用一个变量来记录当前的得分,并与设定的分数目标进行比较。当得分超过或等于设定的目标分数时,通过相应的代码来修改时间延迟的数值,从而实现加速的效果。 比如,可以使用一个if语句判断当前得分和目标分数的关系,当达到目标分数时,修改一个控制时间延迟的变量的数值,从而实现加速,具体代码如下: ``` int score = 0; // 记录得分 int targetScore = 100; // 分数目标 int delay = 100; // 初始时间延迟 // 游戏循环 while (1) { // 贪吃蛇移动逻辑 // ... // 判断是否达到分数目标 if (score >= targetScore) { // 达到目标分数,加速 delay -= 10; targetScore += 100; // 更新目标分数,为下一次加速做准备 } // 控制移动的速度 sleep(delay); } ``` 在以上代码中,通过不断地比较得分和目标分数的大小关系,可以在达到目标分数时不断地减小时间延迟的值,从而实现游戏的加速效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值