Reputation: 37
I am trying to make a jump and run game in Swift, and I have run into two main problems.
The first is that I applied the gravity to the GameScene, but every time I jump, the player goes through the floor instead of stopping at its original position. I tried setting dynamic = false before jumping, and then setting it to true after jumping, but it still falls through the floor.
Another problem that I have is that when clicked, the player applies and impulse every click and therefore jumps, double jumps, triple jumps, etc. I can't seem to figure out how to make it only jump when it is at the ground level.
Here is the code.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//basically my tap to start feature. i set the player's dynamic to false at the play screen, then on the first tap it runs the game, then every other tap it normally jumps
if player.physicsBody!.dynamic {
player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 5.0))
} else {
spawnBarrels()
addTimer()
runScore()
startLabel.removeFromParent()
player.physicsBody?.dynamic = true
player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 4.0))
}
}
func addGround(){
//adds the ground
addChild(ground)
ground.size = CGSize(width: size.width * 1, height: size.height * 0.1)
ground.position = CGPoint(x: size.width * 0.5, y: size.height * 0.05)
ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: size.height, height: size.height * 0.1))
ground.physicsBody?.dynamic = false
}
var canJump = true
//change
func didBeginContactGround(contact: SKPhysicsContact){
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask){
case PhysicsCategory.Player | PhysicsCategory.Ground:
canJump = true
default:
return
}
}
Upvotes: 2
Views: 598
Reputation: 454
For the first part of your question: You have the collision, contact, and category bitmasks mixed up. These are their Definitions/Uses:
PhysicsCategory.Player
)PhysicsCategory.Ground
)func didBeginContact(contact: SKPhysicsContact){}
Right now you're telling your player to check for collision between it and other players, and collide with nothing (If this doesn't make sense I suggest looking into these bitmasks further). If you want your player to die when it comes into contact with an obstacle, you would set its Contact to be PhysicsCategory.Obstacle
.
For the Second Part: You can set the contact bitmask to be PhysicsCategory.Ground
, and if you also want obstacles, it can be: PhysicsCategory.Ground | PhysicsCategory.Obstacle
. Then you can make a boolean called canJump, and only allow jumping when this is true
.
Then you would write this somewhere in your code:
func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask) {
case PhysicsCategory.Player | PhysicsCategory.Ground:
canJump = true;
default:
return
}
}
Then whenever your player jumps, set canJump to false
. This will make it so that when the player hits the ground, they can then jump again. If you want to be more precise, instead of setting canJump to false
after jumping, set it false
after the player is no longer in contact with the ground by making another identical function but changing the name to didEndContact
, and setting it to false
instead of true
.
Also, dynamic should always be true
for the player. Here's a link that should help if you don't understand the different bitmasks:
Upvotes: 0