- 1、本文档共6页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
11.2 物理模拟
11.2 物理模拟
物理模拟
即使使⽤了基于定时器的动画来复制第10章中关键帧的⾏为,但还是会有⼀些 质上
的区别:在关键帧的实现中,我们提前计算了所有帧,但是在新的解决⽅案中,我们
实际上实在按需要在计算。意义在于我们可以根据⽤户输⼊实时修改动画的逻辑,或
者和别的实时动画系统例如物理引擎进⾏整合。
Chipmunk
我们来基于物理学创建⼀个真实的重⼒模拟效果来取代当前基于缓冲的弹性动画,但
即使模拟2D的物理效果就已近极其复杂了,所以就不要尝试去实现它了,直接⽤开源
的物理引擎库好了。
我们将要使⽤的物理引擎叫做Chipmunk 。另外的2D物理引擎也同样可以 (例如
Box2D ),但是Chipmunk使⽤纯C写的,⽽不是C++ ,好处在于更容易和Objective-C
项⽬整合。Chipmunk有很多版 ,包括⼀个和Objective-C绑定的“indie”版 。C语⾔
的版 是免费的,所以我们就⽤它好了。在 书写作的时候6.1.4是最新的版 ;你可
以从http: 下载它。
Chipmunk完整的物理引擎相当巨⼤复杂,但是我们只会使⽤如下⼏个类:
cpSpace - 这是所有的物理结构体的容器。它有⼀个⼤⼩和⼀个可选的重⼒⽮
量
cpBody - 它是⼀个固态⽆弹⼒的刚体。它有⼀个坐标,以及其他物理属性,例
如质量,运动和摩擦系数等等。
cpShape - 它是⼀个抽象的⼏何形状,⽤来检测碰撞。可以给结构体添加⼀个
多边形,⽽且cpShape有各种⼦类来代表不同形状的类型。
在例⼦中,我们来对⼀个⽊箱建模,然后在重⼒的影响下下落。我们来创建⼀
个Crate类,包含屏幕上的可视效果 (⼀个UIImageView)和⼀个物理模型 (⼀
个cpBody和⼀个cpPolyShape,⼀个cpShape的多边形⼦类来代表矩形⽊箱)。
⽤C版 的Chipmunk会带来⼀些挑战,因为它现在并不⽀持Objective-C的引⽤计数模
型,所以我们需要准确的创建和释放对象。为了简化,我们把cpShape和cpBody的
⽣命周期和Crate类进⾏绑定,然后在⽊箱的-init⽅法中创建,在-dealloc中释
放。⽊箱物理属性的配置很复杂,所以阅读了Chipmunk⽂档会很有意义。
视图控制器⽤来管理cpSpace,还有和之前⼀样的计时器逻辑。在每⼀步中,我们更
新cpSpace (⽤来进⾏物理计算和所有结构体的重新摆放)然后迭代对象,然后再更
新我们的⽊箱视图的位置来匹配⽊箱的模型 (在这⾥,实际上只有⼀个结构体,但是
之后我们将要添加更多)。
Chipmunk使⽤了⼀个和UIKit颠倒的坐标系 (Y轴向上为正⽅向)。为了使得物理模型
和视图之间的同步更简单,我们需要通过使⽤geometryFlipped属性翻转容器视图
的集合坐标 (第3章中有提到),于是模型和视图都共享⼀个相同的坐标系。
具体的代码见清单11.3 。注意到我们并没有在任何地⽅释放cpSpace对象。在这个例
⼦中,内存空间将会在整个app 的⽣命周期中⼀直存在,所以这没有问题。但是在现
实世界的场景中,我们需要像创建⽊箱结构体和形状⼀样去管理我们的空间,封装在
标准的Cocoa对象中,然后来管理Chipmunk对象的⽣命周期。图11.1展⽰了掉落的⽊
箱。
清单11.3 使⽤物理学来对掉落的⽊箱建模
#import ViewController.h
#import
#import chipmunk.h
interface Crate : UIImageView
property (nonatomic, assign) cpBody *body;
property (nonatomic, assign) cpShape *shape;
end
implementation Crate
#define MASS 100
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
//set image
self.image = [UIImage imageNamed: Crate.png];
self.contentMode = UIViewContentModeScaleAspectFill;
//create the body
文档评论(0)