【问题标题】:What SpriteKit physics properties are needed for stacking and balancing type game堆叠和平衡类型游戏需要哪些 SpriteKit 物理属性
【发布时间】:2017-02-21 23:47:25
【问题描述】:

我正在尝试制作一款游戏,您可以通过左右移动平台来控制平台,同时尝试平衡平台上的坠落物体。然而,平台的移动似乎独立于落在它上面的物品。例如,如果一个块落在我的平台顶部,当我向左或向右移动平台时,块保持不动,只有平台在它下面移动。这使得无法堆叠任何东西,因为块不随平台移动。我不确定我需要使用哪些 SpriteKit 物理属性来模拟平衡。当块与平台碰撞时,我尝试调整恢复弹性,并尝试调整摩擦属性以查看是否有助于块“粘”在平台上,但这似乎也无济于事。

我的平台不是动态的,所以我尝试设置

platform.physicsBody!.isDynamic = true
platform.physicsBody!.affectedByGravity = false
platform.physicsBody!.allowsRotation = false

这似乎有帮助?但是当它与我不能拥有的块碰撞时,平台仍然会移动。

编辑:

这就是我移动平台的方式。用户通过用手指拖动来移动平台父级。由于这会移动平台父级,因此平台也会随之移动。

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
         if let touch = touches.first {
              let location = touch.locationInNode(self)
              platformParent.position.x = location.x
         }
    }

【问题讨论】:

  • 试试这个——一旦落下的方块最终落定,让它成为平台的孩子。然后它应该与平台一起移动,但仍会受到其他块落在平台顶部的影响。或者,如果它固定在平台上时被“卡住”,请使用 SKPhysicsJoint 将其固定到位。

标签: swift sprite-kit skphysicsbody


【解决方案1】:

你需要让平台动态化,所以你需要解决的是如何保持它就位。根据您的用例,有许多正确的选项。试试看这些:

  • 创建位置约束:SKConstraint.positionY
  • 在平台和实体参考对象之间创建滑动关节:SKPhysicsJointSliding
  • 相对于落在其上的物体显着增加平台的质量
  • 更正平台的位置,手动调整每个框架(如果质量允许它保持相对静止,则有帮助)或使用弹簧接头之类的东西

【讨论】:

    【解决方案2】:

    摩擦将防止积木从平台或其他积木上滑落(堆叠时)。当物理物体的friction 系数属性不为零、存在法向力(在这种情况下 F = 质量 x 重力)并且至少有一个物体被移动时,就会发生摩擦一个力或设置它的速度属性。如果您使用moveTomoveBy 操作移动平台或块,摩擦将不起作用。以下是如何在 SpriteKit 中使用摩擦的示例实现。

    首先,设置世界的重力属性。这是默认设置。

    physicsWorld.gravity = CGVector(dx:0, dy:-9.8) 
    

    然后,设置平台的摩擦系数。对每个块执行相同的操作。

    platform.physicsBody?.friction = 1.0
    

    设置块的质量属性以限制它们的重量。

    block.physicsBody?.mass = 0.0001
    

    约束平台以防止其因积木的重量而垂直移动。

    let range = SKRange(constantValue: -self.size.height * 0.45)
    let constraint = SKConstraint.positionY(range)
    
    platform.constraints = [constraint]
    

    最后,使用物理学将平台左右移动:

    var moveTo:CGPoint?
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let point = touch.location(in:self)
            moveTo = point
        }
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let point = touch.location(in:self)
            moveTo = point
        }
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        moveTo = nil
        platform.physicsBody?.velocity = CGVector.zero
    }
    
    override func update(_ currentTime: TimeInterval) {
        if let moveTo = moveTo {
            let dx = moveTo.x - platform.position.x
            let vector = CGVector(dx: 2*dx, dy: 0)
            platform.physicsBody?.velocity = vector
        }
    }
    

    【讨论】:

    • 我不确定我是否了解范围限制,因为它是负数,您的范围不会不在屏幕上吗?此外,我的平台的锚点似乎保持在恒定的 Y 值,但是当块撞击它时它仍然倾斜(围绕其锚点旋转)。最后一件事,我的平台是父级的子级,我通过更改 touchesMoved 上的 x 位置来移动父级,因此平台随之移动。这会奏效吗?很抱歉回复晚了,感谢您提供如此详细的答复。
    • 我编辑了我如何移动平台的问题。
    • 在Xcode 8中,默认场景的锚点是视图的中心,所以场景的上半部分为正,下半部分为负。为防止平台旋转,设置platform.physicsBody?.allowsRotation = false。此外,如果您通过直接更改其x 位置来移动平台,则平台将无法与场景中的其他实体正确交互。您需要通过向其主体施加力或设置主体的速度属性来移动平台。
    • 我的平台由于移动它的父级而移动,通过对其身体施加力或设置它的速度来移动父级是否也会对子级(平台)做同样的事情?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多