下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

教你怎么在Cocos2D里使用物理引擎box2d制作弹球

作者:课课家教育     来源: http://www.kokojia.com点击数:1247发布时间: 2019-04-16 10:23:47

标签: Cocos2D引擎Cocos2DCocos2D box2d

  相信很多同学都接触过很多球类游戏,想知道怎么在Cocos2D中制作一个弹跳的球吗?本篇教程将教你怎么在Cocos2D里使用物理引擎box2d制作弹球。

  这个教程的目的就是让你们熟悉在cocos2d里面如何使用box2d,所采用的例子就是制作一个简单的应用,里面有一个篮球,你可以通过旋转你的iPhone来改变重力的方向,同时篮球碰到屏幕边界可以反弹。

  创建一个空的工程

  打开xcode,选择 cocos2d-0.99.1 Box2d application template来创建一个新的工程,并且命名为Box2D.如果你直接编译并且运行的话,你将会看到一个很酷的例子,里面展示了Box2d的许多内容。然后,这个教程的目的,我们将从0开始,创建一个篮球反弹的应用,这样我们就可以更好地理解那个范例的具体原理。

  因此,让我们把HelloWorld模板里面的内容都删除掉,因为我们要从0开始。把HelloWorldScene.h里面的内容替换成下面的代码:

  教你怎么在Cocos2D里使用物理引擎box2d制作弹球_Cocos2D引擎_Cocos2D_Cocos2D box2d_课课家

  同时修改HelloWorldScene.mm文件:(为什么后缀是.mm,因为box2d是C++写的,而Objective-C++的实现文件必须是.mm后缀,否则你编译会出n个错误!)

  

  最后一步----验证一下,你的Classes分组下面的所有文件(比如HelloWorldScene)是以.mm文件结尾的,如果是.m,那么请改成.mm,否则等下使用Box2d的时候,编译器会报出一大堆莫名其妙的错误!

  如果你编译并运行,你应该看到一个黑色的屏幕。好了,现在让我们开始创建Box2d场景吧。

  Box2D世界相关理论

  在我们开始之前,让我们先交待一下Box2D具体是如何运作的。

  你需要做的第一件事情就是,当使用cocos2d来为box2d创建一个world对象的时候。这个world对象管理物理仿真中的所有对象。

  一旦我们已经创建了这个world对象,接下来需要往里面加入一些body对象。body对象可以随意移动,可以是怪物或者飞镖什么的,只要是参与碰撞的游戏对象都要为之创建一个相应的body对象。当然,也可以创建一些静态的body对象,用来表示游戏中的台阶或者墙壁等不可以移动的物体。

  为了创建一个body对象,你需要做很多事情--首先,创建一个body定义结构,然后是body对象,再指定一个shap,再是fixture定义,然后再创建一个fixture对象。下面会一个一个解释刚刚这些东西。

  你首先创建一个body定义结构体,用以指定body的初始属性,比如位置或者速度。

  一旦创建好body结构体后,你就可以调用world对象来创建一个body对象了。

  然后,你为body对象定义一个shape,用以指定你想要仿真的物体的几何形状。

  接着创建一个fixture定义,同时设置之前创建好的shape为fixture的一个属性,并且设置其它的属性,比如质量或者摩擦力。

  最后,你可以使用body对象来创建fixture对象,通过传入一个fixture的定义结构就可以了。

  请注意,你可以往单个body对象里面添加很多个fixture对象。这个功能在你创建特别复杂的对象的时候非常有用。比如自行车,你可能要创建2个轮子,车身等等,这些fixture可以用关节连接起来。

  只要你把所有需要创建的body对象都创建好之后,box2d接下来就会接管工作,并且高效地进行物理仿真---只要你周期性地调用world对象的step函数就可以了。

  但是,请注意,box2d仅仅是更新它内部模型对象的位置--如果你想让cocos2d里面的sprite的位置也更新,并且和物理仿真中的位置相同的话,那么你也需要周期性地更新精灵的位置。

  好了,现在有一些基本的了解了,还是先看看代码吧!

  Box2d World 实战

  好了,下载我制作的篮球图片,并且把它添加到工程里去吧。下载完后,直接拖到Resources文件夹下,同时确保 “Copy items into destination group’s folder (if needed)” 被复选中。

  接下来,在HelloWorldScene.mm文件顶部添加下面的代码:

  #define PTM_RATIO 32.0

  这里定义了一个“像素/米”的比率。当你在cocos2d里面指定一个body在哪个位置时,你使用的单位要是米。但是,我们之前使用的都是像素作为单位,那样的话,位置就会不正确。根据Box2d参考手册,Box2d在处理大小在0.1到10个单元的对象的时候做了一些优化。这里的0.1米大概就是一个杯子那么大,10的话,大概就是一个箱子的大小。

  因此,我们并不直接传递像素,因为一个很小的对象很有60×60个像素,那已经大大超过了box2d优化时所限定的大小。因此,如果我们有一个64像素的对象,我们可以把它除以PTM_RATIO,得到2米---这个长度,box2d刚好可以很好地用来做物理仿真。

  好了,现在来点有意思的东西。在HelloWorldScene.h文件顶部添加下列代码:

  #import "Box2D.h"

  同时在HelloWorld类中添加以下成员变量:

  b2World *_world;

  b2Body *_body;

  CCSprite *_ball;

  然后,在HelloWorldScene.mm的init方法中加入下面的代码:

  

  呃,这里有很多陌生的代码。我们一点点来解释一下。下面,我会一段段地重复上面的代码,那样可以解释地更加清楚一些。

  

  首先,我们往屏幕中间加入一个精灵。如果你看了前面的教程的话,这里应该没有什么问题。

  

  接下来,我们创建了world对象。当我们创建这个对象的时候,需要指定一个初始的重力向量。这里,我们设置y轴方向为-30,因此,所有的body都会往屏幕下面下落。同时,我们还指定了一个值,用以指明对象不参与碰撞时,是否可以“休眠”。一个休眠的对象将不会花费处理时间,直到它与其实对象发生碰撞的时候才会“醒”过来。

  

  接下来,我们为整个屏幕创建了一圈不可见的边。具体的步骤如下:

  首先创建一个body定义结构体,并且指定它应该放在左下角。

  然后,使用world对象来创建body对象。(注意,这里一定要使用world对象来创建,不能直接new,因为world对象会做一些内存管理操作。)

  接着,为屏幕的每一个边界创建一个多边形shape。这些“shape”仅仅是一些线段。注意,我们把像素转换成了“meter”。通过除以之前定义的比率来实现的。

  再创建一个fixture定义,指定shape为polygon shape。

  再使用body对象来为每一个shape创建一个fixture对象。

  注意:一个body对象可以包含许许多多的fixture对象。

  

  接下来,我们创建篮球的body。这个步骤和之前创建地面的body差不多,但是有下面一些差别需要注意一下:

  我们指定body的类型为dynamic body。默认值是static body,那意味着那个body不能被移动也不会参与仿真。很明显,我们想让篮球参与仿真。

  设置body的user data属性为篮球精灵。你可以设置任何东西,但是,你设置成精灵会很方便,特别是当两个body碰撞的时候,你可以通过这个参数把精灵对象取出来,然后做一些逻辑处理。

  这里使用了一个不同的shape类型--circle shape。

  在这里,我们需要为这个fixture指定一些参数,因此,我们没有使用便捷方法来创建fixture。后面我们会讲到这些参数的具体意义。

  [self schedule:@selector(tick:)];

  最后一件事情就是调度一个tikck方法,这个方法默认是0.1秒回调一次。注意,这并不是最好的处理方式---最好的方式应该是让tick方法有固定的频率(比如每秒60次)。然后,这个教程我们就先这样了。

  因此,让我们来实现tick方法。在init方法之后加入下面的代码:

  

  第一件事情就是调用world对象的step方法,这样它就可以进行物理仿真了。这里的两个参数分别是“速度迭代次数”和“位置迭代次数”--你应该设置他们的范围在8-10之间。(译者:这里的数字越小,精度越小,但是效率更高。数字越大,仿真越精确,但同时耗时更多。8一般是个折中,如果学过数值分析,应该知道迭代步数的具体作用)。

  接下来,我们要使我们的精灵匹配物理仿真。因此,我们遍历world对象里面的所有body,然后看body的user data属性是否为空,如果不为空,就可以强制转换成精灵对象。接下来,就可以根据body的位置来更新精灵的位置了。

  最后一件事---清理内存!因此,在文件的末尾加入下面的代码:

  

  编译并运行,你应该可以看到球会往下掉,并且会从屏幕底部往上面弹起来。

赞(15)
踩(4)
分享到:
华为认证网络工程师 HCIE直播课视频教程