问题
I'm designing a game in iOS Swift.
I have a large texture-atlas of about 100 1920x1080p PNG's. When I call the functions it crashes the app due to memory pressure. When I disable the function my app runs just fine.
Can I prevent this crash by editing my code or is my texture-atlas just 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")
}
回答1:
Animation like that would be always expensive even if you optimize textures in some way (e.g. changing texture format). 1920x1080px texture occupies about 8 megabytes if using standard RGBA8888 format when stored in RAM memory and as you said, because of device memory limitation, 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 of it, and then to use SKVideoNode to play it. This is even recommended in docs just because using textures can be expensive in some situations:
Like any other node, you can put the movie node anywhere inside the node tree and Sprite Kit will render it properly. For example, you might use a video node to animate some visual behaviors that would be expensive to define using a collection of textures.
This would be a suitable way for background animations, cut scenes, intros ...
For looping a video you can use AVPlayer to initialize SKVideoNode with it. Read more here. I suggest you to do this because SKVideoNode is limited to just play() and pause() methods for controlling video playback.
Hope this helps and make some sense!
来源:https://stackoverflow.com/questions/30555313/large-texture-atlas-causes-termination-due-to-memory-pressure