我必须删除一个精灵节点,一旦我结束使用它



我正在场景中创建一系列移动管道。但它总是在生成大约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}
    }
}
}

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

SpriteKit编程指南

将创建一个SKTexture对象并将其附加到精灵。这只要sprite节点在场景中,可见,并且对于渲染场景。稍后,如果精灵已从场景中移除,或者不再可见,精灵套件可以删除纹理数据,如果需要该内存用于其他用途。这种自动内存管理简化但不会消除管理所需的工作游戏中的艺术资产。

纹理对象本身只是实际纹理的占位符数据纹理数据更耗费资源,因此Sprite Kit会加载只有在需要时才将其存储到内存中。

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

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

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"

希望您的崩溃将停止

最新更新