SKSpriteNode 无法检测到与两个 bodyWithEdgeLoopFromPath 主体的碰撞
Posted
技术标签:
【中文标题】SKSpriteNode 无法检测到与两个 bodyWithEdgeLoopFromPath 主体的碰撞【英文标题】:SKSpriteNode can't detect collision with two bodyWithEdgeLoopFromPath bodies 【发布时间】:2015-01-30 03:19:10 【问题描述】:我使用 bodyWithEdgeLoopFromPath 创建了两个对象。但是当我通过方法检查碰撞时 - (void)didBeginContact:(SKPhysicsContact *)contact。它不工作。
对象 1: UIBezierPath *paddleLeftPath = [UIBezierPath bezierPath];
[paddleLeftPath moveToPoint:CGPointMake(-19,17)];
[paddleLeftPath addLineToPoint:CGPointMake(20,17)];
[paddleLeftPath addLineToPoint:CGPointMake(10,6)];
[paddleLeftPath addLineToPoint:CGPointMake(17,-7)];
[paddleLeftPath addLineToPoint:CGPointMake(6,-19)];
[paddleLeftPath addLineToPoint:CGPointMake(-6,-20)];
[paddleLeftPath addLineToPoint:CGPointMake(-17,-11)];
[paddleLeftPath addLineToPoint:CGPointMake(-13,6)];
[paddleLeftPath closePath];
objectRocket = [[NodeRocket alloc] initWithWithFile:@"main0.png" scale:0.5 atPosition:CGPointMake(CGRectGetMidX(self.frame),110)];
objectRocket.name = @"Rocket";
objectRocket.physicsBody.dynamic = NO;
objectRocket.physicsBody.usesPreciseCollisionDetection = YES;
objectRocket.physicsBody.categoryBitMask = rocketCategory;
objectRocket.physicsBody.collisionBitMask = meteorCategory;
objectRocket.physicsBody.contactTestBitMask = meteorCategory;
objectRocket.zPosition = 10;
objectRocket.physicsBody.allowsRotation = NO;
[self addChild:objectRocket];
对象 2: SKNode* meteorPair = [SKNode 节点]; meteorPair.position = CGPointMake(0, 0); 流星对.zPosition = 10;
NSInteger scaleValue = (arc4random() % 8) + 1;
meteorTexture = [SKTexture textureWithImageNamed:[NSString stringWithFormat:@"monster%d.png",(int)scaleValue]];
[meteorTexture setFilteringMode:SKTextureFilteringNearest];
if (pointDrop.x > self.size.width - meteorTexture.size.width/2 - 10)
pointDrop.x = self.size.width - meteorTexture.size.width/2 - 10;
else if (pointDrop.x < meteorTexture.size.width/2 + 10)
pointDrop.x = meteorTexture.size.width/2 + 10;
CGFloat x = (arc4random() % 2) + 0.5;
CGFloat distanceToMove = self.frame.size.height - 115 - objectUFO.size.height/2;
SKAction* moveMeteor = [SKAction moveByX:0 y:-distanceToMove duration:x/100.0 * distanceToMove];
SKAction* removeMeteor = [SKAction removeFromParent];
moveMeteorAndRemove = [SKAction sequence:@[moveMeteor, removeMeteor]];
SKSpriteNode* meteorObject = [SKSpriteNode spriteNodeWithTexture:meteorTexture];
[meteorObject setScale:0.55];
meteorObject.position = CGPointMake(pointDrop.x, pointDrop.y - objectUFO.size.height/2 );
UIBezierPath *paddleLeftPath = [UIBezierPath bezierPath];
[paddleLeftPath moveToPoint:CGPointMake(-22,28)];
[paddleLeftPath addLineToPoint:CGPointMake(21,28)];
[paddleLeftPath addLineToPoint:CGPointMake(17,-30)];
[paddleLeftPath addLineToPoint:CGPointMake(-18,-30)];
[paddleLeftPath closePath];
meteorObject.name = [NSString stringWithFormat:@"monster%d.png",(int)scaleValue];
meteorObject.physicsBody.dynamic = NO;
meteorObject.physicsBody.usesPreciseCollisionDetection = YES;
meteorObject.physicsBody.categoryBitMask = meteorCategory;
[meteorPair addChild:meteorObject];
[meteorPair runAction:moveMeteorAndRemove];
meteorPair.name = @"meteor pair";
[self addChild:meteorPair];
meteorObject.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromPath:paddleLeftPath.CGPath];
请帮助我。我做错了什么?
【问题讨论】:
查看文档,两个静态(基于边缘)的物体永远不会产生碰撞。同样使用移动动作绕过物理模拟,使用 applyImpulse/Force 来移动动态物理体。 我让物体meteorObject坠落到与objectRocket发生碰撞。但是方法 didBeginContact 不起作用。 我将 bodyWithEdgeLoopFromPath 更改为 bodyWithPolygonFromPath。和meteorObject.physicsBody.dynamic = YES。他们可能会发生冲突,但方法 didBeginContact 仍然无法正常工作。 你设置了collisionDelegate吗?还要检查类别等位掩码,它们经常被误解,它们必须双向(即流星和火箭在一个主体中,火箭和流星在另一个主体中 - 仅省略其中一个位掩码不会产生碰撞)。 【参考方案1】:你为 SKScene 的物理世界设置了 contactDelegate 了吗?也许您错过了它,然后 didBeginContact 从未被调用过。 在你的游戏场景上试试这个
self.physicsWorld.contactDelegate = self
【讨论】:
【参考方案2】:看起来你在分配物理体之前设置了一堆参数。
我是 SKPhysics 的新手,但从所有示例中可以看出,当您创建节点时,它带有一个 nil/null 物理体。
要明确。 SKSpriteNode* meteorObject = [SKSpriteNode spriteNodeWithTexture: ... meteorObject.physicsBody.dynamic = NO; meteorObject.physicsBody.usesPreciseCollisionDetection = YES; meteorObject.physicsBody.categoryBitMask = meteorCategory; ... meteorObject.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromPath:
必须是:-
SKSpriteNode*meteorObject = [SKSpriteNode spriteNodeWithTexture: ... meteorObject.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromPath: meteorObject.physicsBody.dynamic = NO; meteorObject.physicsBody.usesPreciseCollisionDetection = YES; meteorObject.physicsBody.categoryBitMask = meteorCategory; ...
【讨论】:
以上是关于SKSpriteNode 无法检测到与两个 bodyWithEdgeLoopFromPath 主体的碰撞的主要内容,如果未能解决你的问题,请参考以下文章
didBegin 未检测到两个 SKSpriteNode 之间的接触