【问题标题】:How to create multiple node characters in sprite kit /SKphysics joint?如何在 sprite kit /SKphysics 关节中创建多个节点角色?
【发布时间】:2016-07-08 21:31:59
【问题描述】:

我正在创建一个游戏,对于我的角色,他的腿和躯干具有独立的动画,因此它们是具有独立物理体的独立节点。我在将躯干和腿连接在一起时遇到了很多麻烦,但是连接它们不是问题,保持它们连接是问题。在四处走动时,有时英雄的躯干会从腿上滑落。有点有趣但不实用,哈哈。这是我的物理编码

enum BodyType:UInt32 {

case bullet1 = 2

case enemy1 =  4
case enemy2 =  16
case enemy3 =  32

case desertForegroundCase = 64

case tank11 =  128
case tank12 =  256
case tank13 =  512

case tank21 =  1024
case tank22 =  2048
case tank23 =  4056

case tank31 =  8112
case tank32 =  16224
case tank33 =  32448

case cliff1 =  64856
case cliff2 =  129212

case soldierT = 258424
case soldierL = 516848

static let ground: UInt32 = 1
}
     func CreateScene (){

    desertBackground.position = CGPoint(x: frame.size.width / 2, y: 
    frame.size.height / 2)
    desertBackground.size = CGSize (width: 1136, height: 640)
    desertBackground.zPosition = -5
    desertForegroundImage.position = CGPointMake(568, 100)
    desertForegroundImage.zPosition = -1
    let desertForeground = SKSpriteNode(texture: 
    desertForegroundTexture, size:CGSize(width: 1136, height: 200))
        desertForeground.position = CGPointMake(568, 100)
    let desertForegroundBody = SKPhysicsBody(texture: 
    desertForegroundTexture, size: CGSize(width: 1136, height: 200))
    desertForegroundBody.dynamic = false
    desertForegroundBody.affectedByGravity = false
    desertForegroundBody.allowsRotation = false
    desertForegroundBody.categoryBitMask = BodyType.ground
    desertForegroundBody.contactTestBitMask = BodyType.enemy1.rawValue 
    | BodyType.enemy2.rawValue | BodyType.enemy3.rawValue  | 
    BodyType.soldierL.rawValue | BodyType.soldierT.rawValue
    desertForeground.physicsBody = desertForegroundBody
    desertForeground.zPosition = -1

    self.addChild(desertForegroundImage)
    self.addChild(desertForeground)
    self.addChild(desert gully)

    }
   func CreateHero (){

    soldierLegs.position = CGPoint(x: 405 , y: 139)
    soldierLegs.zPosition = 1
    soldierLegs.anchorPoint.x = 0.6
    soldierLegs.anchorPoint.y = 0.7

    let soldierLegsBody:SKPhysicsBody = SKPhysicsBody(rectangleOfSize: 
    soldierLegs.size)
    soldierLegsBody.dynamic = true
    soldierLegsBody.affectedByGravity = true
    soldierLegsBody.allowsRotation = false
    //body.restitution = 0.4
    soldierLegsBody.categoryBitMask = BodyType.soldierL.rawValue
    soldierLegsBody.contactTestBitMask = BodyType.enemy1.rawValue | 
    BodyType.enemy2.rawValue | BodyType.enemy3.rawValue  | 
    BodyType.desertForegroundCase.rawValue
    soldierLegs.physicsBody = soldierLegsBody

    soldierTorso.position = soldierLegs.position
    soldierTorso.zPosition = 2
    soldierTorso.anchorPoint.x = 0.25
    soldierTorso.anchorPoint.y = 0.1

    let soldierTorsoBody:SKPhysicsBody = SKPhysicsBody(rectangleOfSize: 
    soldierTorso.size)
    soldierTorsoBody.dynamic = true
    soldierTorsoBody.affectedByGravity = true
    soldierTorsoBody.allowsRotation = false
    soldierTorsoBody.categoryBitMask = BodyType.soldierT.rawValue
    soldierTorsoBody.contactTestBitMask = BodyType.enemy1.rawValue | 
    BodyType.enemy2.rawValue | BodyType.enemy3.rawValue  | 
    BodyType.desertForegroundCase.rawValue
    soldierTorso.physicsBody = soldierTorsoBody
    let joint  = 
    SKPhysicsJointFixed.jointWithBodyA(soldierLegs.physicsBody!, bodyB: 
    soldierTorso.physicsBody!, anchor: soldierLegs.position)

    soldierLegsBody.collisionBitMask = BodyType.ground
    soldierTorsoBody.collisionBitMask = BodyType.ground

    self.addChild(soldierTorso)
    self.addChild(soldierLegs)
    self.physicsWorld.addJoint(joint)

}

