2015-09-13 70 views
0

我試圖將5幀的動畫合併到我現有的spritenode的spawn函數中。目前,烏鴉從右向左移動穿過屏幕,但我想製作這個動畫,無論我嘗試什麼,我都會產生線程1錯誤。帶有產卵功能的動畫圖像

通過註釋掉某些代碼,我可以在屏幕上的靜態位置對鳥進行動畫處理,或者將鳥從右向左但不動畫(註釋出spawn func)。

我知道下面的代碼不會在當前窗體中工作,但它是我正在處理的一切,希望有人能幫助我。

下面是我的代碼我想起來插槽...

謝謝

//did move to view 

var crowTexture1 = SKTexture(imageNamed: "crow1") 
crowTexture1.filteringMode = SKTextureFilteringMode.Nearest 
var crowTexture2 = SKTexture(imageNamed: "crow2") 
crowTexture2.filteringMode = SKTextureFilteringMode.Nearest 
var crowTexture3 = SKTexture(imageNamed: "crow3") 
crowTexture3.filteringMode = SKTextureFilteringMode.Nearest 
var crowTexture4 = SKTexture(imageNamed: "crow4") 
crowTexture4.filteringMode = SKTextureFilteringMode.Nearest 
var crowTexture5 = SKTexture(imageNamed: "crow5") 
crowTexture5.filteringMode = SKTextureFilteringMode.Nearest 


    var animFly = SKAction.animateWithTextures([crowTexture1, crowTexture2, crowTexture3, crowTexture4, crowTexture5], timePerFrame: 0.1) 
    var fly = SKAction.repeatActionForever(animFly) 

    var distanceToMoveBird = CGFloat(self.frame.size.width + 2 * crowTexture1.size().width); 
    var moveBirds = SKAction.moveByX(-distanceToMoveBird, y:0, duration:NSTimeInterval(0.0040 * distanceToMoveBird)); 
    var removeBirds = SKAction.removeFromParent(); 
    moveAndRemoveBirds = SKAction.sequence([moveBirds, removeBirds,]); 

    var spawnBirds = SKAction.runBlock({() in self.spawnBird()}) 
    var delayBirds = SKAction.waitForDuration(NSTimeInterval(4.0)) 
    var spawnThenDelayBirds = SKAction.sequence([spawnBirds, delayBirds]) 
    var spawnThenDelayForeverBirds = SKAction.repeatActionForever(spawnThenDelayBirds) 
    self.runAction(spawnThenDelayForeverBirds) 

//spawning function 

func spawnBird() { 


    var bird = SKSpriteNode() 
    bird.position = CGPointMake(self.frame.size.width + crowTexture1.size().width * 2, 0); 
    var height = UInt32(self.frame.size.height/1) 
    var height_max = UInt32(500) 
    var height_min = UInt32(500) //300 
    var y = arc4random_uniform(height_max - height_min + 1) + height_min; 
    var bird1 = SKSpriteNode(texture: crowTexture1) 



    bird1.position = CGPointMake(0.0, CGFloat(y)) 
    bird1.physicsBody = SKPhysicsBody(rectangleOfSize: bird1.size) 
    bird1.physicsBody?.dynamic = false 
    bird1.physicsBody?.categoryBitMask = crowCategory 
    bird1.physicsBody?.collisionBitMask = catCategory | scoreCategory 
    bird1.physicsBody?.contactTestBitMask = 0 
    bird.addChild(bird1) 

    bird.runAction(moveAndRemoveBirds) 

    birds.addChild(bird) 

} 

回答

0

設置我爲了工作示例(如果你只是複製粘貼&代碼) ,您需要一個名爲crow.atlas的名爲crow.atlas的atlas,其紋理名爲[email protected][email protected]等。如果您不想使用地圖集,則可以手動初始化紋理,就像您已經在做的那樣你的代碼在initializeCrowAnimation方法中)。

我寫的代碼裏面所有需要的意見:

import SpriteKit 

class GameScene: SKScene { 

    let CrowCategory : UInt32 = 0x1 << 1 
    let CatCategory : UInt32 = 0x1 << 2 
    let ScoreCategory : UInt32 = 0x1 << 3 

    var animationFrames : [SKTexture]! 

    override func didMoveToView(view: SKView) { 

     //1 - Get textures 

     initializeCrowAnimation() 

     // 2 - Generate birds 
     generateBirds() 

    } 


    //Initialize crow animation - first way 

