xml地图|网站地图|网站标签 [设为首页] [加入收藏]

[C入门,c入门

来源:http://www.ccidsi.com 作者:最新解决方案 人气:90 发布时间:2019-11-13
摘要:[C入门,c入门 那风流洒脱篇是有关设置蛇的本性的,接上生机勃勃篇(五)。   设置蛇的速度,很简短,只要不是负数就行了。 void SNK_SetSnakeSpeed(Snake *snake, int speed){ if (snake != 0) snake-sp

[C入门,c入门

  那风流洒脱篇是有关设置蛇的本性的,接上生机勃勃篇(五)。

 

设置蛇的速度,很简短,只要不是负数就行了。

void SNK_SetSnakeSpeed(Snake *snake, int speed)
{
    if (snake != 0) snake->speed = SDL_abs(speed);
}

 

安装蛇的倾向有个别复杂,玩过贪吃蛇的都通晓,蛇向前挪动时,它不可能向后转弯;向左移动时,它不或然向右转弯。所以,笔者也要做些那样的决断。

void SNK_SetSnakeDirection(Snake *snake, int direction)
{
    if (snake != 0 && (direction & (SNAKE_UP | SNAKE_DOWN | SNAKE_LEFT | SNAKE_RIGHT)))
    {
        if (snake->direction & (SNAKE_UP | SNAKE_DOWN))
        {
            if (direction & (SNAKE_LEFT | SNAKE_RIGHT))
                snake->direction = direction;
        }
        else
        {
            if (direction & (SNAKE_UP | SNAKE_DOWN))
                snake->direction = direction;
        }
    }
}

如此那般就能够有限帮衬方向是没错,何况具有精确的转弯行为。

 

最后设置蛇的水彩,那个就没怎么好说的了。

void SNK_SetSnakeColor(Snake *snake, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
    if (snake != 0)
    {
        snake->color.r = r;
        snake->color.g = g;
        snake->color.b = b;
        snake->color.a = a;
    }
}

 

到此,蛇的得以完结代码就写完了。整个娱乐最大旨的一些也就那么些了,接下去正是弄个绝色的分界面了。

 

以下是snk-snake.c文件的后生可畏体化源码:

#include "snk-snake.h"

#define INIT_SNAKE(world, size, x, y)                                       
    snake->world = (world);                                                 
    snake->x = (SDL_abs(x) > (world)->w) ? 0 : SDL_abs(x);                  
    snake->x = (size) ? ((snake->x / SDL_abs(size)) * SDL_abs(size)) : 0;   
    snake->y = (SDL_abs(y) > (world)->h) ? 0 : SDL_abs(y);                  
    snake->y = (size) ? ((snake->y / SDL_abs(size)) * SDL_abs(size)) : 0;   
    snake->size = (size) ? SDL_abs(size) : 0;                               
    snake->color.r = snake->color.g = snake->color.b = snake->color.a = 0;  
    snake->speed = 0;                                                       
    snake->length = 1;                                                      
    snake->direction = SNAKE_UP;                                            
    snake->body = 0;

#define MOVE_SNAKE(body) do {                                               
    switch ((body)->direction)                                              
    {                                                                       
        case SNAKE_UP:   (body)->y -= snake->size; break;                   
        case SNAKE_DOWN: (body)->y  = snake->size; break;                   
        case SNAKE_LEFT: (body)->x -= snake->size; break;                   
        case SNAKE_RIGHT:(body)->x  = snake->size; break;                   
    }                                                                       
} while (0)

#define APPEND_BODY(last, body) do {                                        
    if ((last)->direction & (SNAKE_UP | SNAKE_DOWN)) {                      
        (body)->x = (last)->x;                                              
        if ((last)->direction & SNAKE_UP)                                   
            (body)->y = (last)->y   snake->size;                            
        else                                                                
            (body)->y = (last)->y - snake->size;                            
    } else {                                                                
        if ((last)->direction & SNAKE_LEFT)                                 
            (body)->x = (last)->x   snake->size;                            
        else                                                                
            (body)->x = (last)->x - snake->size;                            
        (body)->y = (last)->y;                                              
    }                                                                       
    (body)->direction = (last)->direction;                                  
    (body)->next = (snake->body != 0) ? snake->body : 0;                    
    snake->body = (body);                                                   
      snake->length;                                                        
} while (0)

#define REMOVE_BODY(body) do {                                              
    snake->body = (body)->next;                                             
    SDL_free(body);                                                         
    (body) = snake->body;                                                   
} while (body)

Snake * SNK_CreateSnake(World *world, int size, int x, int y)
{
    Snake *snake;

    if (world == 0) return 0;

    if ((snake = (Snake *)SDL_malloc(sizeof(Snake))) == 0) return 0;

    INIT_SNAKE(world, size, x, y);
    SNK_GrowSnake(snake);

    return snake;
}

void SNK_DestroySnake(Snake *snake)
{
    struct Body *body;

    if (snake != 0)
    {
        if ((body = snake->body)) REMOVE_BODY(body);

        SDL_free(snake);
        snake = 0;
    }
}

void SNK_MoveSnake(Snake *snake)
{
    struct Body *body;

    if (snake != 0)
    {
        MOVE_SNAKE(snake);

        for (body = snake->body; body; body = body->next)
        {
            MOVE_SNAKE(body);
            body->direction = (body->next != 0) ? body->next->direction : snake->direction;
        }
    }
}

void SNK_DrawSnake(Snake *snake)
{
    SDL_Rect rect;
    struct Body *body;

    if (snake != 0)
    {
        rect.x = snake->x;
        rect.y = snake->y;
        rect.w = rect.h = snake->size;

        if (((snake->world != 0) ? (snake->world->render != 0) : 0))
        {
            SDL_SetRenderDrawColor(snake->world->render,
                                   snake->color.r, snake->color.g,
                                   snake->color.b, snake->color.a);
            SDL_RenderDrawRect(snake->world->render, &rect);

            for (body = snake->body; body; body = body->next)
            {
                rect.x = body->x;
                rect.y = body->y;
                SDL_RenderDrawRect(snake->world->render, &rect);
            }
        }
    }
}

void SNK_GrowSnake(Snake *snake)
{
    struct Body *body;

    if (snake != 0)
    {
        if ((body = (struct Body *)SDL_malloc(sizeof(struct Body))) == 0) return;

        if (snake->body == 0)
        {
            APPEND_BODY(snake, body);
        }
        else
        {
            APPEND_BODY(snake->body, body);
        }
    }
}


int SNK_HasIntersection(Snake *snake, SDL_Rect rect)
{
    SDL_Rect bodyrect;
    struct Body *body;

    if (snake != 0)
    {
        bodyrect.w = bodyrect.h = snake->size;

        for (body = snake->body; body; body = body->next)
        {
            bodyrect.x = body->x;
            bodyrect.y = body->y;

            if (SDL_HasIntersection(&bodyrect, &rect) != 0)
                return 1;
        }
    }

    return 0;
}

int SNK_GetSnakeStatus(Snake *snake)
{
    SDL_Rect headrect;

    if (((snake != 0) ? (snake->world != 0) : 0))
    {
        headrect.w = (snake->x > 0 && snake->x < snake->world->w);
        headrect.h = (snake->y > 0 && snake->y < snake->world->h);

        if (headrect.w && headrect.h)
        {
            headrect.x = snake->x;
            headrect.y = snake->y;
            headrect.w = headrect.h = snake->size;

            if (SNK_HasIntersection(snake, headrect) != 0)
                return SNAKE_DIED;

            return SNAKE_MOVABLE;
        }
        else
        {
            switch (snake->direction)
            {
            case SNAKE_UP:
                headrect.x = (snake->y > 0);
                break;
            case SNAKE_DOWN:
                headrect.x = ((snake->y   snake->size) < snake->world->h);
                break;
            case SNAKE_LEFT:
                headrect.x = (snake->x > 0);
                break;
            case SNAKE_RIGHT:
                headrect.x = ((snake->x   snake->size) < snake->world->w);
                break;
            }

            return ((headrect.x != 0) ? SNAKE_MOVABLE : 0);
        }
    }

    return 0;
}

void SNK_SetSnakeSpeed(Snake *snake, int speed)
{
    if (snake != 0) snake->speed = SDL_abs(speed);
}

void SNK_SetSnakeDirection(Snake *snake, int direction)
{
    if (snake != 0 && (direction & (SNAKE_UP | SNAKE_DOWN | SNAKE_LEFT | SNAKE_RIGHT)))
    {
        if (snake->direction & (SNAKE_UP | SNAKE_DOWN))
        {
            if (direction & (SNAKE_LEFT | SNAKE_RIGHT))
                snake->direction = direction;
        }
        else
        {
            if (direction & (SNAKE_UP | SNAKE_DOWN))
                snake->direction = direction;
        }
    }
}

void SNK_SetSnakeColor(Snake *snake, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
    if (snake != 0)
    {
        snake->color.r = r;
        snake->color.g = g;
        snake->color.b = b;
        snake->color.a = a;
    }
}

宏INIT_SNAKE中snake->x和snake->y重复了一遍,首即使为了将蛇的职位和蛇的分寸对齐。

APPEND_BODY用于充实链表节点,并安装snake->body永世指向蛇尾,提升追加节点的作用。

那生机勃勃篇是有关设置蛇的性质的,接上意气风发篇(五)。 设置蛇的进程,极粗略,只要不是负数就行了。 void SNK_SetSnakeSpeed(Snake *snak...

[C入门,c入门

  因为早就写了食物的落到实处,所以本身不知道终归是该先写世界的兑现依旧蛇的兑现。因为世界正是贰个窗口,能够立时在世界中看见食品的旗帜,对于绝大许多人的话,借使写完代码立时就能够来看功能,那就再好可是了。然则,笔者最终依旧接纳了先写蛇的落实那篇笔记。假诺先写世界的达成,小编就不能依照现行反革命的思绪完完整整的写下去,因为尚未蛇,世界部分的代码就破损,看完食物的功用后,小编大概得写蛇的完结,然后又得修改世界部分的代码,来查看蛇的功效。顾虑太多,实在折腾不起。所以本身准备把食品和蛇的落到实处都写完,最终统风流罗曼蒂克看运转作效果果。

 

蛇和食品同样,得在世界中开创,所以代码基本大概。

Snake * SNK_CreateSnake(World *world, int size, int x, int y)
{
    Snake *snake;

    if (world == 0) return 0;

    if ((snake = (Snake *)SDL_malloc(sizeof(Snake))) == 0) return 0;

    INIT_SNAKE(world, size, x, y);
    SNK_GrowSnake(snake);

    return snake;
}

宏INIT_SNAKE用于开首化Snake结构体。

SNK_GrowSnake函数用于将蛇的尺寸加后生可畏,因为蛇创立出来后独有蛇头,小编一定要另行给它加个蛇尾。尽管唯有蛇头,当然也能运转,那只是仿照,不是确实的生命体。不过那是异形蛇,不好看。小编要么让它平常一点,相符常规思维。

 

蛇的躯干生机勃勃节豆蔻梢头节的,所以能够见见自家在头文件中用了叁个单向链表表示蛇的人身。所以销毁辰时,小编要遍历整个链表才行,然后依次释放种种肉体节点。

void SNK_DestroySnake(Snake *snake)
{
    struct Body *body;

    if (snake != 0)
    {
        if ((body = snake->body)) REMOVE_BODY(body);

        SDL_free(snake);
        snake = 0;
    }
}

宏REMOVE_BODY便是用来遍历链表并释放人体节点的,小编把它定义为一个宏,那展现略微频仍一举。这么做要紧是因为本身不能不定义二个APPEND_BODY宏来扩张蛇的骨肉之躯节点,所以为了和扩大节点相呼应,笔者定义了移除节点那个宏。

 

移步蛇的地点分为两部,移动蛇头和移动蛇的身子。主假诺出于定义的时候作者从没把蛇头当做肉体的一片段,因为身体能够加强,而蛇头不能够增高,所以只可以这么了。

void SNK_MoveSnake(Snake *snake)
{
    struct Body *body;

    if (snake != 0)
    {
        MOVE_SNAKE(snake);

        for (body = snake->body; body; body = body->next)
        {
            MOVE_SNAKE(body);
            body->direction = (body->next != 0) ? body->next->direction : snake->direction;
        }
    }
}

snake代表蛇头,MOVE_SNAKE(snake)表示移动蛇头的职责,MOVE_SNAKE(body)表示移动肉体的岗位。

一抬手一动脚肉体须求遍历链表,但是这里设置身体方向不晓得是还是不是有人看懂? 当前肉体节点的趋向等于下八个肉体节点的趋势,反复推敲,那是怎么着意思?

作者对蛇的剖判是,蛇只会在后面部分增添节点,假诺snake->body指向第二个节点first, first指向第四个节点second, 那么自个儿扩展第两个节点将在从snake->body开首遍历一遍,追加第多个节点将要从snake->body伊始遍历一次。所以本身更换了那些从未效能的行为,笔者让snake->body始终对准最后一个肉体节点,由此当追加新的躯干节点时,直接增添就可以,而不用遍历链表。

进而那么些for循环其实是从蛇尾向蛇头方向遍历的,当蛇头方向更换时,身体随之蛇头变化,蛇尾跟着身体变化。那是蛇能随随意便拐弯的关键所在。

 

接下去就是画出蛇的旗帜了,和画食品相通,笔者用三番两次串的矩形表示蛇。

void SNK_DrawSnake(Snake *snake)
{
    SDL_Rect rect;
    struct Body *body;

    if (snake != 0)
    {
        rect.x = snake->x;
        rect.y = snake->y;
        rect.w = rect.h = snake->size;

        if (((snake->world != 0) ? (snake->world->render != 0) : 0))
        {
            SDL_SetRenderDrawColor(snake->world->render,
                                   snake->color.r, snake->color.g,
                                   snake->color.b, snake->color.a);
            SDL_RenderDrawRect(snake->world->render, &rect);

            for (body = snake->body; body; body = body->next)
            {
                rect.x = body->x;
                rect.y = body->y;
                SDL_RenderDrawRect(snake->world->render, &rect);
            }
        }
    }
}

 

对此蛇的滋长,有两个乐趣:未有尾巴时,增加的是尾巴。有尾巴时,增进的是身体。

void SNK_GrowSnake(Snake *snake)
{
    struct Body *body;

    if (snake != 0)
    {
        if ((body = (struct Body *)SDL_malloc(sizeof(struct Body))) == 0) return;

        if (snake->body == 0)
        {
            APPEND_BODY(snake, body);
        }
        else
        {
            APPEND_BODY(snake->body, body);
        }
    }
}

 

接下去是反省碰撞的函数,它根本有五个用处:1. 当参数rect是蛇头地点时,用来检查实验蛇头是不是咬到协调的骨血之躯。2. 当参数rect是食品地点时,用来检查评定身体是否蒙受食物。咬到和谐可能碰着食品,再次回到1, 不然重返0。

int SNK_HasIntersection(Snake *snake, SDL_Rect rect)
{
    SDL_Rect bodyrect;
    struct Body *body;

    if (snake != 0)
    {
        bodyrect.w = bodyrect.h = snake->size;

        for (body = snake->body; body; body = body->next)
        {
            bodyrect.x = body->x;
            bodyrect.y = body->y;

            if (SDL_HasIntersection(&bodyrect, &rect) != 0)
                return 1;
        }
    }

    return 0;
}

 

在头文件中,小编定义了蛇的五个状态:已死还能活动。那么些函数就是用于检验蛇的气象的。再次来到SNAKE_DIED表示蛇死了;重回SNAKE_MOVABLE表示蛇处孙铎常意况,能够随便活动;再次来到0表示蛇遭遇世界的边际,不可以移动。笔者从未兑现蛇能够从一只回到其他方面这种功效,也尚无规定蛇遇到墙就死了。一切尽恐怕维持轻松!

int SNK_GetSnakeStatus(Snake *snake)
{
    SDL_Rect headrect;

    if (((snake != 0) ? (snake->world != 0) : 0))
    {
        headrect.w = (snake->x > 0 && snake->x < snake->world->w);
        headrect.h = (snake->y > 0 && snake->y < snake->world->h);

        if (headrect.w && headrect.h)
        {
            headrect.x = snake->x;
            headrect.y = snake->y;
            headrect.w = headrect.h = snake->size;

            if (SNK_HasIntersection(snake, headrect) != 0)
                return SNAKE_DIED;

            return SNAKE_MOVABLE;
        }
        else
        {
            switch (snake->direction)
            {
            case SNAKE_UP:
                headrect.x = (snake->y > 0);
                break;
            case SNAKE_DOWN:
                headrect.x = ((snake->y   snake->size) < snake->world->h);
                break;
            case SNAKE_LEFT:
                headrect.x = (snake->x > 0);
                break;
            case SNAKE_RIGHT:
                headrect.x = ((snake->x   snake->size) < snake->world->w);
                break;
            }

            return ((headrect.x != 0) ? SNAKE_MOVABLE : 0);
        }
    }

    return 0;
}

此处switch语句唯有当蛇境遇世界的分界时才会跻身,那意气风发段重视是为着兑现二个作用:当蛇遭逢世界的疆界时,蛇不能再向前挪动,不过蛇能够重复转弯。

 

未完,待续!

因为已经写了食物的落实,所以小编不亮堂毕竟是该先写世界的实现如故蛇的兑现。因为世界就是一个窗口,能够即时在世界中...

本文由68399皇家赌场发布于最新解决方案,转载请注明出处:[C入门,c入门

关键词: 68399皇家赌场

上一篇:bzoj3037--贪心,bzoj3037

下一篇:没有了

频道精选

最火资讯