使用SKShapeNode(SpriteKit)进行奇怪的碰撞检测

时间:2015-09-26 17:52:42

标签: ios sprite-kit collision-detection shape

我正在尝试检测正方形$files = mysql_query("SELECT * FROM names WHERE name LIKE '$nameid%'") or die(mysql_error()); $i=1; while($row=mysql_fetch_array($files)) { echo "<a href=\"/files/$row[1]\>"; $i++; 和圆SkShapeNode之间的碰撞。它基本上可以工作,但似乎hitbox / physics体并非真正与节点形状对齐。它似乎是随机关闭10-20分。

这是我的代码:

SkShapeNode

我通过移动方形来触发碰撞(圆圈保持在原位):

SKShapeNode* circle= [SKShapeNode shapeNodeWithCircleOfRadius:7.0];
circle.physicsBody= [SKPhysicsBody bodyWithCircleOfRadius:7.0];
circle.physicsBody.usesPreciseCollisionDetection= YES;
circle.physicsBody.categoryBitMask= catCircle;
circle.physicsBody.contactTestBitMask= catSquare;

circle.position= CGPointMake(x, y);
[self addChild:circle];

SKShapeNode* square= [SKShapeNode shapeNodeWithRect:rect];
square.position= position;
square.physicsBody= [SKPhysicsBody bodyWithRectangleOfSize:rect.size];
square.physicsBody.categoryBitMask= catSquare;
square.physicsBody.contactTestBitMask= catCircle;
square.physicsBody.dynamic= YES;
square.physicsBody.usesPreciseCollisionDetection= YES;

[self addChild:square];

一旦检测到碰撞,我就会通过[square runAction:[SKAction moveTo:somePoint duration:2]]; 中的removeAllActions取消操作。

这就是它的样子:

enter image description here

正如你所看到的,一旦触及圆圈,该方块停止,但在此之前/之后有一些点。

我做错了什么?

2 个答案:

答案 0 :(得分:0)

我不确定CD是如何与IOS一起工作的,但这可能是正常行为,通常在发现碰撞时发生碰撞时会发生碰撞检测,如上所示,您的对象将位于另一个对象内部。一旦发生碰撞,您需要将物体移回框架,直到它没有碰撞。

您可以通过每次存储前一帧的位置以及发生碰撞时将对象设置回原位置来执行此操作。

答案 1 :(得分:0)

我有完全相同的问题(Xcode 7,iOS 9),但在我的情况下,问题似乎只与模拟器隔离。当我在设备上运行相同的代码时,它按预期工作。

<强>更新

我遇到的问题似乎与您的不同。但是,我想出了为什么你在物理体中遇到了偏移。要在代码中更好地理解,请添加以下行(最好在视图控制器中的某个位置):

    skView.showsPhysics = YES;

上面的代码将向您展示物理体的轮廓,这是您将看到的(蓝色轮廓代表物理体)。

enter image description here

您选择实例化方块的类方法导致了这种副作用,即:

    SKShapeNode* square= [SKShapeNode shapeNodeWithRect:rect];
  

创建具有矩形路径的形状节点。 (根据Apple的文档)

     

<强>参数   的 RECT
  相对于节点原点的矩形

而是使用此方法创建正方形,事物将按预期运行:

    SKShapeNode* square= [SKShapeNode shapeNodeWithRectOfSize:rect.size];
  

创建一个形状节点,其中矩形路径以节点的原点为中心。

如果您仍打算使用:

        SKShapeNode* square= [SKShapeNode shapeNodeWithRect:rect];

然后你必须确保根据以下内容设置'rect':

rect = CGRectMake(-someWidth/2, -someHeight/2, someWidth, someHeight)

以上将确保physicsBody与形状节点的路径对齐。

至于理解为什么会发生这种情况......当你使用:

创建方形节点时

SKShapeNode * square = [SKShapeNode shapeNodeWithRect:rect];

如果rect = CGRectMake(50.0,50.0,100.0,100.0),那么你正在创建一个SKShapeNode并给它一个矩形的形状,其左下角位于点(50.0,50.0),相对到SKShapeNode。

以后使用:

创建physicsBody
square.physicsBody= [SKPhysicsBody bodyWithRectangleOfSize:rect.size];

物理体的位置默认设置为相对于其节点的原点(SKShapeNode)而不是形状(即CGPathRef)。我知道这听起来有点令人困惑,但我希望它有所启发。

节点的位置相对于其父节点(在您的情况下是场景),而属于SKShapeNode的形状的位置是相对于其节点的。通过使用以下方法实例化方形节点:

SKShapeNode* square= [SKShapeNode shapeNodeWithRectOfSize:rect.size]

你确保你的形状与你的节点对齐。