2016-07-13 4 views
-3

의 적을 생성 할 때 앱이 멈 춥니 다. 게임이 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 
     } 
    } 
} 
+1

당신이 코드를 훨씬 쉽게 읽을 수있게 해주는 무관 한 코드를 모두 제발 주실 수 있겠습니까? – Eric

+0

그리고 spawnEnemies의 while 루프 안에있는 print 문은 앱이 정지 될 때 텍스트를 출력합니까? – Eric

+0

SO Mark Wong –

답변

1

지나치게 반복하고 있기 때문에 앱이 정지되었습니다. 레벨 1에서 코드를 실행했을 때 루프를 통해 몇 번이나 세어 보았습니다.

Total loops: 192078 

두 번째 시간을 통해 :를 통해

처음

메인 스레드에서 192,000 이상의 루프를 통해 실행하는 그래서 파 1
Total loops: 339925 

. 이렇게하면 앱이 완전히 정지됩니다.

+0

감사합니다. 기능을 수정하고 문제를 해결했습니다. 나는 아마 루프를 가지고 뭔가를해야한다는 것을 깨달았습니다. 그래서 나의 의심을 확인해 주셔서 감사합니다. –

관련 문제