[C入门 - 游戏编程系列] 贪吃蛇篇(四) - 食物实现
由于食物是贪吃蛇游戏中最简单的一部分,而且和其他部分关联性不强,基本上是一个独立的部分,所以我打算先实现它。
我的想法是食物必须在世界中才能被创造出来,也就是说,先有世界再有食物,所以我得先判断世界是否存在,存在的话才可以创建食物。
Food * SNK_CreateFood(World *world, int size)
{
Food *food; if (world == ) return ; if ((food = (Food *)SDL_malloc(sizeof(Food))) == ) return ; INIT_FOOD(world, size); return food;
}
对于指针变量,我总是显式地将它和数值比较,这有助于避免某些隐藏的错误。宏INIT_FOOD用来初始化Food结构体,在最后的完整源码中可以看到定义。
由于food是用SDL_malloc函数分配的,所以销毁食物只要释放内存就可以了。在C语言中,释放后的指针并不为零, 一个好的习惯是:每次释放指针后,显式的将指针置为零。我总是会遵循这个习惯,除非释放指针后程序也立刻退出,否则我总是将释放后的指针置为零。
void SNK_DestroyFood(Food *food)
{
SDL_free(food);
food = ;
}
我对食物的美或丑没有任何概念,所以我这里所谓的食物仅仅只是一个矩形。在画食物这里可以有很多创意,画一个奇葩的食物可以令人耳目一新。不过我只力求简洁,意思到了就可以了。
void SNK_DrawFood(Food *food)
{
SDL_Rect rect; if (food != )
{
rect.x = food->x;
rect.y = food->y;
rect.w = rect.h = food->size; if (((food->world != ) ? (food->world->render != ) : ))
{
SDL_SetRenderDrawColor(food->world->render,
food->color.r, food->color.g,
food->color.b, food->color.a);
SDL_RenderDrawRect(food->world->render, &rect);
}
}
}
设置食物位置的函数定义的很简单,给一个食物和坐标就可以了。但是内部实现起来我还是做了一点判断和处理,为了保证两方面的可行性:1. 确保坐标是正数且在世界范围内。2. 食物坐标要为食物大小的整数倍。尽管不是整数倍也能行,不过我是打算将食物和蛇设置为相同大小的,如果不是整数倍,就会发生蛇还没吃完食物,食物就消失了的情况。
void SNK_SetFoodPosition(Food *food, int x, int y)
{
if (((food != ) ? (food->world != ) : ))
{
if (SDL_abs(x) > food->world->w)
x = food->world->w; if (SDL_abs(y) > food->world->h)
y = food->world->h; if (food->size != )
{
food->x = (SDL_abs(x) / food->size) * food->size;
food->y = (SDL_abs(y) / food->size) * food->size;
}
}
}
最后就是设置食物颜色了,这个很简单,依次赋值就行了。
void SNK_SetFoodColor(Food *food, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
if (food != )
{
food->color.r = r;
food->color.g = g;
food->color.b = b;
food->color.a = a;
}
}
以下是snk-food.c文件的完整内容:
#include "snk-food.h" #define INIT_FOOD(world, size) \
food->world = (world); \
food->x = food->y = ; \
food->size = (size) ? SDL_abs(size) : ; \
food->color.r = food->color.g = food->color.b = food->color.a = ; Food * SNK_CreateFood(World *world, int size)
{
Food *food; if (world == ) return ; if ((food = (Food *)SDL_malloc(sizeof(Food))) == ) return ; INIT_FOOD(world, size); return food;
} void SNK_DestroyFood(Food *food)
{
SDL_free(food);
food = ;
} void SNK_DrawFood(Food *food)
{
SDL_Rect rect; if (food != )
{
rect.x = food->x;
rect.y = food->y;
rect.w = rect.h = food->size; if (((food->world != ) ? (food->world->render != ) : ))
{
SDL_SetRenderDrawColor(food->world->render,
food->color.r, food->color.g,
food->color.b, food->color.a);
SDL_RenderDrawRect(food->world->render, &rect);
}
}
} void SNK_SetFoodPosition(Food *food, int x, int y)
{
if (((food != ) ? (food->world != ) : ))
{
if (SDL_abs(x) > food->world->w)
x = food->world->w; if (SDL_abs(y) > food->world->h)
y = food->world->h; if (food->size != )
{
food->x = (SDL_abs(x) / food->size) * food->size;
food->y = (SDL_abs(y) / food->size) * food->size;
}
}
} void SNK_SetFoodColor(Food *food, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
if (food != )
{
food->color.r = r;
food->color.g = g;
food->color.b = b;
food->color.a = a;
}
}
[C入门 - 游戏编程系列] 贪吃蛇篇(四) - 食物实现的更多相关文章
- [C入门 - 游戏编程系列] 贪吃蛇篇(二) - 食物定义
游戏中的食物没有那么多复杂属性,特别是贪吃蛇游戏中,我把食物看待的很简单: 1. 它必须属于世界,才能出现在世界.不可能一个不属于世界的食物,出现在世界中:但是可能存在着一个食物,它属于世界,但是却没 ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(一) - 世界定义
每个游戏都有一个很明确的目的或者说游戏主题,贪吃蛇的目的很明确:蛇找到并吃掉食物.只有目的是很无聊的,算不上一个好游戏.所以设计者增加了创意:1. 吃掉食物后蛇会增长:2. 吃掉食物后分数会增加.有些 ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(六) - 蛇实现
这一篇是关于设置蛇的属性的,接上一篇(五). 设置蛇的速度,很简单,只要不是负数就行了. void SNK_SetSnakeSpeed(Snake *snake, int speed) { ) sna ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(三) - 蛇定义
蛇是这个游戏的主角,要实现的功能也是最复杂的一个.因为蛇不止有属性,还有行为.它会动,还会吃东西,还会长大!而且还会死!这是很要命的.我一向看不懂复杂的代码,也写不出复杂的代码.所以对于蛇,我很纠结, ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(五) - 蛇实现
因为已经写了食物的实现,所以我不知道到底是该先写世界的实现还是蛇的实现.因为世界就是一个窗口,可以立刻在世界中看到食物的样子,对于大多数人来说,如果写完代码立刻就能看到效果,那就再好不过了.可是,我最 ...
- [C入门 - 游戏编程系列] 序言篇
记得学习C语言的时候,看着别人能写各种各样的小游戏和小软件,甚是羡慕.而自己,虽然说语法都会,但是真正上手写个几百行的代码,就显得力不从心.曾经一度很是郁闷,看过一些书,大都处于教语法的层面,有些涉及 ...
- [C入门 - 游戏编程系列] 环境篇
这一系列笔记的代码都是在Ubuntu 14.04下编码并测试的,原因无他,因为我笔记本电脑只装了一个Ubuntu系统,其中唯一使用的第三方库SDL也是开源并且跨平台的.所以即使你用的是Windows或 ...
- Love2D游戏引擎制作贪吃蛇游戏
代码地址如下:http://www.demodashi.com/demo/15051.html Love2D游戏引擎制作贪吃蛇游戏 内附有linux下的makefile,windows下的生成方法请查 ...
- H5游戏开发:贪吃蛇
贪吃蛇的经典玩法有两种: 积分闯关 一吃到底 第一种是笔者小时候在掌上游戏机最先体验到的(不小心暴露了年龄),具体玩法是蛇吃完一定数量的食物后就通关,通关后速度会加快:第二种是诺基亚在1997年在其自 ...
随机推荐
- JS apply()的使用详解
首先: apply和call的区别在哪里? 其次: 什么情况下用apply,什么情况下用call? 最后: 一般在什么情况下可以使用apply? *************************** ...
- 关于selenium中的sendKeys()隔几秒发送一个字符
看一下你的IEDriverServer.exe是不是64位的,我也遇到了这样的问题,换成32位的IEDriverServer.exe,瞬间速度快了
- 【转】将Vim改造为强大的IDE—Vim集成Ctags/Taglist/Cscope/Winmanager/NERDTree/OmniCppComplete(有图有真相)
原文网址:http://blog.csdn.net/bokee/article/details/6633193 工欲善其事,必先利其器.一个强大的开发环境可以大大提高工作效率.好吧,我知道这是废话.. ...
- SPOJ375.QTREE树链剖分
题意:一个树,a b c 代表a--b边的权值为c.CHANGE x y 把输入的第x条边的权值改为y,QUERY x y 查询x--y路径上边的权值的最大值. 第一次写树链剖分,其实树链剖分只能说 ...
- 使用Python做科学计算初探
今天在搞定Django框架的blog搭建后,尝试一下python的科学计算能力. python的科学计算有三剑客:numpy,scipy,matplotlib. numpy负责数值计算,矩阵操作等: ...
- mysql 存储过程:提供查询语句并返回查询执行影响的行数
mysql 存储过程:提供查询语句并返回查询执行影响的行数DELIMITER $$ DROP PROCEDURE IF EXISTS `p_get_select_row_number`$$ CREAT ...
- Java基础 -- 冒泡排序算法(带详细注释)
冒泡排序的要点: 1.多轮排序,每轮排序中选出最大的元素放在最顶端,并且下次排序不再使用该元素; 2. 使用双for循环,外层for循环控制要排序的次数(轮数), 内层for循环控制当前要排序的元素并 ...
- js推断元素是否隐藏
if( document.getElementById("div").css("display")==='none') if( document.getEl ...
- MongoDB 的 MapReduce 大数据统计统计挖掘
MongoDB虽然不像我们常用的mysql,sqlserver,oracle等关系型数据库有group by函数那样方便分组,但是MongoDB要实现分组也有3个办法: * Mongodb三种分组方式 ...
- 解决linux不能使用chmod更改权限的问题
本人安装的是win10和ubuntu的双系统,发现在ubuntu下挂载windows硬盘不用命令chmod更改文件的权限,解决方法记录如下: 对于使用命令$ chmod 777 dirname更改不了 ...