Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sprite Kit stop Impulse

I want to increase a CGFloat every time while the Screen is tapped. The float has a set maximum and minimum value. I tried to go through this suggestion: StackOverflow

However, this only increases the CGFloat after the touch is made, or the maximum is reached. I want to increase the CGFloat during the touch, meaning the longer you touch the higher the Jump/CGFloat.

The problem probably lies within the impulse, that you cant change it after it was applied. That means, after the 'Player' gets an impulse of 20, and the screen is longer touched, the Float may increase, but the impulse won't.

If you look at my current code, the impulse is set at maximum while the screen is touched, but if released the action should be removed. However, it doesn't work, the impulse does not stop.

I know that you can set the velocity of the body at a value after the press is made, and if the press has ended the velocity back to 0 so it stops it 'jump', but that doesn't look quite smooth as it would be with an impulse.

Has anybody a solution?

struct Constants {

static let minimumJumpForce:CGFloat = 20.0
static let maximumJumpForce:CGFloat = 60.0
}

class GameScene: SKScene, SKPhysicsContactDelegate {

var force: CGFloat = 20.0

func longPressed(longPress: UIGestureRecognizer) {

    if (longPress.state == UIGestureRecognizerState.Began) {

        println("Began")

        self.pressed = true

        let HigherJump = SKAction.runBlock({Player.physicsBody?.applyImpulse(CGVectorMake(0, Constants.maximumJumpForce))})

        self.runAction(HigherJump , withKey:"HighJump")

    }else if (longPress.state == UIGestureRecognizerState.Ended) {

        println("Ended")

        self.pressed = false

        self.removeActionForKey("HighJump")

    }

}

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

    for touch in (touches as! Set<UITouch>) {
        let location = touch.locationInNode(self)

    }
}

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in (touches as! Set<UITouch>) {
        let location = touch.locationInNode(self)

}
}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */

}
like image 484
Albert Avatar asked Aug 16 '15 10:08

Albert


2 Answers

1.Create ‘Game’ from Xcode template based on SpriteKit
2.Copy paste listed code to GameScene class

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {

    var location = CGPoint()
    var floorSize = CGSize()
    var floorColor = UIColor()
    var player = SKSpriteNode()

    override func didMoveToView(view: SKView) {

        view.showsFPS = true;
        view.showsNodeCount = true;
        view.showsDrawCount = true;

        self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
        self.physicsBody?.categoryBitMask = 1
        self.physicsBody?.contactTestBitMask = 1
        self.physicsWorld.gravity = CGVectorMake(0, 0)
        self.physicsWorld.contactDelegate = self;

        location = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))

        player = SKSpriteNode(imageNamed:"Spaceship")
        player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 320, height: 320))
        player.physicsBody?.categoryBitMask = 1
        player.physicsBody?.collisionBitMask = 1
        player.physicsBody?.contactTestBitMask = 1
        player.physicsBody?.linearDamping = 0;
        player.xScale = 1
        player.yScale = 1
        player.position = location
        self.addChild(player)

    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.physicsWorld.gravity = CGVectorMake(0, 0)
        let direction = Float(1.5708)//Float(player.zRotation) + Float(M_PI_2)
        player.physicsBody?.applyForce(CGVector(dx: 150000*CGFloat(cosf(direction)), dy: 150000*CGFloat(sinf(direction))))
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.physicsWorld.gravity = CGVectorMake(0, -7.9)
    }

}

3.Run the app

This should give you start point for you 'Jump' game :)

like image 186
Alexey Bondarchuk Avatar answered Oct 23 '22 18:10

Alexey Bondarchuk


Try changing this:

if(self.pressed){

    let HigherJump = SKAction.runBlock({if(self.force < Constants.maximumJumpForce){
        self.force += 2.0
    }else{
        self.force = Constants.maximumJumpForce
        }})
    self.runAction(HigherJump)
}

to this:

if(self.pressed){
    if(self.force < Constants.maximumJumpForce) {
         self.force += 2.0
    }
    else {
         self.force = Constants.maximumJumpForce
    }
}

Theres no need to use a runBlock SKAction here.

like image 30
MaxKargin Avatar answered Oct 23 '22 18:10

MaxKargin