我在我的播放器Class中为我的播放器制作了一个hitbox sprite。如何在gamescene的didBegin方法中访问该hitbox精灵?

时间:2017-07-12 23:46:39

标签: ios swift3 sprite-kit

这个“hitbox”的目的是让玩家只能在地面/平台上行走时跳跃。击球员比玩家更宽一点并且在玩家的脚上。这是我的玩家类:

class Player: SKSpriteNode {

  let maxPlayerSpeed:CGFloat = 300
  static var isPlayerOnGround = false



    init() {

        //players texture
        let texture = SKTexture(imageNamed: "playerMove1")

        super.init(texture: texture, color: SKColor.clear, size: texture.size())

        //hitbox that sits underneath the player and follows him
        let jumpHitBox = SKSpriteNode(color: .red, size: CGSize(width: texture.size().width - (texture.size().width / 8), height: texture.size().height / 5))

        jumpHitBox.position.y = (-texture.size().height) + (texture.size().height / 2)
        jumpHitBox.alpha = 0.5
        jumpHitBox.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: jumpHitBox.size.width,
                                                                   height: jumpHitBox.size.height))

        jumpHitBox.zPosition = 3
        jumpHitBox.physicsBody?.pinned = true
        jumpHitBox.physicsBody?.allowsRotation = false
        jumpHitBox.physicsBody?.categoryBitMask = CollisionTypes.playerJump.rawValue
        jumpHitBox.physicsBody?.collisionBitMask = 0
        jumpHitBox.physicsBody?.contactTestBitMask = CollisionTypes.ground.rawValue
        addChild(jumpHitBox)



        physicsBody = SKPhysicsBody(rectangleOf: size)
        physicsBody?.categoryBitMask = CollisionTypes.player.rawValue
        physicsBody?.contactTestBitMask = CollisionTypes.star.rawValue | CollisionTypes.saw.rawValue | CollisionTypes.finish.rawValue
        physicsBody?.collisionBitMask = CollisionTypes.ground.rawValue
        physicsBody?.affectedByGravity = true
        physicsBody?.restitution = 0.2
        physicsBody?.isDynamic = true
        physicsBody?.allowsRotation = false
        setScale(0.6)
        zPosition = 5
        physicsBody?.linearDamping = 0.0 }

required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder) //error here
        }

我想在此方法中使用jumpHitBox作为GameScene.swift中的另一个contact.bodyA / B节点:

func didBegin(_ contact: SKPhysicsContact) {

        if contact.bodyA.node == player {
           playerCollided(with: contact.bodyB.node!)


        } else if contact.bodyB.node == player {
           playerCollided(with: contact.bodyA.node!)

        }
    }

我不知道如何在GameScene.swift的didBegin中引用我的播放器类中的jumpHitBox子节点。

非常感谢任何建议。

编辑:我在

收到错误
required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder) //error here
    }

我没有把任何东西放在我的播放器类中但是因为将jumpHitBox精灵移动到全局声明我在所需的init中的super.init(coder:aDecoder)行中得到一个错误:属性'self.jumpHitBox'没有在super.init调用

初始化

3 个答案:

答案 0 :(得分:2)

从类外引用jumpHitBox的一种方法是将其作为Player类的属性,如同let jumpHitBox: SKSpriteNode中一样,就像你声明maxPlayerSpeed是Player类的属性一样。

