【问题标题】:Animate image with spawn function具有生成功能的动画图像
【发布时间】:2015-09-13 08:16:25
【问题描述】:

我正在尝试将 5 帧动画合并到我现有的 spritenode 生成函数中。目前一只乌鸦在屏幕上从右到左移动,我想对此进行动画处理,但无论我尝试什么,我都会不断产生线程 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)

}

【问题讨论】:

    标签: ios swift animation sprite-kit sprite


    【解决方案1】:

    要设置我的示例以便工作(如果您只是复制和粘贴代码),您需要一个名为 crow.atlas 的 atlas 纹理名为 crowAnimation1@2x.png 、 crowAnimation2@2x.png 等。如果你不'不想使用图集,您可以手动初始化纹理,就像您已经在做的那样(只需将您的代码放在 initializeCrowAnimation 方法中)。

    我在代码中编写了所有需要的 cmets:

    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 中找到相同的主题。

    【讨论】:

    • 谢谢你的评论,我一直在玩你的代码,我喜欢这个概念,我似乎无法将它与我的代码集成,即一只鸟从右到右进入屏幕留在一定的高度范围内。小鸟需要穿过整个屏幕,因为这是触发,一旦小鸟击中屏幕左侧的触点就会增加分数......如果你或其他任何人知道如何实现这一点,那就是我寻找,我将不胜感激。
    猜你喜欢
    • 2020-03-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 2017-11-06
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多