    func initializeCrowAnimation(numOfFrames:Int){ 

     //You can use numOfFrames parameter if you want to get only certain number of textures from atlas 

     animationFrames = [SKTexture]() 

     let atlas = SKTextureAtlas(named: "crow") 


     for var i = 1; i <= atlas.textureNames.count; i++ { 

      let textureName = "crowAnimation\(i)" 


      animationFrames.append(atlas.textureNamed(textureName)) 
     } 

    } 

    //Initialize crow animation - second way 

    func initializeCrowAnimation(){ 


     let atlas = SKTextureAtlas(named: "crow") 

     animationFrames = [ 
      atlas.textureNamed("crowAnimation1"), 
      atlas.textureNamed("crowAnimation2"), 
      atlas.textureNamed("crowAnimation3"), 
      atlas.textureNamed("crowAnimation4"), 
      atlas.textureNamed("crowAnimation5"), 
     ] 


    } 

    //Helper methods 

    func randomBetweenNumbers(firstNum: CGFloat, secondNum: CGFloat) -> CGFloat{ 
     return CGFloat(arc4random())/CGFloat(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum) 
    } 

    func getRandomPoint()->CGPoint{ 

     var xRange:UInt32 = UInt32(frame.size.width) // you can change the range here if you like 
     var yRange:UInt32 = UInt32(frame.size.height) // you can change the range here if you like 

     return CGPoint(x:Int(arc4random()%xRange),y:Int(arc4random()%yRange)) 
    } 


    //Method for creating bird node 

    func getBird()->SKSpriteNode{ 

     let bird = SKSpriteNode(texture: animationFrames.first) 
     bird.physicsBody = SKPhysicsBody(rectangleOfSize: bird.size) 
     bird.physicsBody?.dynamic = false 
     bird.physicsBody?.categoryBitMask = CrowCategory 
     bird.physicsBody?.collisionBitMask = CatCategory | ScoreCategory 
     bird.physicsBody?.contactTestBitMask = 0 
     bird.name = "crow" //will help you to enumerate all crows if needed 

     //Flying animation 
     let flyAnimation = SKAction.repeatActionForever(SKAction.animateWithTextures(animationFrames, timePerFrame: 0.1)) 

     bird.runAction(flyAnimation, withKey: "flying") // you can stop flying animation at any time by removing this key 

     //Moving animation 

     let move = SKAction.moveTo(getRandomPoint(), duration: NSTimeInterval(randomBetweenNumbers(4, secondNum:6))) 

     let remove = SKAction.removeFromParent() 

     let moveAndRemove = SKAction.sequence([move,remove]) 

     bird.runAction(moveAndRemove, withKey: "moving") 


     return bird 

    } 

    //If needed you can use something like this to stop generating birds, or any other action associated by certain key 

    func stopGeneratingBirds(){ 

     if(self.actionForKey("spawning") != nil){ 

      self.removeActionForKey("spawning") 
     } 

    } 

    func generateBirds(){ 

     //spawn a bird with delay between 2 + (+1/-1) means, between 1 and 3 seconds 
     let delay = SKAction.waitForDuration(2, withRange: 1) 


     var block = SKAction.runBlock({ 

      //Note that here if you don't use something like [unowned self] or [weak self] you will create a retain cycle 

      //Because I am using outdated Swift version (and retain cycle is a whole new topic), I will skip it 

      var bird = self.getBird() 

      bird.position = self.getRandomPoint() 

      println(bird.position) 

      self.addChild(bird) 

     }) 



     let spawnSequence = SKAction.sequence([delay, block]) 


     self.runAction(SKAction.repeatActionForever(spawnSequence), withKey: "spawning") 
    } 

    deinit{ 
     println("Deinited") 
    } 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 
    } 

} 

請注意,這只是它可以給你在哪個方向,你可以去一個基本的想法,你的代碼與此相比較,看一個例子爲什麼你的代碼不工作。

這是測試,它的工作,但請注意,也許我錯過了什麼。

關於保留週期,以及如何避免它們,您可以read more here(並相應地更新您的代碼)。我已經跳過了在我的答案中添加該部分,因爲我的Swift版本已過時,可能適用於我,對您無效,但關鍵是使用[unowned self][weak self]。相同的主題可以在文檔here中找到。

+0

感謝您的評論,我一直在玩弄你的代碼,我喜歡這個概念,我似乎無法將它與我的代碼整合在一起,只有一隻鳥在一定的高度範圍內從右到左進入屏幕。這隻鳥需要穿過整個屏幕,因爲這是觸發器,一旦鳥碰到屏幕左側的觸點,就會增加分數......如果您或其他人知道如何做到這一點,那就是我尋找,我會很感激。 –