I have a small Space Game that I have been working on for a month or so now while learning SpriteKit and Swift. I got everything working just as I want it except for one thing, no matter what I try I either get errors or an close but not desired effect.
My issues is with spawning 1 random Power every XX seconds. The code I have right now works, but doesn't spawn 1, it spawns 1 or 2 or even 3 at the same time at a set interval between 30 and 90 seconds.
I tried several different arc4random ways, but I can't figure out how to do it. Could someone please guide me into the right direction. This is my last hurdle before the game is finished and it has been bugging me for weeks now.
The code I use solar, while working, but not he desired effect:
func startNewLevel(){
levelNumber += 1
if self.action(forKey: "spawningEnemies") != nil{
self.removeAction(forKey: "spawningEnemies")
}
if self.action(forKey: "spawningUfos") != nil{
self.removeAction(forKey: "spawningUfos")
}
if self.action(forKey: "spawningLifePowerUps") != nil{
self.removeAction(forKey: "spawningLifePowerUps")
}
if self.action(forKey: "spawningShieldPowerUps") != nil{
self.removeAction(forKey: "spawningShieldPowerUps")
}
if self.action(forKey: "spawningRapidFirePowerUps") != nil{
self.removeAction(forKey: "spawningRapidFirePowerUps")
}
var levelDuration = TimeInterval()
// Change the levelDuration = X.X to what ever you want to determin your game diffculty. The higher the number the slow the game and vice versa
switch levelNumber {
case 1: levelDuration = 3.0 //Easy
case 2: levelDuration = 2.8
case 3: levelDuration = 2.6
case 4: levelDuration = 2.4
case 5: levelDuration = 2.2
case 6: levelDuration = 2.0 //Medium
case 7: levelDuration = 1.8
case 8: levelDuration = 1.6
case 9: levelDuration = 1.4
case 10: levelDuration = 1.2
case 11: levelDuration = 1.0 //Hard
case 12: levelDuration = 0.8
case 13: levelDuration = 0.6
case 14: levelDuration = 0.4
case 15: levelDuration = 0.2 //Insane
default:
levelDuration = 0.2
print("Cannot find levelinfo")
}
let upperBonuslimit : UInt32 = 90 // Default 120 seconds
let lowerBonuslimit : UInt32 = 60 // Default 60 seconds
let upperlimit : UInt32 = 90 // Default 90 seconds
let lowerlimit : UInt32 = 30 // Default 30 seconds
let spawn = SKAction.run(spawnEnemy)
let waitToSpawn = SKAction.wait(forDuration: levelDuration)
let spawnSequence = SKAction.sequence([waitToSpawn, spawn])
let spawnForever = SKAction.repeatForever(spawnSequence)
self.run(spawnForever, withKey: "spawningEnemies")
let spawnUfoEnemy = SKAction.run(spawnUfo)
let waitToSpawnUfo = TimeInterval(CGFloat(arc4random() % ((upperBonuslimit - lowerBonuslimit) * 10) + lowerBonuslimit * 10)/10.0)
let randomWaitUfo = SKAction.wait(forDuration: waitToSpawnUfo)
let spawnUfoSequence = SKAction.sequence([randomWaitUfo, spawnUfoEnemy])
let spawnUfoForever = SKAction.repeatForever(spawnUfoSequence)
self.run(spawnUfoForever, withKey: "spawningUfos")
let spawnLife = SKAction.run(spawnALifePowerUp)
let waitToSpawnLife = TimeInterval(CGFloat(arc4random() % ((upperlimit - lowerlimit) * 10) + lowerlimit * 10)/10.0)
let randomWait = SKAction.wait(forDuration: waitToSpawnLife)
let spawnSequenceLife = SKAction.sequence([randomWait, spawnLife])
let spawnForeverLife = SKAction.repeatForever(spawnSequenceLife)
self.run(spawnForeverLife, withKey: "spawningLifePowerUps")
let spawnShield = SKAction.run(spawnAShieldPowerUp)
let waitToSpawnShield = TimeInterval(CGFloat(arc4random() % ((upperlimit - lowerlimit) * 10) + lowerlimit * 10)/10.0)
let randomWait2 = SKAction.wait(forDuration: waitToSpawnShield)
let spawnSequenceShield = SKAction.sequence([randomWait2, spawnShield])
let spawnForeverShield = SKAction.repeatForever(spawnSequenceShield)
self.run(spawnForeverShield, withKey: "spawningShieldPowerUps")
let spawnRapidFire = SKAction.run(spawnARapidFirePowerUp)
let waitToSpawnRapidFire = TimeInterval(CGFloat(arc4random() % ((upperlimit - lowerlimit) * 10) + lowerlimit * 10)/10.0)
let randomWait3 = SKAction.wait(forDuration: waitToSpawnRapidFire)
let spawnSequenceRapidFire = SKAction.sequence([randomWait3, spawnRapidFire])
let spawnForeverRapidFire = SKAction.repeatForever(spawnSequenceRapidFire)
self.run(spawnForeverRapidFire, withKey: "spawningRapidFirePowerUps")
}
Please let me know if there is anything I need to explain better. Or if I need to add any code.
Here is one of the Powerup function codes just incase it's needed swell to understand my issue:
func spawnALifePowerUp(){
if livesNumber < 5 {
let randomXStart = random(min: gameArea.minX, max: gameArea.maxX)
let randomXEnd = random(min: gameArea.minX, max: gameArea.maxX)
let startPoint = CGPoint(x: randomXStart, y: self.size.height * 1.2)
let endPoint = CGPoint(x: randomXEnd, y: -self.size.height * 0.2)
let lifePower = SKSpriteNode(imageNamed: "lifePowerUp")
lifePower.name = "LifePu"
lifePower.setScale(1.2)
lifePower.position = startPoint
lifePower.zPosition = 3
lifePower.physicsBody = SKPhysicsBody(rectangleOf: lifePower.size)
lifePower.physicsBody!.affectedByGravity = false
lifePower.physicsBody!.categoryBitMask = PhysicsCategories.LifePu
lifePower.physicsBody!.collisionBitMask = PhysicsCategories.None
lifePower.physicsBody!.contactTestBitMask = PhysicsCategories.Player | PhysicsCategories.ShieldActive
lifePower.physicsBody!.isDynamic = true
self.addChild(lifePower)
let lifeRotation:SKAction = SKAction.rotate(byAngle: CGFloat.pi * 2, duration: 5)
let repeatLifeRotation:SKAction = SKAction.repeatForever(lifeRotation)
let moveLifeHeart = SKAction.move(to: endPoint, duration: 3.5) // Life Power Up move Speed
let deleteLifeHeart = SKAction.removeFromParent()
let lifeHeartSequence = SKAction.sequence([moveLifeHeart, deleteLifeHeart])
if currentGameState == gameState.inGame{
lifePower.run(lifeHeartSequence)
lifePower.run(repeatLifeRotation)
}
let dx = endPoint.x - startPoint.x
let dy = endPoint.y - startPoint.y
let amoutToRotate = atan2(dy, dx)
lifePower.zRotation = amoutToRotate
} else {
print("Life meter FULL!")
}
}