第5个Demo,这次我们来做第一个真实可玩的玩意儿。
BowlingDemo
这章用到了物体的概念,如果没基础,建议随时查阅这篇SCNPhysicsBody。还不懂的话请恶补物理知识先。
先看效果图:
很简略的一个保龄球游戏。实现了保龄球按位置、角度、旋转方向、力度等不同条件击打的效果。一共也就50来行代码。(其实涉及到新知识的就1行)
1、场景建模
同样可视化完成
与之前不同的是,我们对节点设置了物理属性
在这里再简单说一下(详细介绍见这里),从上到下,
Physice Body
:分为三种,动态、静态、和运动。
动态表示会根据受力情况运动的,静态表示不会动的,运动表示不会受力但是会对其他物体发力的。
Settings
:从上到下依次为“摩擦力”、“弹性”、“滚动摩擦”、“移动阻力”、“旋转阻力”、“电荷”、“是否受重力”、“是否允许静止”。
Bit masks
:从上到下依次为“物体本身分类”、“会发生碰撞的物体分类”、“会监听碰撞的分类”。这些分类都是位,可以通过位运算同时设置多个。
Physics shape
:物体的形状
在我们的Demo里,场地是不会动的,所以设置为staticBody
,球和瓶子都是会受力而运动的,所以设置为dynamicBody
。在该例中不存在kinematicBody
。
摩擦力阻力根据实际效果微调,这些值没必要实际测量。最终效果是根据相对值而不是绝对值。
我们在代码中需要获取到我们的球只需要:
SCNScene *scene = [SCNScene sceneNamed:@"SceneKit Scene.scn"];
self.scnView.scene = scene;
_bowlingBall = [scene.rootNode childNodeWithName:@"bowling" recursively:NO];
2、UI及控制
建模完成后,我们的Demo实际上已经完成80%了。
UI布局,storyboard、xib、code都可以,这个不多说。我说一下我的两个监听。
一个是位置调整:
-(IBAction)positionDidChanged:(UISlider *)sender {
SCNVector3 position = _bowlingBall.position;
position.x = sender.value;
_bowlingBall.position = position;
}
一个是投掷:
-(IBAction)throwing {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(powerChanging) object:nil];
SCNVector3 force = SCNVector3Make(_anglesSlider.value*5, 0, -(15+_power*10));
SCNVector3 postion = SCNVector3Make(_rotatesSlider.value, 0, 0);
[_bowlingBall.physicsBody applyForce:force atPosition:postion impulse:YES];
}
核心是这个方法:- (void)applyForce:(SCNVector3)direction atPosition:(SCNVector3)position impulse:(BOOL)impulse;
给物体的某个位置施加一个力或冲量。
在这我简单说明一下:(上文提到的文章中有详细说明)
force
参数,是一个冲量的矩阵,和SCNNode
的坐标系一样,往前就是-z轴,往左就是-x轴,往上是+y轴,值越大,冲量越大。所以我们这里的力量就是z的值,角度就是x的值。
position
参数,是施力的位置,根据位置的不同,可以使球的旋转方向发生变化。
以上,简单实现了类似保龄球的效果。
慢慢地开始有意思起来了哦。如果有什么不对的地方,谢谢斧正。