如果您进行了此更改,请记住删除此行let中的let jumpHitBox = SKSpriteNode(color: .red ....,因为您现在只需要为其分配值,而不是声明它。您现在也应该将呼叫转移到此super.init之后。否则编译器会抱怨,即在调用super.init之前必须为类的所有属性赋值。

现在可以使用player.hitBox

在didBegin中访问jumpHitBox

希望这有帮助!

答案 1 :(得分:2)

虽然我会尝试使用注释中提到的更简单的velocity.dy方法,但问题是您的hitbox是在初始化程序的范围内声明的,因此您只能在那里访问它。如果为hitbox提供更高的范围,例如类属性,那么您可以在任何地方访问它:

class Player: SKSpriteNode {

  let maxPlayerSpeed:CGFloat = 300

  // This is probably going to cause you bugs later btw.. it should probably be
  // just a regular property:
  static var isPlayerOnGround = false

  // Now you can just call playerInstance.jumpHitBox :
  private(set) var jumpHitBox = SKSpriteNode()

  init() {

    //players texture
    let texture = SKTexture(imageNamed: "playerMove1")

    super.init(texture: texture, color: SKColor.clear, size: texture.size())
    jumpHitBox = SKSpriteNode(color: .red, size: CGSize(width: texture.size().width - (texture.size().width / 8), height: texture.size().height / 5))
    //hitbox that sits underneath the player and follows him
  }
}

更新:

class Player: SKSpriteNode {

  let maxPlayerSpeed:CGFloat = 300

  // This is probably going to cause you bugs later btw.. it should probably be
  // just a regular property:
  static var isPlayerOnGround = false

  // Now you can just call playerInstance.jumpHitBox :
  var jumpHitBox = SKSpriteNode()

  private func makeHitBox() -> SKSpriteNode {
    let texture = SKTexture(imageNamed: "playerMove1")

    //hitbox that sits underneath the player and follows him
    let localJumpHitBox = SKSpriteNode(color: .red, size: CGSize(width: texture.size().width - (texture.size().width / 8), height: texture.size().height / 5))

    localJumpHitBox.position.y = (-texture.size().height) + (texture.size().height / 2)
    localJumpHitBox.alpha = 0.5
    localJumpHitBox.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: localJumpHitBox.size.width,
                                                                    height: localJumpHitBox.size.height))

    localJumpHitBox.zPosition = 3
    localJumpHitBox.physicsBody?.pinned = true
    localJumpHitBox.physicsBody?.allowsRotation = false
    localJumpHitBox.physicsBody?.categoryBitMask = CollisionTypes.playerJump.rawValue
    localJumpHitBox.physicsBody?.collisionBitMask = 0
    localJumpHitBox.physicsBody?.contactTestBitMask = CollisionTypes.ground.rawValue

    return localJumpHitBox
  }

  init() {

    //players texture
    let texture = SKTexture(imageNamed: "playerMove1")

    super.init(texture: texture, color: SKColor.clear, size: texture.size())

    physicsBody = SKPhysicsBody(rectangleOf: size)
    physicsBody?.categoryBitMask = CollisionTypes.player.rawValue
    physicsBody?.contactTestBitMask = CollisionTypes.star.rawValue | CollisionTypes.saw.rawValue | CollisionTypes.finish.rawValue
    physicsBody?.collisionBitMask = CollisionTypes.ground.rawValue
    physicsBody?.affectedByGravity = true
    physicsBody?.restitution = 0.2
    physicsBody?.isDynamic = true
    physicsBody?.allowsRotation = false
    setScale(0.6)
    zPosition = 5
    physicsBody?.linearDamping = 0.0
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder) //error here
    jumpHitBox = makeHitBox()
    addChild(jumpHitBox)
  }
}

答案 2 :(得分:0)

这是一个次要答案,显示了解决问题的不同方法。注意,玩家只能在地面上跳跃。这使用"延迟帧"或"跳帧"或者你想要把它,因为跳转命令(pb.applyImpulse)只被称为╔════════╦══════════════════╦═══════╦═══════╗ ║ client ║ id ║ zstd ║ 40.59 ║ ║ client ║ clientid ║ delta ║ 0.00 ║ ║ client ║ createdon ║ zstd ║ 19.85 ║ ║ client ║ updatedon ║ zstd ║ 12.59 ║ ║ client ║ deletedon ║ raw ║ 0.00 ║ ║ client ║ lockversion ║ zstd ║ 39.12 ║ ║ client ║ regionid ║ zstd ║ 54.47 ║ ║ client ║ officeid ║ zstd ║ 88.84 ║ ║ client ║ countryid ║ zstd ║ 79.13 ║ ║ client ║ firstcontactdate ║ zstd ║ 22.31 ║ ║ client ║ didexistprecirts ║ raw ║ 0.00 ║ ║ client ║ isactive ║ raw ║ 0.00 ║ ║ client ║ statusreason ║ raw ║ 0.00 ║ ║ client ║ createdbyid ║ zstd ║ 52.43 ║ ║ client ║ islocked ║ raw ║ 0.00 ║ ║ client ║ locktype ║ zstd ║ 63.01 ║ ║ client ║ keyworker ║ zstd ║ 38.79 ║ ║ client ║ inactivedate ║ zstd ║ 25.40 ║ ║ client ║ current_flag ║ zstd ║ 90.51 ║ ╚════════╩══════════════════╩═══════╩═══════╝ 里面的 ,这意味着该角色实际上不会更高,直到下一个帧。

didSimulatePhysics