2
votes

I am working on a game similar to pong, while starting the game I apply impulse to the ball in random direction, which is at the centre of the screen e.g.

func impulse(){
    let randomNum:UInt32 = arc4random_uniform(200)
    let someInt:Int = Int(randomNum)

    //Ball Impulse
    if someInt<49{
    ball.physicsBody?.applyImpulse(CGVector(dx: ballSpeed+3, dy: ballSpeed-5))
    }else if someInt<99{
        ball.physicsBody?.applyImpulse(CGVector(dx: ballSpeed+5, dy: -ballSpeed+5))
    }else if someInt<149{
        ball.physicsBody?.applyImpulse(CGVector(dx: -ballSpeed-5, dy: -ballSpeed+5))
    }else if someInt<200{
        ball.physicsBody?.applyImpulse(CGVector(dx: -ballSpeed-3, dy: ballSpeed-5))
    }

}

Where ballSpeed is the preset speed of ball. So is there any way I can gradually increase the velocity of ball with duration while it is in motion? As ball will keep on bouncing around the screen so it is difficult to apply force to it using dx and dy.

EDIT -

I am using above method just to assign a random quadrant/direction to ball at start of the game.

Start, when impulse method is implemented e.g. Game start image

And I want to increase speed of the ball by a predefined unit over time during gameplay e.g. Gameplay

1
If the sprite is moving via physics, then its velocity property will have a value. This is a vector, so you can just apply another impulse using the velocity as the vector for the impulse to give it more speed.Steve Ives
Are you aware that your intervals are uneven? Your first interval goes from 0 to 48, the next from 49 to 98, the next from 99 to 148, and the last from 149 to 200, meaning the first 3 ranges are only 49 values wide and the last is 51.user1118321
@user1118321 - Actually, I prefer the ball to start in the 3rd quadrant when game start so it's just like a bonus of 2 extra points I am giving here which usually turns out to negligible when executedAmol Kumar
@SteveIves - Here, in this case, I am trying to increase ball speed by 2 units every 5 seconds so how can I implement that using ball.physicsBody?.applyImpulse((ball.physicsBody?.velocity)!)Amol Kumar

1 Answers

2
votes

Ok, here you go! The ball CONSTANTLY gets faster, no matter what!!! Adjust amount to determine how much the ball gains speed each frame.

class GameScene: SKScene, SKPhysicsContactDelegate {

  let ball = SKShapeNode(circleOfRadius: 20)
  var initialDY = CGFloat(0)
  var initialDX = CGFloat(0)



  override func didMove(to view: SKView) {
    self.physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
    self.physicsWorld.gravity = CGVector.zero

    // Configure ball pb:
    let pb = SKPhysicsBody(circleOfRadius: 20)
    ball.physicsBody = pb
    addChild(ball)

    pb.applyImpulse(CGVector(dx: 10, dy: 10))
  }

  override func update(_ currentTime: TimeInterval) {
    initialDX = abs(ball.physicsBody!.velocity.dx)
    initialDY = abs(ball.physicsBody!.velocity.dy)
  }

  override func didSimulatePhysics() {
    guard let pb = ball.physicsBody else { fatalError() }

    // decrease this to adjust the amount of speed gained each frame :)
    let amount = CGFloat(5)

    // When bouncing off a wall, speed decreases... this corrects that to _increase speed_ off bounces.
    if abs(pb.velocity.dx) < abs(initialDX) {
      if      pb.velocity.dx < 0 { pb.velocity.dx = -initialDX - amount }
      else if pb.velocity.dx > 0 { pb.velocity.dx =  initialDX + amount }
    }

    if abs(pb.velocity.dy) < abs(initialDY) {
      if      pb.velocity.dy < 0 { pb.velocity.dy = -initialDY - amount }
      else if pb.velocity.dy > 0 { pb.velocity.dy =  initialDY + amount }
    }
  }
}

you can modify this to only increase speed every 5 seconds with an SKAction.repeatForever(.sequence([.wait(forDuration: TimeInterval, .run( { code } ))) but IMO having it constantly gain speed is a bit more awesome and easier to implement.