问题
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()
}
}
回答1:
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
回答2:
You can use some custom boolean variable called isOnTheGround
in order to restrict jumping while in the air. This variable need to be updated by you.Note that character is not necessarily on the ground just if it is in contact with "platform" (eg. side contact can occur). So, it's up to you to define what means "on the ground". When you define that, then it's easy:
Hint: You can compare character's y position with platform's y position to see is character is really on the platform.
Assuming that both character's and platform's anchor point are unchanged (0.5,0.5), to calculate character's legs y position you can do something like this (pseudo code):
characterLegsY = characterYPos - characterHeight/2
And to to get platform's surace:
platformSurfaceYPos = platformYPos + platformHeight/2
Preventing jumping while in the air
In touchesBegan:
- if
isOnTheGround
-> jump
In didEndContact:
- here you set
isOnTheGround
to false (character ended contact with ground/platform)
In didBeginContact:
- check if character is really on the ground
- set
isOnTheGround
variable to true
Here you can find an example of something similar...
来源:https://stackoverflow.com/questions/31903934/swift-jump-only-when-landed