[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毫秒,表示蛇的速度,它是时间值,而不是移动的距离。
[C入门 - 游戏编程系列] 贪吃蛇篇(三) - 蛇定义的更多相关文章
- [C入门 - 游戏编程系列] 贪吃蛇篇(一) - 世界定义
每个游戏都有一个很明确的目的或者说游戏主题,贪吃蛇的目的很明确:蛇找到并吃掉食物.只有目的是很无聊的,算不上一个好游戏.所以设计者增加了创意:1. 吃掉食物后蛇会增长:2. 吃掉食物后分数会增加.有些 ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(六) - 蛇实现
这一篇是关于设置蛇的属性的,接上一篇(五). 设置蛇的速度,很简单,只要不是负数就行了. void SNK_SetSnakeSpeed(Snake *snake, int speed) { ) sna ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(四) - 食物实现
由于食物是贪吃蛇游戏中最简单的一部分,而且和其他部分关联性不强,基本上是一个独立的部分,所以我打算先实现它. 我的想法是食物必须在世界中才能被创造出来,也就是说,先有世界再有食物,所以我得先判断世界是 ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(二) - 食物定义
游戏中的食物没有那么多复杂属性,特别是贪吃蛇游戏中,我把食物看待的很简单: 1. 它必须属于世界,才能出现在世界.不可能一个不属于世界的食物,出现在世界中:但是可能存在着一个食物,它属于世界,但是却没 ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(五) - 蛇实现
因为已经写了食物的实现,所以我不知道到底是该先写世界的实现还是蛇的实现.因为世界就是一个窗口,可以立刻在世界中看到食物的样子,对于大多数人来说,如果写完代码立刻就能看到效果,那就再好不过了.可是,我最 ...
- [C入门 - 游戏编程系列] 序言篇
记得学习C语言的时候,看着别人能写各种各样的小游戏和小软件,甚是羡慕.而自己,虽然说语法都会,但是真正上手写个几百行的代码,就显得力不从心.曾经一度很是郁闷,看过一些书,大都处于教语法的层面,有些涉及 ...
- [C入门 - 游戏编程系列] 环境篇
这一系列笔记的代码都是在Ubuntu 14.04下编码并测试的,原因无他,因为我笔记本电脑只装了一个Ubuntu系统,其中唯一使用的第三方库SDL也是开源并且跨平台的.所以即使你用的是Windows或 ...
- SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)
前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲 ...
- SQL Server 调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)
前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲 ...
随机推荐
- ScrollView嵌套listview 时根据内容动态设置listview高度
public static void setListViewHeightBasedOnChilds(ListView listView){ ListAdapter listAdapter = list ...
- android Canvas drawText 文字居中
1首先利用canvas获取画布的宽高, //获取屏幕的宽和高int width = canvas.getWidth();int height = canvas.getHeight(); 2获取文字的宽 ...
- Qt浅谈之二十七进程间通信之QtDBus
一.简介 DBus的出现,使得Linux进程间通信更加便捷,不仅可以和用户空间应用程序进行通信,而且还可以和内核的程序进行通信,DBus使得Linux变得更加智能,更加具有交互性. DB ...
- vim 中Ctags的安装和使用
Ctags是一个用来为源文件中的标识符(如变量.函数.类成员.宏定义等)创建索引文件的程序.这些tags文件能被编辑器或其它工具用来快速查找定位源代码中的符号(tag/symbol),如变量名,函数名 ...
- 【转】将Vim改造为强大的IDE—Vim集成Ctags/Taglist/Cscope/Winmanager/NERDTree/OmniCppComplete(有图有真相)
原文网址:http://blog.csdn.net/bokee/article/details/6633193 工欲善其事,必先利其器.一个强大的开发环境可以大大提高工作效率.好吧,我知道这是废话.. ...
- Android ToggleButton使用介绍
ToggleButton,就是开关按钮,包括选中和未选中状态,并且需要为不同的状态设置不同的事件处理: 例如:使用图片来展示ToggleButton不同的状态: MainActivity.java p ...
- java开发经验分享(四)
四. 关于测试 1. 在整个项目计划中,测试时间安排的合理性,对测试阶段的情况应作充分预计,不可为了赶发布点而忽略质量. 2. 务必清楚产品包.更新包.bug包的提交规范.具体请参照<开发规范手 ...
- cf445A DZY Loves Chessboard
A. DZY Loves Chessboard time limit per test 1 second memory limit per test 256 megabytes input stand ...
- 手游与App测试如何快速转型? —— 过来人科普手游与App测试四大区别
随着智能设备的普及和移动互联网的兴起,各家互联网巨头纷纷在往移动端布局和转型,同时初创的移动互联网公司也都盯着这个市场希望分一杯羹.在这个大环境下,互联网的重心已经慢慢从Web端转向了移动端,而移动端 ...
- 关于bootstrap--排版(标题、强调、背景、插入符等)
1. 2.标题:<h1>这是主标题<small>这是副标题,为当前字号65%,灰色(#999)</small></h1>. 3.段落:<p> ...