在initWithSize:方法末尾加入下列代码:
// 1 创建物理形状(以屏幕为边界) SKPhysicsBody* borderBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame]; // 2 将物理形状设为场景的身体 self.physicsBody = borderBody; // 3 设置阻力系数 self.physicsBody.friction = 0.0f; |
创建一个 SKPhysicsBody。 SKPhysicsBody 用于模拟某个节点的外形。在这里,创建了一个只有4边的形状,它没有体积或容积,不受外力和冲量的影响。每个节点都可以设置物理外形。 我们在这里设置了场景的外形。注意:SKPhysicsBody 的坐标系是相对于节点位置而言的。
设置阻尼系数为0.0f,这样当小球撞上笼子边界后不会减速。你需要的是一种完全反射,球体撞上墙壁后以相同角度反弹离开。
完全反射
尽管你拥有一个神奇的笼子,但你看不见效果。只有加入球体之后,你才能看到樊笼的存在。在 initWithSize: 方法最后加入以下代码:
// 1 SKSpriteNode* ball = [SKSpriteNode spriteNodeWithImageNamed: @"ball.png"]; ball.name = ballCategoryName; ball.position = CGPointMake(self.frame.size.width/3, self.frame.size.height/3); [self addChild:ball]; // 2 ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2]; // 3 ball.physicsBody.friction = 0.0f; // 4 ball.physicsBody.restitution = 1.0f; // 5 ball.physicsBody.linearDamping = 0.0f; // 6 ball.physicsBody.allowsRotation = NO; |
如你所料,我们创建了一个角色,以 ball 为名进行引用,设置它的位置(相对于场景),然后添加到场景中。我们将 ball 的外形创建为立体的。与前面基于屏幕边界创建的线条型的形状相比,这种形状受外力和冲量的形象,会与其他形状发生碰撞。我们以“小球”角色同样的大小创建了球形的物理形状。接下来,设置物理形状的属性。你已经使用过摩擦系数了,这行代码应该很明白了,它将使小球的摩擦系数为0。Restitution 属性是指物体的弹性。设为 1.0 意味着球体与另外物体相撞时将会百分之百的反弹。也就是说,球体在碰撞中将以同样力量弹回。LinearDamping 表示气体或液体对物体的减速效果(线性阻尼)。在逃逸游戏中,球不会被减速。因此,线性阻尼设置为0。AllowsRotation 属性正如其字面意义。表示是否允许物体旋转。这里,我们设置为不允许。
注意:通常,让形状与玩家真正看到情况越逼近越好。对于球体,很容易模拟它的行为。但对于更复杂的形状,你不得不花费大量的心思。这里需要提醒你的是,过于复杂的物体可能会付出高额的性能代价。
该让小球动起来了(实际上是跳动起来)。在上述代码后加入这行:
[ball.physicsBody applyImpulse:CGVectorMake(10.0f, -10.0f)]; |
这行代码在小球上施加了一个推力(就像安装了火箭助推器),使它向某个方向运动(沿右下对角线运动)。一旦小球开始运动,它会在笼子中来回反弹。 让我们测试一下。编译运行程序,你会看到小球沿着屏幕的四边不断进行反弹运动。
我不停地跳啊跳,跳得你心烦意乱:D
加入球拍
接下来是什么?这是一个逃逸游戏,然而它还没有球拍。
在 initWithSize: 方法的小球代码后面,加入以下代码来构造球拍(以及它的物理外形):
SKSpriteNode* paddle = [[SKSpriteNode alloc] initWithImageNamed: @"paddle.png"]; paddle.name = paddleCategoryName; paddle.position = CGPointMake(CGRectGetMidX(self.frame), paddle.frame.size.height * 0.6f); [self addChild:paddle]; paddle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:paddle.frame.size]; paddle.physicsBody.restitution = 0.1f; paddle.physicsBody.friction = 0.4f; // 设置物体为静态物体 paddle.physicsBody.dynamic = NO; |
大部分代码和球的代码一样。但是使用了长方体作为球拍的形状,就如你在屏幕中见到的一样。
这里球拍应当是静态的。这样,球拍就不会受重力和外力所影响。接下来你会看到为什么要特别说明这一点。 编译运行程序,球拍会在场景中显示,小球会被球拍弹开。
史上最无聊的游戏:/
这很无聊,因为你根本无法移动球拍。
|