在子类节点中未检测到冲突

Posted

技术标签:

【中文标题】在子类节点中未检测到冲突【英文标题】:No collisions being detected in subclassed nodes 【发布时间】:2016-11-28 17:17:35 【问题描述】:

我正在写一个游戏。它没有检测到任何碰撞,即使我在打开该视图时可以看到物理体。

为了在游戏场景中设置物理世界,我在类声明上方编写了以下代码:

struct PhysicsCategory 
    static let None: UInt32 = 0
    static let Chicken: UInt32 = 0b1
    static let Edge: UInt32 = 0b10

然后,在场景的实际类中:

override func didMove(to view: SKView) 
    setupNodes()
    setupTrial()

    let playableRect = CGRect(x: 0, y: 0, width: size.width/2, height: size.height/2)
    self.physicsBody = SKPhysicsBody(edgeLoopFrom: playableRect)
    self.physicsWorld.contactDelegate = self
    self.physicsBody!.categoryBitMask = PhysicsCategory.Edge
    self.physicsBody!.contactTestBitMask = PhysicsCategory.Chicken

    // This is important for handling all the custom events
    enumerateChildNodes(withName: "//*", using:  node, _ in
        // we need to limit this to chickens only
        if let customNode = node as? CustomNodeEvents 
            customNode.didMoveToScene()
        
    )

这是检测碰撞的代码:

func didBegin(_ contact: SKPhysicsContact) 
    print("something happened")
    let collision = contact.bodyA.categoryBitMask |    contact.bodyB.categoryBitMask

    if collision == PhysicsCategory.Chicken | PhysicsCategory.Edge 
        print("it works!")
    

我想要动画的节点是鸡。我希望游戏能够检测到它们何时与上方世界的边缘发生碰撞。

我的鸡子类是这样的:

class TargetNode: SKSpriteNode, CustomNodeEvents, InteractiveNode 

func didMoveToScene() 
    isUserInteractionEnabled = true

    anchorPoint = CGPoint(x: 0, y: 0)
    let playableRect = CGRect(x: self.anchorPoint.x, y: self.anchorPoint.y, width: self.size.width, height: self.size.height)

    physicsBody = SKPhysicsBody(edgeLoopFrom: playableRect)
    physicsBody!.isDynamic = true
    physicsBody!.categoryBitMask = PhysicsCategory.Chicken
    physicsBody!.contactTestBitMask = PhysicsCategory.Edge | PhysicsCategory.Chicken
    physicsBody!.velocity = CGVector(dx: 100, dy: 0)


编辑:在游戏场景文件中使用此方法将节点添加到场景中。

func generateItems(targetNumber: Int, target: Bool) 
    let movingItems = true
    for _ in 0...(targetNumber - 1) 
        if (target) 
            let name = createTarget()
            let targetNode = TargetNode(imageNamed: name)
            targetNode.name = name
            fgNode.addChild(targetNode)
            targetNode.position = generateRandomLocation()
            //if movingItems  animateTargets(targetNode) 
       

【问题讨论】:

你在哪里添加节点到场景中? 我正在使用上面编辑中添加的函数生成一堆节点。 看起来边缘和小鸡都有由边缘循环构造的物理体。我认为这些不会发生冲突。 【参考方案1】:

将您的鸡设置为SKPhysicsBody(edgeLoopFrom :_) 是个坏主意。请尝试SKPhysicsBody(rectangleOf :_) 在您的鸡周围绘制一个矩形,您要绘制的形状类型可能会有所不同,请查看文档以获取更多信息。

此外,还要检查鸡与playableRect联系的天气

删除self.physicsBody!.contactTestBitMask = PhysicsCategory.Chicken,因为我们不想检查矩形是否与鸡接触,我们想知道鸡是否与可播放的矩形接触。所以把contactTestBitMask放在鸡上。

从您的鸡子类中删除:| PhysicsCategory.Chicken,除非您想检查鸡是否也相互碰撞。

最后:检查碰撞,如果小鸡与 playableRect 接触

  func didBegin(_ contact: SKPhysicsContact) 

    if contact.bodyA.categoryBitMask == PhysicsCategory.Chicken && contact.bodyB.categoryBitMask == PhysicsCategory.Edge 
       print("Chickens have collided with edge")
    

    

【讨论】:

谢谢。只是出于好奇,为什么改变 SKPhysicsBody 形状会改变什么? 那是因为基于边缘的物理实体无法与其他基于边缘的实体交互。我可以竖起大拇指吗? :)

以上是关于在子类节点中未检测到冲突的主要内容,如果未能解决你的问题,请参考以下文章

如何检测精灵节点上特定位置的 SKSpriteNode 之间的冲突?

在子类中未检测到 C++ 纯虚函数

CSMA/CD的基本原理

NSight Compute - 预期银行冲突但未检测到任何

未检测到 SkSpriteNode 冲突

XCode 4.5 警告父/子类的类别之间的方法名称冲突