这就是他会滑落多远。有没有办法只用 2 个独立的节点编写一个物理体?还是我只是缺少一些代码?任何帮助都是帮助,谢谢。

【问题讨论】:

    标签: sprite-kit nodes game-physics skphysicsbody


    【解决方案1】:

    问题是两个物理物体会相互碰撞,因为你将动态设置为 true,它们会移动,你可以将动态设置为 false 或

    在 BodyType Struct 中添加一个新常量,如下所示:

    static let none: UInt32 = 0
    

    然后你可以将这段代码添加到物理体中

    soldierLegsBody.collisionBitMask = BodyType.none
    soldierTorsoBody.collisionBitMask = BodyType.none
    

    或者,如果您需要士兵从地面弹起,您将需要为地面创建一个新的身体类型,如下所示:

     static let ground: UInt32 = <  A Number >
    

    然后您可以将碰撞位掩码设置为 BodyType.ground。

    希望这会有所帮助!如果您有任何问题,请发表评论:)

    【讨论】:

    • 接触位掩码和碰撞位掩码有什么区别?我应该摆脱接触位掩码吗?还是我应该同时拥有它们?因为没有在碰撞位掩码中输入地面,角色只是从地图上掉下来,所以如果我只需要复制我的联系人位掩码中的所有信息并将其放入我的碰撞位掩码@Loanb222,我为什么要同时拥有两者跨度>
    • 碰撞位掩码告诉节点发生碰撞,因此玩家不会从地面坠落,并且 didBeginContact 函数不会使用碰撞位掩码运行。
    • 我没有提到 didBeginContact,我说的是我的代码中的联系人位掩码。当我设置士兵LegsBody.collisionBitMask = BodyType.none 时,腿开始穿过我之前没有的其他物理边界,这是为什么?
    • 您可能希望为地面创建一个 BodyType 并将碰撞位掩码设置为地面。玩家正在从地面坠落,因为您说您不希望玩家与任何东西发生碰撞。假设你想在玩家接触敌人时结束游戏,你会希望保持接触位掩码不变。
    • 我真的希望你的建议能奏效,哈哈,但事实并非如此,我不能将动态值设置为 false,因为这样躯干就不会受到重力的影响。我在碰撞位掩码中创建了地面,但这仍然不会影响躯干和腿的分离。还有其他想法吗?大声笑@loanb222
    【解决方案2】:

    我想通了,在声明物理联合之后

    let joint = 
    SKPhysicsJointFixed.jointWithBodyA(soldierLegs.physicsBody!, 
    bodyB:soldierTorso.physicsBody!, anchor: soldierLegs.position)
    

    通过

    将关节的动态值的第二个节点声明为false
        joint.bodyB.dynamic = false
    

    然后使用更新函数重新定位节点

     override func update(currentTime: CFTimeInterval) {
    
       soldierTorso.position = soldierLegs.position
    
    }
    

    每秒将额外节点定位 60 次应该确保节点不会移动,或者为了获得更高的帧速率或更顺畅的运行,我确定每秒定位它 5 到 20 次就可以了,但是每定位躯干 60 次秒对我来说并没有降低任何帧速率

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      相关资源
      最近更新 更多