My goal is to set up all my platforms in the .sks file for easier design of my levels.
this is declared at the top of game scene.swift before didMove:
private var JumpThroughPlatformObject = SKSpriteNode()
and this is in DidMove:
if let JumpThroughPlatformObjectNode = self.childNode(withName: "//jumpThroughPlatform1") as? SKSpriteNode {
JumpThroughPlatformObject = JumpThroughPlatformObjectNode}
I reference the platform to get it's height from the .sks, since all my platforms are going to be the same height I only need to get it from one.
Below is what Im trying to use in my update method to turn off collisions until my player is totally above the platform. The main issue with only checking if my players velocity is greater than zero is: if the player is at the peak of a jump (his velocity slows to zero). if this happens and the player is inside a platform, he either instantly springs up to the top of the platform or gets launched downward.
I don't want my platforms to have to be 1 pixel high lines. I also need to have the player have a full collision box since he will be interacting with other types of environments. This leads me to believe that I somehow need to only register the top of the platform as a collision box and not the entire platform.
This if statement I wrote is supposed to take the y position of a platform and add half of its height to it, since the y position is based on the center of the sprite I figured this would put the collision for the platform on its top boundary.
I did the same for the player but in reverse. Putting the players collisions on only the bottom of his border. But its not working perfectly and I'm not sure why at this point.
if (JumpThroughPlatformObject.position.y + (JumpThroughPlatformObject.size.height / 2)) > (player.position.y - (player.size.height / 2))
The function below is giving me 3 main issues:
My players jump is always dy = 80. If I'm jumping up to a platform that position.y = 90, the players peak of the jump stops in the middle of the platform, but he teleports to the top of it instead of continuing to fall to the ground.
the left and right edges of the platforms still have full collision with the player if I'm falling
if my player is on a platform and there is another one directly above me, the player can't jump through it.
let zero:CGFloat = 0
if let body = player.physicsBody { let dy = player.physicsBody?.velocity.dy // when I jump dy is greater than zero else I'm falling if (dy! >= zero) { if (JumpThroughPlatformObject.position.y + (JumpThroughPlatformObject.size.height / 2)) > (player.position.y - (player.size.height / 2)) { print(" platform y: \(JumpThroughPlatformObject.position.y)") print ("player position: \(player.position.y)") // Prevent collisions if the hero is jumping body.collisionBitMask = CollisionTypes.saw.rawValue | CollisionTypes.ground.rawValue } } else { // Allow collisions if the hero is falling body.collisionBitMask = CollisionTypes.platform.rawValue | CollisionTypes.ground.rawValue | CollisionTypes.saw.rawValue } }
Any advice would be greatly appreciated. I've been tearing my hair out for a couple days now.
EDIT in didBegin and didEnd:
func didBegin(_ contact: SKPhysicsContact) {
if let body = player.physicsBody {
let dy = player.physicsBody?.velocity.dy
let platform = JumpThroughPlatformObject
let zero:CGFloat = 0
if contact.bodyA.node == player {
// playerCollided(with: contact.bodyB.node!)
if (dy! > zero || body.node!.intersects(platform)) && ((body.node?.position.y)! - player.size.height / 2 < platform.position.y + platform.size.height / 2) {
body.collisionBitMask &= ~CollisionTypes.platform.rawValue
}
} else if contact.bodyB.node == player {
// playerCollided(with: contact.bodyA.node!)
isPlayerOnGround = true
if (dy! > zero || body.node!.intersects(platform)) && ((body.node?.position.y)! - player.size.height / 2 < platform.position.y + platform.size.height / 2) {
body.collisionBitMask &= ~CollisionTypes.platform.rawValue}
}
}
}
func didEnd(_ contact: SKPhysicsContact) {
if let body = player.physicsBody {
// let dy = player.physicsBody?.velocity.dy
// let platform = JumpThroughPlatformObject
if contact.bodyA.node == player {
body.collisionBitMask |= CollisionTypes.platform.rawValue
}else if contact.bodyB.node == player {
body.collisionBitMask |= CollisionTypes.platform.rawValue
}
}
}
Adding what I did, the player can no longer jump through the platform.