Large texture atlas causes termination due to memory pressure
I am developing a game in iOS Swift.
I have a large texture atlas of about 100 1920x1080p PNG. When I call the functions it crashes the application due to memory pressure. When I disable the feature, my application works fine.
Can I prevent this crash by editing my code, or is my texture atlas too big?
code:
var waterWave: SKSpriteNode!
var waterWalkingFrames : [SKTexture]!
func addWater() {
let waterAnimatedAtlas = SKTextureAtlas(named: "water.atlas")
var waterFrames = [SKTexture]()
let numImages = waterAnimatedAtlas.textureNames.count
for var i=0; i<numImages; i++ {
let waterTextureName = "water_000\(i)"
waterFrames.append(waterAnimatedAtlas.textureNamed(waterTextureName))
}
self.waterWalkingFrames = waterFrames
let firstFrame = waterWalkingFrames[0]
self.water = SKSpriteNode(texture: firstFrame)
self.water.anchorPoint = CGPointMake(0.5, 0.5)
self.water.position = CGPointMake(CGRectGetMidX(self.frame), self.runningBar.position.y + (self.runningBar.size.height / 2) + 5)
self.water.size.width = self.frame.size.width
self.water.size.height = self.frame.size.height
self.water.zPosition = 7
self.addChild(self.water)
waterAnimation()
}
func waterAnimation() {
self.water.runAction(SKAction.repeatActionForever(
SKAction.animateWithTextures(waterWalkingFrames, timePerFrame: (1 / 60), resize: false, restore: true)), withKey:"surferBasic")
}
This kind of animation would always be expensive, even if you've optimized the textures in some way (like changing the texture format ). The 1920x1080px texture takes up about 8 megabytes when using the standard RGBA8888 format when stored in RAM, and as you said due to device memory constraints , the app will crash at some point.
In this situation, if your animation allows you to do this, a good way would be to make a video and then use SKVideoNode to play it. It's even recommended in the docs just because textures can be expensive in some situations:
Like any other node, you can put the movie node anywhere inside the Tree node and the Sprite Kit will do it right. For example, you can use a video node to animate visual behavior, which would be expensive to define with a set of textures.
This would be the right way for background animations, cut scenes, intro ...
For video looping, you can use AVPlayer to initialize SKVideoNode with it . More details here . I suggest you do this because SKVideoNode is only limited to the play () and pause () methods for controlling video playback.
Hope this helps and makes some sense!