iOS SpriteKit-碰撞和联系无法按预期工作 [英] iOS SpriteKit - collisions and contacts not working as expected

查看:83
本文介绍了iOS SpriteKit-碰撞和联系无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时候,在我的SpriteKit程序中,我的碰撞和接触(使用SKPhysicsBody)没有按预期方式触发或起作用。我想我已经设置了所需的一切,但仍无法获得正确的交互。


我是否可以编写一些代码来检查什么与什么以及什么物体相撞?设置生成联系人?

解决方案

为帮助诊断这些类型的问题,我编写了一个可以在任何地方调用的函数并且将分析当前场景并生成列表,列出将通知与哪些节点发生碰撞的其他节点以及发生碰撞的事件。



该函数是独立的



函数如下:

  //标记:-分析碰撞/接触设置。 
func checkPhysics(){

//使用PhysicalBodies
创建所有节点的数组var physicsNodes = [SKNode]()

//获取所有物理实体
enumerateChildNodesWithName( //。){节点,如果$ _ = node.physicsBody {
PhysicalNodes.append(node)
}其他{
print( \(node.name)没有物理物体,因此不能碰撞或参与接触。)
}
}

/ /对于每个节点,对照其他节点的伸缩和检查其类别,测试PhysicalNodes中节点的位掩码
{
let category = node.physicsBody!.categoryBitMask
//通过节点标识节点如果名称为空,则分类
let name = node.name!= nil吗? node.name:类别\(类别)
let crashMask = node.physicsBody!.collisionBitMask
let contactMask = node.physicsBody!.contactTestBitMask

//如果全部collisonmask集的一部分,只说它与所有内容发生碰撞。
,如果collisionMask == UInt32.max {
print( \(name)碰撞一切))
}

for PhysicalNodes中的otherNode {
if(节点!= otherNode)&& (node.physicsBody?.dynamic == true){
let otherCategory = otherNode.physicsBody!.categoryBitMask
//如果名称为空,则按其类别标识节点
let otherName = otherNode .name!=无otherNode.name: Category \(otherCategory)

//如果collisonmask和类别匹配,如果((collisionMask& otherCategory)!= 0)& & (collisionMask!= UInt32.max){
print( \(name)与\(otherName)相撞))
}
//如果contactMAsk和category匹配,它们将contact
if(contactMask& otherCategory)!= 0 {print( \(name)在联系\(otherName)时通知)}
}
}
}
}

您还需要检查以下三件事:


  1. 场景必须 SKPhysicsContactDelegate

  2. 您必须设置 physicsWorld.contactDelegate = self

  3. 您需要实现
    <$的一种可选方法c $ c> SKPhysicsContactDelegate :

didBeginContact



didEndcontact



设置完所有图片后应调用该函数-通常在 didMoveToView 作品:

  checkPhysics()

当我在练习Swift项目的 didMoveToView 的末尾调用此函数时,得到以下输出:


Optional( shape_blueSquare)与Optional( Category
2147483648)Optional( shape_blueSquare)与
碰撞Optional( shape_redCircle )Optional( shape_blueSquare)与
碰撞Optional( shape_purpleSquare)Optional( shape_blueSquare)与
与Optional( shape_yellowTriangle)碰撞Optional( shape_redCircle)
与Optional碰撞(类别2147483648)
Optional( shape_redCircle)与Optional( shape_blueSquare)
Optional( shape_redCircle)在与
联系时通知Optional( shape_purpleSquare)Optional( shape_redCircle)与
碰撞Optional( shape_yellowTriangle)Optional( shape_redCircle)
在联系Optional( shape_yellowTriangle)时发出通知
Optional( shape_purpleSquare)与Optional( Category
2147483648)碰撞(可选) shape_purpleSquare)与
碰撞。Optional( shape_yellowTriangle)Optional( shape_yellowTriangle) b与为
输入的所有内容didBeginContact冲突Optional( shape_purpleSquare)和Optional( shape_redCircle)
didBeginContact为Optional( shape_purpleSquare)和
Optional( shape_redCircle)didBeginContact输入为
Optional( shape_yellowTriangle)和Optional( shape_redCircle)


类别2147483648是我的边界,它确实没有名字。我给了这个类别以匹配它的crashBitMask



