I'm new to ios game development field.
I have been going through the following apple tutorial multiple times but not getting the points
https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html
thanks
Directly from the SKTextureAtlas class reference :
Texture atlases can improve memory usage and rendering performance. For example, if you have a scene with sprites drawn with different textures, Sprite Kit performs one drawing pass for each texture. However, if all of the textures were loaded from the same texture atlas, then Sprite Kit can render the sprites in a single drawing pass—and use less memory to do so. Whenever you have textures that are always used together, you should store them in an atlas.
SKTextureAtlas Class Reference
animation can be hundred of files. atlas puts them in one large file.
reading one file (large with lots of images) is much more efficient then reading hundreds of files (with one image each)
rendering of one large image and then showing only part of it is much more efficient then rendering each file separately.
Related
I use SKScenes for different screens of my main menu. Each of these screens is rather complicated, sporting dozens of elements.
So each time user moves between those screens there is like 1-2 second lag before going next scene or previous scene as I recreate them each time.
Should I just store my scenes in some singleton after they are created so that next calls are faster?
Is it a good thing to do? Won't it be too memory-heavy?
Some optimization tips:
1) Your biggest memory hog is going to be the graphics. To keep this under control, use SKTexture object with a texture atlas. Always use a texture atlas because:
Texture atlases can improve memory usage and rendering performance. For example, if you have a scene with sprites drawn with different textures, Sprite Kit performs one drawing pass for each texture. However, if all of the textures were loaded from the same texture atlas, then Sprite Kit can render the sprites in a single drawing pass—and use less memory to do so. Whenever you have textures that are always used together, you should store them in an atlas.
2) Create your texture atlases based on levels so you do not use up memory for nothing. In other words, create an atlas for level 1, another one for level 2 and so on. According to the docs:
For a larger game, you may need to split the textures into levels or themes. Each level or theme’s textures are designed to fit in a specific amount of memory. When the player starts a new level, you preload all of that level’s texture objects. When the player finishes playing the level, the textures not needed for the next level are discarded.
3) You can use a (SKSpriteNode) singleton if you have a lot of the same animations used in different scenes. For example, an enemy present in all levels who has animations for idle, walking, running, jumping, attacking, etc... The same singleton can load all of your texture alases for your animations. You can also use a singleton to store all of your game sounds and thus further reduce load times but keep an eye on memory usage if you have a lot of sounds/music.
4) Setting the skView.ignoresSiblingOrder = YES; also gives an optimization boost. According to the documentation:
The default value is NO, which means that when multiple nodes share the same z position, those nodes are sorted and rendered in a deterministic order. Parents are rendered before their children, and siblings are rendered from eldest to youngest. When this property is set to YES, the position of the nodes in the tree is ignored when determining the rendering order. The rendering order of nodes at the same z position is arbitrary and may change every time a new frame is rendered. When sibling and parent order is ignored, Sprite Kit applies additional optimizations to improve rendering performance. If you need nodes to be rendered in a specific and deterministic order, you must set the z position of those nodes.
5) If your images do not absolutely require alpha, do not include it in your images.
6) Remove nodes from the parent if you no longer need them. Also make sure you remove any reference to them such as inclusion in any arrays. The rest is taken care of by SpriteKit as stated in the docs:
An SKTexture object is created and attached to the sprite. This texture object automatically loads the texture data whenever the sprite node is in the scene, is visible, and is necessary for rendering the scene. Later, if the sprite is removed from the scene or is no longer visible, Sprite Kit can delete the texture data if it needs that memory for other purposes. This automatic memory management simplifies but does not eliminate the work you need to do to manage art assets in your game.
In other words, delete a SKTexture object by removing any strong references to it, including:
All texture references from SKSpriteNode and SKEffectNode objects in your game
Any strong references to the texture in your own code
An SKTextureAtlas object that was used to create the texture object
I am making a test xna game as a learning exercise and I have a small question about using 2d textures. Basically the game is a grid of different 'tiles' which are taken from a text map file. I basically just parse through the file when initializing a level and create a matrix of the different tile types. The level is essentially a tub of wall tiles and spikes. So essentially, there are lots of wall tiles and multiple spike tiles and then lots of empty tiles. However, there are four types of wall tile and spike textures to cover different directions.
My question is what is the best way to load the textures for each of the tile? Do I load individual textures for each tile? i.e when I create a tile, pass it a texture2d which I can draw and load the texture at the same time. This seems like a good way, but then I have to load each tiles texture individually and this seems wasteful.
The other option I can think of is to use a static texture in the tile struct an then simple load this texture as a tile atlas with the different walls and spikes. This way I am only loading a single texture, and then when drawing I just move a rectangle to the area of the appropriate tile within the sprite.
I am not sure which of these ways would be optimal from a performance perspective, or if there is an alternative approach?
Thanks in advanmce
The wonderful thing about the content pipeline is that when you do
Content.Load<Texture2D>("sometexture");
It doesn't load the Texture2D everytime. The content pipeline is smart enough to load it once and send back the same Texture2D for that texture everytime. It would actually be worse if you made the static struct.
I have a pool of CCSprites numbering 1200 in each of two arrays, displayGrid1 and displayGrid2. I turn them visible or invisible when showing walls or floors. Floors have a number of different textures and are not z-order dependent. Walls also have several textures and are z-order dependent.
I am getting about 6-7 frames when moving which is okay because its a turn based isometric rogue-like. However, I am also getting a small amount of flicker, which I think is performance related, because there is no flicker on the simulator.
I would like to improve performance. I am considering using an array CCSpriteBatchNodes for the floor which is not z-order dependent but am concerned with the cost of adding and removing sprites frequently between the elements of this array, which would be necessary I think.
Can anyone please advise as to how I can improve performance?
As mentioned in the comments, you're using multiple small sprite files loaded individually which can cause performance issues as there is wasted memory being used to store excess pixel data around each of the individual sprites. Each row of pixel data in an OpenGL texture must have a number of bytes totaling a power of 2 for performance reasons. Although I believe OpenGL ES under iOS does this automatically, it can come with a big performance hit. Grouping sprites together into a single texture that is correctly sized can be a tremendous boon to rendering performance.
You can use an App like Zwoptex to group all these smaller sprite files into a larger, more manageable sprite sheets/texture atlas and utilize one CCSpriteBatchNode for each sprite sheet/texture atlas.
Cocos2D has pretty good support for utilizing sprite sheets with texture atlases and converting your code to using these instead of individual files can be done with little effort. Creating individual sprites from a texture atlas is easy, you just call the sprite by name instead of from the file.
CCSpriteBatchNodes group OpenGL calls for their sprites together, a process known as batching, which causes the operating system and OpenGL to have to make less round trips to the GPU which greatly improves performance. Unfortunately, CCSpriteBatchNodes are limited to only being able to draw sprites for the texture that backs them (enter sprite sheets/texture atlases).
I am developing a game for iPhone retina enabled.
This game has alot of sprite sheets to be used.
MyQuestion which is better to use
pvr
pvr.gz
pvr.ccz
or normal png format
which is the best practice for using sprite sheets.
Counter-Question: Is it better to use a sports car or a pickup truck?
It depends on your particular use case. You'll use PNG if you can't afford any loss in quality. You'll use PVR if memory and rendering speed are of higher concern.
GZ and CCZ are simply compression algorithms that determine how well the data is packed and how fast it can be loaded. I hear that PVR.CZZ is the fastest to load.
Now, what made me curious is that you say you have "a lot of sprite sheets". Ideally you'll want to be using as few as possible (best: 1) sprite sheets in a scene. If you create a sprite sheet per game object you're approaching it the wrong way, sprite sheets (texture atlases) are not a tool to structure and categorize your image assets! Your goal should be to cram as many images as possible into a single sprite sheet (texture atlas) to improve rendering performance.
In some cases you'll even want to duplicate some of your images so that you can create a single texture atlas for the current scene (level) even if that means to duplicate some images in the other scenes.
I am loading a Texture2D that contains multiple sprite textures. I would like to pull the individual textures out when I load the initial Texture to store into separate Texture2D objects, but can't seem to find a method any where that would let me do this. SpriteBatch.Draw I believe should only be called from within a begin, end block right?
Thanks.
I am loading a Texture2D that contains
multiple sprite textures. I would like
to pull the individual textures out
when I load the initial Texture to
store into separate Texture2D objects.
You don't have to do this nor should you. Accessing a single texture is faster than multiple textures. Also, textures are stored in GPU texture memory. It just makes no sense to split it up.
You should instead focus on writing code that can access individual sprites within your sprite sheet. I suggest you have a look at how sprite based games work.
Here is a great tutorial video series that should help you out: tile engine videos