body上的bodyWithEdgeLoopF​​romRect

时间:2014-06-17 23:50:55

标签: ios7 sprite-kit skphysicsbody

我想创建几个包含精灵的盒子,让我们说正方形。方块将在框边框内反弹。为此,我为每个盒子使用了bodyWithEdgeLoopF​​romRect。为什么我使用bodyWithEdgeLoopF​​romRect而不是创建一个物理身体?因为我希望盒子内的方块被限制并仅在内部反弹。如果我创建一个物理身体,方块将从外部碰撞。

我为每个盒子创建了一个[SKPhysicsBody bodyWithEdgeLoopF​​romRect:]但是正方形只是留下了盒子,因为里面没有物理体。 似乎bodyWithEdgeLoopF​​romRect仅适用于场景SKNode物理节点:self.physicsBody

我检查了bodyWithEdgeLoopF​​romRect方法的文档,但没有提到它必须只用在场景对象上。它似乎可以在任何SKNode上使用。

这是代码。里面的白色方块因重力而下降。他们不会像我认为的那样在黑匣子内反弹。

self.physicsWorld.gravity = CGVectorMake(0, -0.2);
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
SKSpriteNode *boxContainer01 = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(100, 100)];
boxContainer01.position = CGPointMake(boxContainer01.size.width/2, self.size.height/2);
SKSpriteNode *boxContainer02 = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(100, 100)];
boxContainer02.position = CGPointMake(self.size.width - boxContainer01.size.width/2, self.size.height/2);

boxContainer01.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:boxContainer01.frame];
boxContainer02.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:boxContainer02.frame];
boxContainer01.physicsBody.collisionBitMask = 1;
boxContainer02.physicsBody.collisionBitMask = 1;
SKSpriteNode *square01 = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(20, 20)];
square01.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:square01.size];
square01.physicsBody.collisionBitMask = 1;
SKSpriteNode *square02 = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(20, 20)];
square02.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:square02.size];
square02.physicsBody.collisionBitMask = 1;

[boxContainer01 addChild:square01];
[boxContainer02 addChild:square02];

[self addChild:boxContainer01];
[self addChild:boxContainer02];
self.physicsBody.collisionBitMask = 1;

Squares ignore the physics body Squares hit the borders of the screen

2 个答案:

答案 0 :(得分:0)

假设您发布的代码片段在物理设置方面是完整的,那么您缺少的是设置物体的contactTestBitMask。默认情况下,它的值为0,这意味着除非更改位掩码,否则身体不会与其他身体接触(因此不会发生碰撞)。

尝试为所有身体提供相同的接触测试位掩码,例如:

node.physicsBody.contactTestBitMask = 1;

这将使那些contactTestBitMask匹配的物体(更精确:当两个物体的contactTestBitMask值之间的逻辑AND比较导致非零值时)它们将接触并发生碰撞。

答案 1 :(得分:0)

我相信我终于找到了答案。我也遇到了一个绊脚石,并使用Apple的spritekit编程指南中的代码来生成落石,看看物理体是否恰好在别处创建。我的盒子位于屏幕的中央,但落下的岩石击中了屏幕右上角的一个看不见的块,所以似乎bodyWithEdgeLoopF​​romRect在创建物理体时试图重新计算原点。在Apple的bodyWithEdgeLoopF​​romRect文档中,它说:

  

rect:定义边的矩形。指定了矩形   相对于拥有节点的起源。

我相信发生的事情是,当您更改框的位置时,您将在父节点的坐标系中更改它。添加物理实体时,您在框本身的坐标空间中这样做。首次创建框时,父节点和框的坐标系是对齐的,但只要移动框,它们就不一样了。

因此,最简单的解决方案是在设置框位置之前为框框架创建物理主体。这样做可以让您在重新定位时正确对齐。要么是这样,要么将你的物理体更改为此(这正确设置原点,因为锚点自动位于框的中心):

boxContainer01.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(-boxContainer01.frame.size.width/2, -boxContainer01.frame.size.height/2, boxContainer01.frame.size.width, boxContainer01.frame.size.height)];