当我运行我的应用程序时,似乎当游戏在spawnEnemies()中生成敌人时,在添加敌人孩子的while循环期间,整个应用程序冻结。没有SKActions运行且没有注册触摸输入。是什么导致了这个问题?感谢
//
// GameScene.swift
// Defence
//
// Created by iD Student on 7/6/16.
// Copyright (c) 2016 iD Tech. All rights reserved.
//
import SpriteKit
struct DefType {
static let basic: Int = 1
}
struct EnemyType {
static let basic: Int = 1
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var basicDef = SKSpriteNode()
var defencesArr: [Defence] = []
var enemiesArr: [Enemy] = []
var waveCount: Double = 0
//Interval between which enemies are spawned
var spawnRate:Double = 2
//Percentage increase per level of spawnRate
var spawnRateScale: Double = 0.05
var timeOfLastSpawn: Double = 0
var basicEnemySpawnBase: Double = 5
var basicEnemySpawnScale: Double = 0.5
var basicEnemySpawned: Int = 0
//Time between each wave
var waveTimer: Double = 0
var timeOfLastWave: Double = 0
var touchLocation = CGPointZero
var placementPos = CGPointZero
var basicDefSelected: Bool = false
let basicDefSelector = SKSpriteNode()
var selectedNode = SKSpriteNode()
override func didMoveToView(view: SKView) {
backgroundColor = UIColor.blackColor()
basicDef.texture = SKTexture(imageNamed: "basic.png")
basicDef.size = CGSize(width: 40, height: 40)
basicDef.position = CGPoint(x: size.width-20, y: 30)
self.addChild(basicDef)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("tapped:"))
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: Selector("pressed:"))
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: Selector("handlePanFrom:"))
view.addGestureRecognizer(gestureRecognizer)
view.addGestureRecognizer(tapGestureRecognizer)
view.addGestureRecognizer(longPressRecognizer)
physicsWorld.gravity = CGVectorMake(0, 0)
physicsWorld.contactDelegate = self
}
func tapped(sender: UITapGestureRecognizer) {
}
func pressed(sender: UILongPressGestureRecognizer) {
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
func addDefence(type: Int) {
var defenceAdded: Defence = Defence(type: DefType.basic)
switch type {
case DefType.basic:
defenceAdded = Defence(type: DefType.basic)
break
default:
break
}
defencesArr.append(defenceAdded)
addChild(defenceAdded)
defenceAdded.position = placementPos
}
func selectNodeForTouch(touchLocation : CGPoint) {
let touchedNode = self.nodeAtPoint(touchLocation)
if touchedNode is SKSpriteNode && touchedNode.physicsBody?.categoryBitMask != 0 && selectedNode.physicsBody?.categoryBitMask != 0{
if !selectedNode.isEqual(touchedNode){
selectedNode.removeAllActions()
selectedNode = touchedNode as! SKSpriteNode
}
}
}
func handlePanFrom(recognizer : UIPanGestureRecognizer) {
if recognizer.state == .Began {
touchLocation = recognizer.locationInView(recognizer.view)
touchLocation = convertPointFromView(touchLocation)
selectNodeForTouch(touchLocation)
if basicDef == selectedNode{
basicDefSelector.size = CGSize(width: 40, height: 40)
basicDefSelector.alpha = 0.5
basicDefSelector.position = touchLocation
basicDefSelector.texture = SKTexture(imageNamed: "basic.png")
addChild(basicDefSelector)
selectedNode = basicDefSelector
basicDefSelected = true
}
} else if recognizer.state == .Changed {
var translation = recognizer.translationInView(recognizer.view!)
translation = CGPoint(x: translation.x, y: -translation.y)
selectedNode.position = CGPoint(x: selectedNode.position.x + translation.x, y: selectedNode.position.y + translation.y)
recognizer.setTranslation(CGPointZero, inView: recognizer.view)
} else if recognizer.state == .Ended {
if basicDefSelected == true {
placementPos = selectedNode.position
basicDefSelector.removeFromParent()
addDefence(DefType.basic)
basicDefSelected = false
}
selectedNode = SKSpriteNode()
}
}
func spawnEnemies(wave: Double) {
var enemiesToBeAdded: [Int] = []
var enemyToBeAdded: Int = EnemyType.basic
var enemyAdded: Enemy = Enemy(type: EnemyType.basic)
var basicEnemySpawnAmount = basicEnemySpawnBase + (wave * basicEnemySpawnScale)
while basicEnemySpawnAmount > 0 {
print(basicEnemySpawnAmount)
enemyToBeAdded = EnemyType.basic
enemiesToBeAdded.append(enemyToBeAdded)
basicEnemySpawnAmount -= 1
}
while enemiesToBeAdded.count > 0 {
print("TimeDifferential \(CACurrentMediaTime() - timeOfLastSpawn)")
if (CACurrentMediaTime() - timeOfLastSpawn) >= spawnRate {
print("spawned")
let randomX = drand48() * Double(size.width-80)
let enemyPos: CGPoint = CGPoint(x: CGFloat(randomX), y: size.height+100)
let randomIndex = arc4random_uniform(UInt32(enemiesToBeAdded.count))
switch enemiesToBeAdded[Int(randomIndex)] {
case EnemyType.basic:
enemyAdded = Enemy(type: EnemyType.basic)
break
default:
break
}
addChild(enemyAdded)
enemyAdded.position = enemyPos
enemiesArr.append(enemyAdded)
enemiesToBeAdded.removeAtIndex(Int(randomIndex))
var movEnemy: SKAction
movEnemy = SKAction.moveTo(CGPoint(x: enemyAdded.position.x, y: -100), duration: enemyAdded.flightSpeed)
enemyAdded.runAction(SKAction.sequence([movEnemy, SKAction.removeFromParent()]))
timeOfLastSpawn = CACurrentMediaTime()
}
}
}
override func update(currentTime: CFTimeInterval) {
waveTimer = (waveCount * spawnRate * (1+spawnRateScale)) + 20
for defence in defencesArr {
if defence.towerType == DefType.basic {
if (CACurrentMediaTime() - defence.lastShotTime) >= defence.fireRate {
let bullet = SKSpriteNode()
bullet.texture = SKTexture(imageNamed: "basicBullet.png")
bullet.size = CGSize(width: 40, height: 40)
bullet.position = CGPoint(x: defence.position.x, y: defence.position.y+20)
addChild(bullet)
let vector = CGVectorMake(0, CGFloat(defence.bulletRange))
let projectileAction = SKAction.sequence([
SKAction.moveBy(vector, duration: defence.bulletSpeed),
SKAction.removeFromParent()
])
bullet.runAction(projectileAction)
defence.lastShotTime = CACurrentMediaTime()
}
}
}
if (CACurrentMediaTime() - timeOfLastWave) >= waveTimer {
timeOfLastWave = CACurrentMediaTime()
spawnEnemies(waveCount)
waveCount += 1
}
}
}
答案 0 :(得分:1)
你的应用程序因为过度循环而冻结。当我运行你的代码时,在第1级,我计算了循环次数。
第一次通过:
Total loops: 192078
第二次通过:
Total loops: 339925
因此,对于wave 1,您正在主线程上运行超过192,000个循环。这肯定会冻结你的应用程序。