Rich Townsend Rich Townsend - 7 months ago 21
Swift Question

swift - Jump only when landed

I'm looking to restrict my character (cat), to only jump when it's either on the ground (dummy SKNode), or when on the tree (treeP SKNode).

Currently I don't have any restrictions to

touchesBegan
and as a result the cat is able to fly through the air if the user clicks in quick succession, whilst this could be useful in other games it's not welcome here.

If anyone could help me I'd be really happy.

What i would like to do but have no experience would be to enable a click (jump), if the cat was in contact with either dummy or tree and likewise disable clicks if not in contact with either dummy or tree.

Here is everything that may be of use....

class GameScene: SKScene, SKPhysicsContactDelegate {

let catCategory: UInt32 = 1 << 0
let treeCategory: UInt32 = 1 << 1
let worldCategory: UInt32 = 1 << 1

override func didMoveToView(view: SKView) {

// part of cat code

cat = SKSpriteNode(texture: catTexture1)
cat.position = CGPoint(x: self.frame.size.width / 2.2, y: self.frame.size.height / 7.0 )
cat.physicsBody?.categoryBitMask = catCategory
cat.physicsBody?.collisionBitMask = crowCategory | worldCategory
cat.physicsBody?.contactTestBitMask = crowCategory | contact2Category

// part of the ground code

var dummy = SKNode()
dummy.position = CGPointMake(0, groundTexture.size().height / 2)
dummy.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, groundTexture.size().height))
dummy.physicsBody!.dynamic = false
dummy.physicsBody?.categoryBitMask = worldCategory
dummy.physicsBody?.collisionBitMask = 0
dummy.physicsBody?.contactTestBitMask = 0
moving.addChild(dummy)

// part of the tree code

func spawnTrees() {
var treeP = SKNode()
treeP.position = CGPointMake( self.frame.size.width + treeTexture1.size().width * 2, 0 );
treeP.zPosition = -10;
var height = UInt32( self.frame.size.height / 4 )
var y = arc4random() % height;
var tree1 = SKSpriteNode(texture: treeTexture1)
tree1.position = CGPointMake(0.0, CGFloat(y))
tree1.physicsBody = SKPhysicsBody(rectangleOfSize: tree1.size)
tree1.physicsBody?.dynamic = false
tree1.physicsBody?.categoryBitMask = treeCategory;
tree1.physicsBody?.collisionBitMask = 0
tree1.physicsBody?.contactTestBitMask = 0
treeP.addChild(tree1)

treeP.runAction(moveAndRemoveTrees)

trees.addChild(treeP)

}

// all of touchesBegan

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */


if (moving.speed > 0){
cat.physicsBody!.velocity = CGVectorMake(0, 0)
cat.physicsBody!.applyImpulse(CGVectorMake(0, 20))

} else if (canRestart) {
self.resetScene()
}

}

Answer

I recently had this problem. This is how I fixed it. In the game scene create this variable:

    var ableToJump = true

Then in the update method put this code:

    if cat.physicsBody?.velocity.dy == 0 {
ableToJump = true
    }
    else {
ableToJump = false
    }

The above code will work because the update method is ran every frame of the game. Every frame it checks if your cat is moving on the y axis. If you do not have an update method, just type override func update and it should autocomplete.

Now the last step is put this code in the touchesBegan:

    if ableToJump == true {
cat.physicsBody!.applyImpulse(CGVectorMake(0,40))
 }

Note: You may have to tinker with the impulse to get desired jump height