Sprite kit学习

来源:互联网 发布:php 数组转json 编辑:程序博客网 时间:2024/06/07 11:41
      
   一起来学习SpriteKit的物理系统。
 
完成游戏的物理系统设置,你需要一下完成以下几点:
1、把SKPhysicsBody关联到拥有物理属性的游戏对象上,每一个游戏对象node节点都有physicsbody属性
2、设置physicsbody的各个属性,让游戏对象在游戏里面呈现更好的游戏效果
3、设置整个游戏世界的物理系统,比如重力,注意,scene也有物理属性
4、可以在physicsbody上施加力
5、定义物体之间的碰撞处理
6、优化整个物理系统

    个人觉得,SpriteKit的碰撞检测做得真心赞。
 
physics body(后面简称pb)有三种,一种是运动的,一种是静止的,还有一种叫做edge的,运动的pb可以接受外界所有的关于物理的影响,静止的pb没有速度,不受力和碰撞的影响,区分这两种pb是有好处的,普通的游戏对象一般都是运动的pb,而墙壁啊,地面,游戏场景的边界等就可以静止的pb
 
edge的话,其实就是边啦,可以这样理解,自由无规则的pb,一般边界可以用它来限定,它频繁地被用来当作游戏场景的边界,还有一个用处是,游戏对象都是有形状的,SpriteKit提供了几种形状给我们,但其实在现实真正的游戏当中,往往我们的游戏对象都是不规则图形,这个时候,如果你想要为你的游戏对象加上一个具有相似形状的pb的话,就可以考虑使用edge了,不过这不是经常采取的方法,使用edge来定形要很大量的计算,消耗资源,这会让你的游戏变得不顺畅,所以不是很提倡这种做法。
这里说几个pb的属性吧,mass属性,即质量,这个学过物理或者没学过的都知道的拉,有mass当然就有density密度啦,这两个属性是会随着对方的变化而变化的,唯一不变的是物体的形状,整个真得学过物理才知道,mass等于density乘于area体积。
 
friction属性,摩擦力,就是物体表面的粗糙程度,在其上面运动的物体会受到其friction的影响,力的话还有linearDamping阻力和angularDamping角力,就是旋转的力,这个跟你的游戏世界里的环境有空,一般是空气阻力啦,或者是在水中的阻力啦,由你的环境决定。
 
restitution属性,可以理解为势能吧,在碰撞的时候它决定碰撞的威力,即作用效果的强弱。
 
dynamic属性,一般动态pb的默认值为yes,将其设置为no之后,就是静态pb了。
 
affectedByGravity属性,yes即接受重力影响,no则不受重力影响。
 
allowsRotation属性,它决定物体是否能选择,设置为no即冻结旋转。


这三个属性很重要:
categoryBitMask,它标记了物体属于那一类物体,默认值为0xffffffff
collisionBitMask,它标记了哪些物体可以跟其发生碰撞,默认值为0xffffffff
contactTestBitMask,它标记了哪些物体会和其发生碰撞后产生一些影响,默认值为0x00000000
 
这三个数值均由32位的十六进制数来表示,即你的游戏可以有32中不同类型的物体,其实用不到那么多,为什么用这样的值来表示,这也是我觉得新颖的地方,在做碰撞检测时,这些值是拿来做逻辑与运算,计算碰撞用的。

判断其他物体是否可以跟自己发生碰撞,要根据自己的collisionBitMask的值与对方物体的categoryBitMask的值进行逻辑与运算,得到的结果不为0,即可以发生碰撞。

SpriteKit提供给我们一个叫做SKPhysicsContactDelegate,这也是它唯一给的一个协议,在初始化scene的时候设置scene.physicsWorld.contactDelegate = self;在.h头文件加上该协议,它提供了好两个检测碰撞的函数,-didBeginContact:和-didEndContact:参数都是一个SKPhysicsContact,里面包含了两个碰撞体的信息,和碰撞的信息,建议大家去看看SKPhysicsContact的api,开发起来才更加得心应手,我们就可以在这两个函数里做我们在碰撞时要做的事情了。

说完碰撞,接着是将多个pb物体连接在一起的joint,可以理解为骨骼吧,如果你想你的游戏展现一些更复杂的物理特效的话,你可能会需要它,这里也不多说了。
 
在游戏中,有时我们需要操控我们的游戏对象,整个时候就需要选中该对象,当对象有了pb之后,我们可以通过很多方法来找到它。最常用的方法,应该不陌生了,就是通过ray射线来寻找物体,首先我们需要确定一条射线,举个例子吧,在平面中,我们可以以(0, 0)为起点,手指点击屏幕的点为终点,一般在3d场景,是通过摄像机的位置点作为起点,然后点击的地方为终点来确定一条射线,然后通过函数bodyAlongRayStart:end:来获取射线穿过的物体,注意整个函数只能获取一个,如果你的射线穿过很多个物体,这时可以使用enumerateBodiesAlongRayStart:end:usingBlock:函数来获取射线上所有的物体,在你的block里面,你可以拿到每个物体的信息,根据这些信息你就可以判断那个是你想要的得到的。还有就是可以根据名字获取物体,整个在前面的文章有提到过。
 
另外还可以根据点来寻找物体,bodyAtPoint:函数会根据你提供的点,判断点是否属于物体,是的话就返回该物体。还有bodyAtRect:函数,在场景中设置一个rect,当有物体进入rect时,bodyAtRect就会返回该物体。
 
接下来是一些注意事项,虚拟整个物理系统是很消耗资源的,所以尽量让你的游戏的物理方面的计算减少,让你的游戏运行得更顺畅,记住你为你的pb设置的一切东西,根据这些设置带来的性质去实现你的游戏逻辑或者是游戏效果,只有知道它们到底是怎么一回事才能把它们的作用发挥出来,关于优化的,得花谢时间出来研究研究,每个游戏引擎都有一套或者几套优化方案,SpriteKit肯定也会有,知道你的机器是怎么运作的,然后再知道你的引擎是怎么在机器上运作的,这样会让对优化你的程序有更大的帮助。
 
也差不多这些了吧,关于物理系统的东西,很强大,有些可能需要自己用过才知道,另外还有粒子系统,也找个时间好好研究研究,写一篇专门的关于粒子系统的笔记。
 


 

0 0