1

我正在尝试创建一个类似于 House Stack 的游戏(https://apps.apple.com/gb/app/house-stack/id1458713825?l)但在分配物理机制时遇到问题。

我的主要问题是当节点下降并与其他人接触时创建一个对象,并在它们达到特定高度时将它们以固体形式向下移动。

我试图创建节点之间接触的固定关节,并在最后一个节点位置 y = 0 时移动它们,但固定关节没有像我想的那样工作。节点像蛇一样摇晃并在移动时崩溃。

还尝试使用接触创建一个新的单个对象并计算其高度,但无法弄清楚我应该如何使用 init(body:[SKPhysicsBody])。即使我将物理体属性分配给新对象,我也无法测量或调用它的高度并使用另一个节点联系人更新身体。

任何想法或例子都会很好。这是我的代码,在此先感谢。

SKNode(内部touchesBegan多次创建同一个节点):

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let Node1 = SKSpriteNode(imageNamed: "Object1")
        Node1.position = MovingObject.position
        Node1.zPosition = 2
        Node1.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: Node1.size.width, height: Node1.size.height))
        Node1.physicsBody?.friction = 0.9
        Node1.physicsBody?.restitution = 0.1
        Node1.physicsBody?.allowsRotation = true
        Node1.physicsBody!.contactTestBitMask = Node1.physicsBody!.collisionBitMask
        Node1.physicsBody!.categoryBitMask = Node1Category
        addChild(Node1)
    }

移动对象:

Inside GameScene;
var MovingObject = SKSpriteNode(imageNamed: "Object1")
let ObjectMove = SKAction.sequence([(SKAction.moveBy(x: 200, y: 0, duration: 0.5)),(SKAction.moveBy(x: -400, y: 0, duration: 1)),(SKAction.moveBy(x: 200, y: 0,  duration: 0.5))])

Inside override func didMove(to view: SKView);
        MovingObject.position = CGPoint(x: 0, y: frame.maxY * 0.55)
        MovingObject.zPosition = 1
        MovingObject.run(SKAction.repeatForever(ObjectMove))
        addChild(MovingObject)

关节和动作:

func didBegin(_ contact: SKPhysicsContact) {
if contact.bodyA.node?.name == "Node1" && contact.bodyB.node?.name == "Node1"
        {
            let joint2 = SKPhysicsJointFixed.joint(withBodyA: contact.bodyA , bodyB: contact.bodyB, anchor: CGPoint(x: contact.contactPoint.x, y:contact.contactPoint.y))
            
            let pos2 = (contact.bodyA.node?.position.x)!-(contact.bodyB.node?.position.x)!

            if pos2 <= Node1.size.width * 0.5 && pos2 >= -Node1.size.width * 0.5{
                physicsWorld.add(joint2)
            }

            if (contact.bodyB.node?.position.y)! >= 0 {
                let movenodedown = SKAction.moveBy(x: 0, y: -Node1.size.height, duration: 0.5)
                contact.bodyB.node?.run(movenodedown)
                ground.run(movenodedown)     
            }   
        }
4

1 回答 1

1

对于那些需要对类似问题有所启发的人;

我通过使用enumerateChildNodes(withName:using:)and physicsBody.isDynamic = falsetogether 而不是固定关节找到了我的解决方案。代码如下。

func didBegin(_ contact: SKPhysicsContact)
    {
if contact.bodyA.node?.name == "Node1" && contact.bodyB.node?.name == "Node1"
        {
let pos2 = (contact.bodyA.node?.position.x)!-(contact.bodyB.node?.position.x)!

            if pos2 <= Node1.size.width * 0.5 && pos2 >= -Node1.size.width * 0.5.
            {
                contact.bodyB.node?.physicsBody?.isDynamic = false
                contact.bodyA.node?.physicsBody?.collisionBitMask = 0
                contact.bodyA.node?.physicsBody?.contactTestBitMask = 0
                
                if (contact.bodyB.node?.position.y)! >= 0
                {
                    let movenodesdown = SKAction.moveBy(x: 0, y: Node1.size.height , duration: 0.5)

                    enumerateChildNodes(withName: "Node1") { (nodes, stop) in
                        let Node1 = nodes as! SKSpriteNode
                        Node1.run(movenodesdown)
                    }
                }
            }
        }
    }
于 2020-06-29T19:58:52.323 回答