I am making a simple platform game using SpriteKit. The game is detecting when the player hits the ground with func didBegin, but for some reason the boolean playerTouchingGround(in my Player class) is not changing to true. I initialized the var playerTouchingGround to true and the player can jump once, but it cannot jump again. The output console prints "hit ground; left ground; hit ground". I don't understand what I am doing wrong. I am probably over looking something simple.
Here is my GameScene code
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())
}
}
Here is my Player class code
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
}
}
}
Here is my Ground class code
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
}
}