12

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 */

}
Community
  • 1
  • 1
Nimbahus
  • 477
  • 3
  • 16

2 Answers2

3

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 :)

Alexey Bondarchuk
  • 2,002
  • 2
  • 20
  • 22
  • I tried it without longPress, and inserted the applyImpulse in the touches began. It still gives me the same result. – Nimbahus Aug 16 '15 at 16:15
  • @Albert Have you tried my solution? [Here is video of my code](https://youtu.be/TMyzXM2I-80) – Alexey Bondarchuk Aug 16 '15 at 16:32
  • Yes I used the exact same code. 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 wont. Here is the result I want to have : [Youtube](https://www.youtube.com/watch?v=-qrD07vIb58) – Nimbahus Aug 16 '15 at 17:36
  • Hey, sorry for the late answer. I tried it exactly with your code, and it still only applies the increased impulse to the character after the next tap. Also it will be rater difficult to handle it like this with a minimum and maximum of Float. – Nimbahus Aug 17 '15 at 16:02
  • So, check my latest updated above. I've created example with UIDynamics. Hope that this will help you a little and now will work for sure :) – Alexey Bondarchuk Aug 19 '15 at 19:24
  • First of all thanks for trying to help me. I tried your code, and it actually behaves exactly like my previous code. If you short tap, the Player gets a small impulse, but if you long press, there does nothing happen until you release/reach the maximum, and then the Player gets an impulse. I need the Player to jump the minimum, and then depending on how long you press the screen, the impulse increases until the maximum. – Nimbahus Aug 20 '15 at 07:28
  • @Albert Hi. Check one more time :) I hope in this time this is something that you need. – Alexey Bondarchuk Aug 20 '15 at 19:51
  • Hi, I tried it. Its sadly not quite this what I expect to get. But I am thankful for your support. – Nimbahus Aug 22 '15 at 09:17
  • I just showed to you direction and simplest solution how to jump if user pressing the screen. All other functionality should be done by you. And in this solution you don't need to track any additional float values. – Alexey Bondarchuk Aug 22 '15 at 12:33
1

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.

MaxKargin
  • 1,560
  • 11
  • 13