请随时尝试使用此功能,让我知道它是否有用或是否有任何情况不能解决。 / p>

Sometimes in my SpriteKit programs, my collisions and contacts (using SKPhysicsBody) don't trigger or work as expected. I think I have set up everything I need, but I am still not getting the right interactions.

Is there some code I can write that will check what will collide with what and what bodies are set up to generate contacts?

解决方案

To help diagnose these types of problems, I have written a function that can be called from anywhere and which will analyse the current scene and produce a list of what nodes with collide with which others and which collisions my scene will be notified for.

The function is stand-alone and does not need to be told anything about the nodes in the scene.

The function is as follows:

            //MARK: - Analyse the collision/contact set up.
    func checkPhysics() {

        // Create an array of all the nodes with physicsBodies
        var physicsNodes = [SKNode]()

        //Get all physics bodies
        enumerateChildNodesWithName("//.") { node, _ in
            if let _ = node.physicsBody {
                physicsNodes.append(node)
            } else {
                print("\(node.name) does not have a physics body so cannot collide or be involved in contacts.")
            }
        }

//For each node, check it's category against every other node's collion and contctTest bit mask
        for node in physicsNodes {
            let category = node.physicsBody!.categoryBitMask
            // Identify the node by its category if the name is blank
            let name = node.name != nil ? node.name : "Category \(category)"
            let collisionMask = node.physicsBody!.collisionBitMask
            let contactMask = node.physicsBody!.contactTestBitMask

            // If all bits of the collisonmask set, just say it collides with everything.
            if collisionMask == UInt32.max {
                print("\(name) collides with everything")
            }

            for otherNode in physicsNodes {
                if (node != otherNode) && (node.physicsBody?.dynamic == true) {
                    let otherCategory = otherNode.physicsBody!.categoryBitMask
                    // Identify the node by its category if the name is blank
                    let otherName = otherNode.name != nil ? otherNode.name : "Category \(otherCategory)"

                    // If the collisonmask and category match, they will collide
                    if ((collisionMask & otherCategory) != 0) && (collisionMask != UInt32.max) {
                        print("\(name) collides with \(otherName)")
                    }
                    // If the contactMAsk and category match, they will contact
                    if (contactMask & otherCategory) != 0 {print("\(name) notifies when contacting \(otherName)")}
                }
            }
        }  
    }

You also need to check these 3 things:

  1. the scene must be a SKPhysicsContactDelegate
  2. You must set physicsWorld.contactDelegate = self
  3. You need to implement one of the optional methods of SKPhysicsContactDelegate:

didBeginContact

didEndcontact

The function should be called once you have set up all of your pics - usually at the end of didMoveToView works:

checkPhysics()

When I call this function from the end of my didMoveToView in my practice Swift project, I get the following output:

Optional("shape_blueSquare") collides with Optional("Category 2147483648") Optional("shape_blueSquare") collides with Optional("shape_redCircle") Optional("shape_blueSquare") collides with Optional("shape_purpleSquare") Optional("shape_blueSquare") collides with Optional("shape_yellowTriangle") Optional("shape_redCircle") collides with Optional("Category 2147483648") Optional("shape_redCircle") collides with Optional("shape_blueSquare") Optional("shape_redCircle") notifies when contacting Optional("shape_purpleSquare") Optional("shape_redCircle") collides with Optional("shape_yellowTriangle") Optional("shape_redCircle") notifies when contacting Optional("shape_yellowTriangle") Optional("shape_purpleSquare") collides with Optional("Category 2147483648") Optional("shape_purpleSquare") collides with Optional("shape_yellowTriangle") Optional("shape_yellowTriangle") collides with everything didBeginContact entered for Optional("shape_purpleSquare") and Optional("shape_redCircle") didBeginContact entered for Optional("shape_purpleSquare") and Optional("shape_redCircle") didBeginContact entered for Optional("shape_yellowTriangle") and Optional("shape_redCircle")

Category 2147483648 is my edge boundary and it does not have a name. I gave it this category to match its collisionBitMask

Please feel free to try this function and let me know if it's useful or if there are any situations it does not handle.

这篇关于iOS SpriteKit-碰撞和联系无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