SceneKit自学之路(5)

第5个Demo,这次我们来做第一个真实可玩的玩意儿。


BowlingDemo

这章用到了物体的概念,如果没基础,建议随时查阅这篇SCNPhysicsBody。还不懂的话请恶补物理知识先。
先看效果图:

最终效果图

很简略的一个保龄球游戏。实现了保龄球按位置、角度、旋转方向、力度等不同条件击打的效果。一共也就50来行代码。(其实涉及到新知识的就1行)

1、场景建模

同样可视化完成

SceneKit自学之路(5)_第1张图片
场景建模

与之前不同的是,我们对节点设置了物理属性
SceneKit自学之路(5)_第2张图片
物理属性

在这里再简单说一下(详细介绍见 这里),从上到下,

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参数,是施力的位置,根据位置的不同,可以使球的旋转方向发生变化。
以上,简单实现了类似保龄球的效果。


慢慢地开始有意思起来了哦。如果有什么不对的地方,谢谢斧正。

你可能感兴趣的:(SceneKit自学之路(5))