一旦我最终使用它,我是否必须删除精灵节点?

时间:2014-10-05 14:23:37

标签: xcode swift xcode6

我在我的场景中创建了一系列移动管道。但是在生成约30个管道后它总是会崩溃。是因为场景中有太多节点而没有新节目的记忆?代码是这样的:

import SpriteKit

class GameScene: SKScene {

var mainPipe: SKSpriteNode = SKSpriteNode()
var space:Float = 1000
var pipeCount:Int = 0


override func didMoveToView(view: SKView) {
    self.backgroundColor = SKColor.blackColor()
    self.size.width = 640
    self.size.height = 1136


}

func randomOffset() -> Float{


    var rNum:Float = Float(arc4random()%181)    // 0-180

    return rNum
}

var durations: CFloat = 5.0
var colorPipes:UIColor = UIColor.grayColor()


func spawnPipeRow(offs:Float){

    self.pipeCount = self.pipeCount + 1
    println("\(self.pipeCount)")

    //offs is the random number
    //let offset = offs + (space/2) - 105
    let offset = offs + Float(self.size.height/100) - 180

    // mainPipe = SKSpriteNode(color:colorPipes, size:CGSize(width: view.bounds.size.width/3, height:700))
    mainPipe = SKSpriteNode(color:colorPipes, size:CGSize(width: self.size.width/5, height:self.size.height/1.5))



    let pipeBottom = (mainPipe as SKSpriteNode).copy() as SKSpriteNode
    let pipeTop    = (mainPipe as SKSpriteNode).copy() as SKSpriteNode

    let xx = self.size.width * 2.0
    self.setPositionRelativeBot(pipeBottom, x:Float(xx), y: offset )
    self.setPositionRelativeTop(pipeTop, x:Float(xx), y: offset + space)

    pipeBottom.physicsBody = SKPhysicsBody(rectangleOfSize: pipeBottom.size)
    pipeTop.physicsBody = SKPhysicsBody(rectangleOfSize: pipeTop.size)

    pipeBottom.physicsBody?.dynamic = false
    pipeTop.physicsBody?.dynamic = false

    //pipeTop.physicsBody?.contactTestBitMask = birdCategory
    //pipeBottom.physicsBody?.contactTestBitMask = birdCategory


    self.addChild(pipeBottom)
    self.addChild(pipeTop)

    var actionArray1:NSMutableArray = NSMutableArray()

    actionArray1.addObject(SKAction.moveTo(CGPointMake(-1000, pipeBottom.size.height - 200), duration: NSTimeInterval(durations)))
    var actionArray2:NSMutableArray = NSMutableArray()

    actionArray2.addObject(SKAction.moveTo(CGPointMake(-1000, pipeTop.size.height - 200), duration: NSTimeInterval(durations)))

    actionArray1.addObject(SKAction.removeFromParent())
    actionArray2.addObject(SKAction.removeFromParent())

    pipeBottom.runAction(SKAction.sequence(actionArray1))
    pipeTop.runAction(SKAction.sequence(actionArray2))

}




override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    /* Called when a touch begins */

    for touch: AnyObject in touches {

    }




}

override func update(currentTime: CFTimeInterval) {
    var timeSinceLastUpdate = currentTime - lastUpdateTimerInterval
    lastUpdateTimerInterval = currentTime

    if(timeSinceLastUpdate > 1){
        timeSinceLastUpdate = 1/60
        lastUpdateTimerInterval=currentTime


    }
    updateWithTimeSinceLastUpdate(timeSinceLastUpdate)



    /* Called before each frame is rendered */
}

func setPositionRelativeBot(node:SKSpriteNode, x: Float, y: Float){

    let xx = (Float(node.size.width)/2) + x
    let yy = (Float(self.size.height)/2) - (Float(node.size.height)/2) + y
    node.position.x = CGFloat(xx)
    node.position.y = CGFloat(yy)

}
func setPositionRelativeTop(node:SKSpriteNode, x:Float, y:Float){
    let xx = (Float(node.size.width)/2) + x
    let yy = (Float(self.size.height)/2) + (Float(node.size.height)/2) + y
    node.position.x = CGFloat(xx)
    node.position.y = CGFloat(yy)

}

var lastUpdateTimerInterval:NSTimeInterval = NSTimeInterval()
var lastYieldTimeInterval:NSTimeInterval = NSTimeInterval()
var speedOfBird: CDouble = 1.8
func updateWithTimeSinceLastUpdate(timeSinceLastUpdate:CFTimeInterval){
    lastYieldTimeInterval += timeSinceLastUpdate
    if(lastYieldTimeInterval > speedOfBird ){
        lastYieldTimeInterval=0
        self.spawnPipeRow(self.randomOffset())
        if speedOfBird > 0.8{
            speedOfBird -= 0.1}
    }
}

}

2 个答案:

答案 0 :(得分:2)

当你不再需要它们时,你应该从场景中删除你的精灵。但是,您的问题可能与纹理占用的内存无关:

<强> SpriteKit Programming Guide

  

创建一个SKTexture对象并将其附加到sprite。这个   纹理对象每当自动加载纹理数据   精灵节点在场景中,是可见的,并且是必需的   渲染场景。稍后,如果精灵从场景中删除或   不再可见,Sprite Kit可以删除纹理数据   需要那些记忆用于其他目的。这种自动内存管理   简化但不会消除您需要进行的管理工作   你游戏中的艺术资产。

     

纹理对象本身只是实际纹理的占位符   数据。纹理数据更加耗费资源,因此Sprite Kit会加载   只在需要时才进入记忆。

     

如果您已有SKTexture对象,则可以创建新纹理   引用它的一部分。这种方法很有效,因为   新纹理对象在内存中引用相同的纹理数据。

答案 1 :(得分:1)

尝试使用以下代码删除它们:

override func update(currentTime: CFTimeInterval) {

    self.enumerateChildNodesWithName("nodeName") {
        node, stop in
        if (node is SKSpriteNode) {
            let sprite = node as SKSpriteNode
            // Check if the node is not in the scene
            if (sprite.position.x < -sprite.size.width/2.0 || sprite.position.x > self.size.width+sprite.size.width/2.0
                || sprite.position.y < -sprite.size.height/2.0 || sprite.position.y > self.size.height+sprite.size.height/2.0) {
                    sprite.removeFromParent()
                    println("outside")
            }
        }
    }

}

别忘了给你的节点命名:

node.name = "nodeName"

希望你的崩溃停止