[C入门 - 游戏编程系列] 贪吃蛇篇(三) - 蛇定义

  蛇是这个游戏的主角,要实现的功能也是最复杂的一个。因为蛇不止有属性,还有行为。它会动,还会吃东西,还会长大!而且还会死!这是很要命的。我一向看不懂复杂的代码,也写不出复杂的代码。所以对于蛇,我很纠结,如何才能简单的实现它。

 

  毫无质疑的一点是,食物具有的属性,蛇也具有。蛇必须存在于世界中,有大小和位置以及颜色。这样最起码可以推测出一个蛇的简单定义。但是这还远远不够,蛇是活的,它能动,就必须有速度和方向,它能吃,就必须能长大。所以,抛开其它的一切,它最简单的形式起码也得这样:

typedef struct Snake

{

    World *world;

    int x, y, size;

    SDL_Color color;

    int speed, length, direction;



    struct Body

    {

        int x, y;

        int direction;

        struct Body *next;

    } *body;

} Snake;

而我要的就是简单,于是乎,一咬牙一跺脚,就它了!

 

  既然选择了创造这样的一条蛇,那我也只能接受创造它了。

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

extern void SNK_DestroySnake(Snake *snake);

 

  这样的蛇,要操控它的属性,就必须实现多个函数。而由于属性之间的相互联系,就得实现更多的函数。例如,改变蛇的方向,会有两种结果:1. 能动,2. 会死!吃掉食物,也有两种结果:1. 能长大,2. 被撑死。所以,我把这些函数一一细分,分为属性函数、行为函数以及附加函数。

 

属性相关函数:

extern void SNK_SetSnakeSpeed(Snake *snake, int speed);

extern void SNK_SetSnakeDirection(Snake *snake, int direction);

extern void SNK_SetSnakeColor(Snake *snake, Uint8 r, Uint8 g, Uint8 b, Uint8 a);

行为相关函数:

extern void SNK_MoveSnake(Snake *snake);

extern void SNK_GrowSnake(Snake *snake);

附加函数:

extern int SNK_HasIntersection(Snake *snake, SDL_Rect rect);

extern int SNK_GetSnakeStatus(Snake *snake);

 

  当这样一条蛇被完完整整的创造出来,我就可以毫无顾虑的让它暴露在世界之中。

extern void SNK_DrawSnake(Snake *snake);

 

  这是我目前所能想到的最简单的方式去实现一条蛇了。对,只是蛇!你会发现,从头到位,贪吃蛇游戏都是蛇在吃食物,但是我并没有在蛇的定义中,包含任何和食物相关的函数或变量, 我只是站在一个造物主的角度去创建生命罢了。蛇吃什么不是我要关心的,我创造了它,并制作了规则,让它去适应世界。

 

以下是snk-snake.h文件中的完整蛇定义:

#ifndef SNK_SNAKE_H_HEADER

#define SNK_SNAKE_H_HEADER



#define SNAKE_UP            (1 << 0)

#define SNAKE_LEFT          (1 << 1)

#define SNAKE_DOWN          (1 << 2)

#define SNAKE_RIGHT         (1 << 3)



#define SNAKE_DIED          (1 << 4)

#define SNAKE_MOVABLE       (1 << 5)



#define SNAKE_INIT_COLOR    0,    0xff, 0, 0xff

#define SNAKE_DIED_COLOR    0xff, 0,    0, 0xff

#define SNAKE_CTMV_COLOR    0xff, 0xff, 0, 0xff



#define SNAKE_INIT_SPEED    900



#include "snk-world.h"



typedef struct Snake

{

    World *world;

    int x, y, size;

    SDL_Color color;

    int speed, length, direction;



    struct Body

    {

        int x, y;

        int direction;

        struct Body *next;

    } *body;

} Snake;



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

extern void SNK_DestroySnake(Snake *snake);



extern int SNK_HasIntersection(Snake *snake, SDL_Rect rect);



extern void SNK_MoveSnake(Snake *snake);

extern void SNK_DrawSnake(Snake *snake);

extern void SNK_GrowSnake(Snake *snake);



extern int SNK_GetSnakeStatus(Snake *snake);



extern void SNK_SetSnakeSpeed(Snake *snake, int speed);

extern void SNK_SetSnakeDirection(Snake *snake, int direction);

extern void SNK_SetSnakeColor(Snake *snake, Uint8 r, Uint8 g, Uint8 b, Uint8 a);



#endif

最开始的几行宏定义是蛇的方向,然后是蛇的状态:已死或者可以移动。最下面几行宏只是为了提供方便,仅在设置属性时使用。SNAKE_INIT_SPEED设置为900毫秒,表示蛇的速度,它是时间值,而不是移动的距离。

你可能感兴趣的:(贪吃蛇)