移动父 SKNode 后,Sprite 工具包找不到 nodeAtPoint

Posted

技术标签:

【中文标题】移动父 SKNode 后,Sprite 工具包找不到 nodeAtPoint【英文标题】:Sprite kit doesn't find nodeAtPoint after moving parent SKNode 【发布时间】:2014-05-07 14:54:21 【问题描述】:

嗨。

我在 Sprite Kit 中遇到了这个奇怪的问题。我正在使用nodeAtPointcategoryBitMask来检测玩家在调用跳转方法时是否触地。

一切正常。但是随后——为了显示抽屉中的一些可选按钮——当我用SKAction moveTo:CGPoint 移动父节点时(我将地面和玩家都作为SKNode 的子节点),玩家不会跳跃。我 NSLog 了pointBelowPlayer,和之前一样,但是blockNode.physicsBody 为空!这可能是 Sprite Kit 中的错误,还是我遗漏了一些关于继承和位置的基本知识?

跳跃的方法:

-(void)playerJump 

    // Player jump if on ground
    CGPoint pointBelowPlayer = CGPointMake(_player.position.x, _player.position.y-_player.size.height);
    SKNode *blockNode = [self nodeAtPoint:pointBelowPlayer];

    if (blockNode.physicsBody.categoryBitMask == groundCategory)
        [_player.physicsBody applyImpulse:CGVectorMake(0, 120.0f)];
    

移动父节点的方法:

-(void)toggleDrawer 
    if (bDrawerVisible) 
        [_actionLayer runAction:[SKAction moveTo:CGPointMake(0, 0) duration:1]];
        bDrawerVisible = false;
     else 
        [_actionLayer runAction:[SKAction moveTo:CGPointMake(0, 200) duration:1]];
        bDrawerVisible = true;
    

创建 SpriteNode:

-(id)initWithSize:(CGSize)size 
    if (self = [super initWithSize:size]) 

        _actionLayer = [SKNode new];

        _player = [self createPlayer];
        [_actionLayer addChild:_player];

        _ground = [self createGround];
        [_actionLayer addChild:_ground];


-(SKSpriteNode *)createPlayer 

    SKSpriteNode *player = [SKSpriteNode spriteNodeWithImageNamed:@"redSquare.png"];
    player.name = @"player";
    player.scale = 0.5;
    player.position = CGPointMake(screenWidth/3, player.size.height*2);
    player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.size];
    player.physicsBody.categoryBitMask = playerCategory;
    player.physicsBody.collisionBitMask = groundCategory;
    player.physicsBody.contactTestBitMask = noteCategory;

    return player;


-(SKSpriteNode *)createGround 

    SKSpriteNode *ground = [SKSpriteNode spriteNodeWithImageNamed:@"ground.png"];
    ground.name = @"ground";
    ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ground.size];
    ground.physicsBody.dynamic = NO;
    ground.physicsBody.categoryBitMask = groundCategory;
    ground.physicsBody.collisionBitMask = playerCategory;
    ground.xScale = screenWidth/ground.size.width;;
    ground.position = CGPointMake(self.size.width/2, 0);

    return ground;

【问题讨论】:

【参考方案1】:

好的,我解决了这个问题... 如果您有多个节点,在您点击的位置,如果最深的节点没有名称,或者最深的节点的名称,您将获得 null。

所以用这个去遍历所有节点都找到了:

UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
NSArray *buttonNodes = [self nodesAtPoint:location];
for (SKNode *node in buttonNodes)

    NSLog(@"%@", node.name);

另外,您可以使用NSLog(@"%f", node.zPosition); 获取 zPosition 以查看女巫在顶部。

【讨论】:

澄清一下,nodeAtPoint 返回该点最深的节点,nodeAtPoint 返回该点所有节点的数组。 这解决了我使用 SK 应用程序从 ios7 迁移到 iOS8 时遇到的问题。谢谢!【参考方案2】:

当前节点可能是另一个节点(可能是您的背景?)。 使用 node.name 命名节点,您可以通过使用 equalToString: 方法比较名称来检查节点是否相同。

【讨论】:

感谢您的快速回复!开发初期,我目前没有任何背景——node.name 在父移动之后返回(null)(之前是“ground”),所以没有其他 nodeAtPoint。 @Brean 它将返回 null,因为未设置名称。为您的节点和日志名称设置不同的名称,然后看看会发生什么。 地面节点已经命名,从我上面的代码可以看出。如果我对 pointBelowPlayer 的节点进行 NSLog 记录,它会返回:<SKScene> name:'(null)' frame:0, 0, 1024, 768,就好像地面不存在一样。

以上是关于移动父 SKNode 后,Sprite 工具包找不到 nodeAtPoint的主要内容,如果未能解决你的问题,请参考以下文章

Sprite Kit中的碰撞检测未检测到碰撞

如何在场景中放置场景 - Sprite Kit

iOS -- SKSpriteNode类

在 Sprite Kit 中复制粒子发射器效果

尝试添加一个已经有父错误的 SKNode

Swift Sprite Kit 再次调用 Function