Sprites Spawning In Straight Away At The Start

I am currently making a game on Xcode 11, I am having a problem where in which my sprite will spawn in straight away at the start, even through their is a wait delay, but after the first spawn the sprites spawn in at their current time. How can I make it so the sprites wont spawn in untill 3 seconds after the scene has started. Any help would be greatly appreciated.


The photo attached shows what happens at the start of the game.

I have attached part of my code for one of the sprites as their setup is similar to each other.

//Setup Bird
func setupBird() {
  bird = SKSpriteNode(imageNamed: "bird-1")
  bird.name = "Bird"
  bird.zPosition = 20.0
  bird.setScale(1.5)
  let birdHeight = bird.frame.height
  let random = CGFloat.random(min: -birdHeight, max: birdHeight*2.0)
  bird.position = CGPoint(x: cameraRect.maxX + bird.frame.width, y: size.height/2.0 + birdHeight + random)
  bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.width/2.0)
  bird.physicsBody!.affectedByGravity = false
  bird.physicsBody!.isDynamic = false
  bird.physicsBody!.categoryBitMask = PhysicsCategory.Bird
  bird.physicsBody!.contactTestBitMask = PhysicsCategory.Player
  addChild(bird)
  bird.run(.sequence([.wait(forDuration: 15, withRange: 5), .removeFromParent()]))

  //Animation For Birds
  var textures: [SKTexture] = []
  for i in 1...3 {
  textures.append(SKTexture(imageNamed: "bird-\(i)"))
  }

  bird.run(.repeatForever(.animate(with: textures, timePerFrame: 0.15)))

}
func spawnBird() {
  let random = CGFloat.random(min: 15.0, max: 30.0)
  run(.repeatForever(.sequence([
  .wait(forDuration: TimeInterval(random)),
  .run { [weak self] in
  self?.setupBird()
  }
  ])))
}

Accepted Reply

I replace the spawnBird() function and got rid of the call of setupBird(), but it gave me this error

Variable used within its own initial value

But i manged to fix the issue anyway by adding frame.width/2.0 to the position of the bird, coin and obstacle which moves it to the end of the screen.

        bird.position = CGPoint(x: cameraRect.maxX + frame.width/2.0 + bird.frame.width, y: size.height/2.0 + birdHeight + random)

Replies

Show what's calling spawnBird and/or setupBird.

I have a function setupNode() where in which all my functions are listed then setupNode() is called at didMove function.

override func didMove(to view: SKView){
        setupNodes()
    }


func setupNodes(){
        //Other Functions
        setupBird()
        spawnBird()
    }

The setupBird in setupNodes is adding a bird immediately. Delete that and just call spawnBird only, then you should get a delay. If you want a shorter delay before the initial bird, then add an initial shorter period before the repeat in spawnBird.


func spawnBird() {  
  let random = CGFloat.random(min: 15.0, max: 30.0)  
  .run(.sequence([.wait(forDuration: 3), .repeatForever(.sequence([  
  .wait(forDuration: TimeInterval(random)),  
  .run { [weak self] in  
  self?.setupBird()  
  }  
  ]))]))
}


If you want the bird spawning to be at varying intervals, you also should change the let random =..., since that's going to pick one delay and use it forever. Use wait(forDuration:withRange:) for varying delays.

I replace the spawnBird() function and got rid of the call of setupBird(), but it gave me this error

Variable used within its own initial value

But i manged to fix the issue anyway by adding frame.width/2.0 to the position of the bird, coin and obstacle which moves it to the end of the screen.

        bird.position = CGPoint(x: cameraRect.maxX + frame.width/2.0 + bird.frame.width, y: size.height/2.0 + birdHeight + random)

The "Variable used within its own initial value" just means you had some typo and were trying to initialize a variable using some expression involving the same variable. Anyway, glad it's working.