你如何让sprite只在swift的地面上跳跃?

时间:2017-09-19 19:49:39

标签: ios swift sprite-kit

我正在使用SpriteKit制作一个简单的平台游戏。游戏正在检测玩家何时使用func didBegin击中地面,但由于某种原因,布尔playerTouchingGround(在我的Player类中)没有变为true。我将var playerTouchingGround初始化为true,玩家可以跳一次,但不能再跳。输出控制台打印“击中地面;左侧地面;击中地面”。我不明白我做错了什么。我可能看起来很简单。

这是我的GameScene代码

import SpriteKit
import GameplayKit

class GameScene: SKScene{

let player: Player!
let ground: Ground!
let controller: ControllerNode!

let contactManager = Player()


// MARK: - Init


override init(size: CGSize) {

    player = Player()
    ground = Ground(size: size)
    controller = ControllerNode(position: CGPoint(x:0, y: 0))

    super.init(size: size)

    self.physicsWorld.contactDelegate = contactManager

    setup()

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}



// MARK: - Setup

func setup() {


    // Background Color
    self.backgroundColor = UIColor.white


    // Adding Player
    addChild(player)
    player.position.x = size.width/2
    player.position.y = size.height/2


    // Adding Ground
    addChild(ground)
    ground.position.x = size.width/2
    ground.position.y = size.height/4


    // Adding ControllerNode
    addChild(controller)

}


override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
    player.movement(directions: self.controller!.pressedDirections())

}
}

这是我的播放器类代码

import SpriteKit
enum CharacterMovement : Int {

case Up
case Right
case Down
case Left

}

enum ColliderType: UInt32 {

case player = 1
case ground = 2
}

class Player: SKSpriteNode, SKPhysicsContactDelegate {


var tick = 0


var currentMovement: CharacterMovement?


var lastMovement: CharacterMovement?


var contactMask: Int = 0

var playerTouchingGround = true

// MARK: - Init

init() {



    let playerSize = CGSize(width: 30, height: 60)

    super.init(texture: nil, color: UIColor.cyan, size: playerSize)

    lastMovement = .Right

    self.zPosition = 10

    setup()

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


// MARK: - Setup

func setup() {


    physicsBody = SKPhysicsBody(rectangleOf: size)
    physicsBody?.usesPreciseCollisionDetection = true
    physicsBody?.categoryBitMask = ColliderType.player.rawValue
    physicsBody?.collisionBitMask = ColliderType.ground.rawValue
    physicsBody?.contactTestBitMask = ColliderType.ground.rawValue
    physicsBody?.allowsRotation = false
    physicsBody?.restitution = 0
    physicsBody?.isDynamic = true

}

func didBegin(_ contact: SKPhysicsContact) {

    print("hit ground")
    playerTouchingGround = true


}




func movement(directions: [ControllerInput]) {



    // if (directions.index(of: .Up) != nil) && (touchingGround == true){

    if (directions.index(of: .Up) != nil) && (playerTouchingGround) {


        physicsBody?.applyImpulse(CGVector(dx: 0, dy: 30))
        playerTouchingGround = false
        currentMovement = .Up
        print("left ground")
    }

    if directions.index(of: .Right) != nil {

        physicsBody?.applyImpulse(CGVector(dx: 1, dy: 0))
        currentMovement = .Right
    }

    if directions.index(of: .Left) != nil {

        physicsBody?.applyImpulse(CGVector(dx: -1, dy: 0))
        currentMovement = .Left
    }

    if currentMovement != nil {
        lastMovement = currentMovement
    }

    if !directions.isEmpty && self.currentMovement != nil {
        // Player Animations
    }
    else {
        currentMovement = nil
    }

    tick += 1
    if tick > 60 {
        tick = 0
    }

}

}

这是我的Ground类代码

import SpriteKit

class Ground: SKSpriteNode {


// MARK: - Init

init(size: CGSize) {

    let groundSize = CGSize(width: size.width, height: 20)

    super.init(texture: nil, color: UIColor.black, size: groundSize)

    setup()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


// MARK: - Setup

func setup() {

    physicsBody = SKPhysicsBody(rectangleOf: size)
    physicsBody?.categoryBitMask = ColliderType.ground.rawValue
    physicsBody?.usesPreciseCollisionDetection = true
    physicsBody?.isDynamic = false
    physicsBody?.restitution = 0
    physicsBody?.categoryBitMask = ColliderType.ground.rawValue
    physicsBody?.collisionBitMask = ColliderType.player.rawValue
    physicsBody?.contactTestBitMask = ColliderType.player.rawValue

}
}

1 个答案:

答案 0 :(得分:1)

您的问题是您正在创建多个Player对象。

每次拨打Player()时,您都会创建一个全新的播放器。

这意味着contactManagerplayer不是同一个实例

let contactManager = Player()  //<---Alright a player


// MARK: - Init


override init(size: CGSize) {

    player = Player()// <-----Uh oh, a new player, need to fix this
    ground = Ground(size: size)
    controller = ControllerNode(position: CGPoint(x:0, y: 0))

    super.init(size: size)

    self.physicsWorld.contactDelegate = contactManager

    setup()

}