Use multiple asset folders in xCode - ios

So I am working on a game in SpriteKit. I have a function that generates a level for the player.
The function uses images placed in assets.xcassets to generate levels. The game has multiple themes , namely fire water and electricity. Each theme has its own set of images with the same names but each theme image set is in its separate folder/group. Is it possible for me to programmatically tell the function to use a specific folder so that I can generate levels for other themes without renaming images. Or is it possible for me to use multiple asset folders and change which one the function uses at runtime. I want to use a random theme every time the player restarts the level.

Sprite Atlas / Sprite Sheet
You can use a Sprite Atlas (also known as Sprite Sheet).
If you don't know what I'm talking about have a look at these 2 nice videos:
Sprite Sheets - The Movie Part 1
Sprite Sheets - The Movie Pt. 2 - Performance
How to use it
If you have watched the videos now you know that the main target of a Sprite Atlas is loading into the GPU all and only (as far as possible) the images needed for the current scene or level. This way drawing each frame becomes much faster because all the resources al already on the GPU and the CPU only needs to transmit the coordinates.
Namespace
Ok but how does it solve your problem?
Xcode allows you to create a namespace for each Sprite Atlas. So you can use the same name for resources in different Sprite Atlas.
How to create a Sprite Atlas.
This is pretty simple.
With Xcode open you Asset Catalog
Tap on the + button you see in the image below
Click on New Sprite Atlas
You'll se a new "Folder", that's your Sprite Atlas.
5. Now click on the Provides Namespacecheckbox on the right.
That's it. Now just drop your images into the Sprites folder in order to add them to your sprite atlas.
In this example I'm going to rename the Sprite Atlas as Sprites0 and will add a red circle named circle.
Then
will create another Sprite Atlas
will check again the Provides Namespacecheckbox
will name Sprites1
and finally will add a green circle names circle.
Here's the final result
Code
Let's see now how to use it.
import SpriteKit
class GameScene: SKScene {
override func didMove(to view: SKView) {
let textureAtlas0 = SKTextureAtlas(named: "Sprites0")
let texture0 = textureAtlas0.textureNamed("circle")
let sprite0 = SKSpriteNode(texture: texture0)
sprite0.position.y = 100
addChild(sprite0)
let textureAtlas1 = SKTextureAtlas(named: "Sprites1")
let texture1 = textureAtlas1.textureNamed("circle")
let sprite1 = SKSpriteNode(texture: texture1)
sprite1.position.y = -100
addChild(sprite1)
}
}
Result
How does it work
Step 1: you load the Sprite Atlas
let textureAtlas0 = SKTextureAtlas(named: "Sprites0")
Step 2: you load a specific texture from the texture atlas
let texture0 = textureAtlas0.textureNamed("circle")
Step 3: you use your texture as you want
let sprite0 = SKSpriteNode(texture: texture0)
sprite0.position.y = 100
addChild(sprite0)

Related

iOS: Can I use Texture Atlas already created with Adobe Animate?

I know that I can add sequences of individual images in Xcode, and let it create the Texture Atlas. This process is well-described in easily-searched venues. (Like this one.)
I am getting atlases from designers, created with Adobe Animate (v18.0) already combined into the full sheet, and moreover with the accompanying XML file describing the animation. (In which sub-images and display frames do not match 1:1, so it's hard to see how Xcode would figure that out.)
It's not clear to me from the SpriteKit docs whether/how to use these pre-defined Texture Atlases. Is this possible?
If you're getting pre-baked texture atlases, with externally-generated descriptions of where the sprites should get their textures, you'll probably have to create your sprites using SKTextures that you create using the init(rect:in:) initializer of a SKTexture.
You'll need to read the sprite's extents out of the XML file, and then create a texture out of the atlas. Then you can create a new SKTexture object that represents a part of the larger texture to act as your sprite's texture.
This is untested pseudocode, but it shows the process:
let spriteRect = (get the rect from the XML)
let atlas = SKTexture( imageNamed: "myTextureAtlas" )
let spriteTexture = SKTexture( rect:spriteRect, in:atlas )
let sprite = SKSpriteNode( texture:spriteTexture )
Once you have this process in place, you can animate the sprites using the usual methods, like setting up SKActions with a list of textures out of the texture atlas.

Preloading textures in SpriteKit

I've done some research and I can't seem to find anything that clearly explains how to go about preloading both single textures and textures within animations. I'm currently using Atlas's in Assets.xcassets to group related animation images. Does having my images in the Atlas mean that they are preloaded? As far as single images, does it make sense to declare the texture before GameScene like this: let laserImage = SKTexture(imageNamed: "Sprites/laser.jpg") and then (for example) within one of my SKSpriteNode subclass I can just pass laserImage through?
I ultimately wanted to know if there was a well defined way of going about this or if I should just store each texture as a constant before GameScene. Any advice on the proper (and most efficient) way of going about this would be great.
I tried to implement appzYourLife answer but it increased the time to load every texture. So I ended up putting all the most used Sprites in one single atlas and puting it in a singleton.
class Assets {
static let sharedInstance = Assets()
let sprites = SKTextureAtlas(named: "Sprites")
func preloadAssets() {
sprites.preloadWithCompletionHandler {
print("Sprites preloaded")
}
}
}
I call Assets.sharedInstance.preloadAssets() in menuScene. And:
let bg1Texture = Assets.sharedInstance.sprites.textureNamed("background1")
bg1 = SKSpriteNode(texture: bg1Texture)
to reference a texture already loaded in memory.
One Single Texture Atlas
Put all your assets into a single Sprite Atlas. If they don't fit, try at least to put all the assets of a single scene into a single Sprite Atlas
Preloading
If you want you can preload the texture atlas in memory with this code
SKTextureAtlas(named: "YourTextureAtlasName").preloadWithCompletionHandler {
// Now everything you put into the texture atlas has been loaded in memory
}
Automatic caching
You don't need to save a reference to the texture atlas, SpriteKit has an internal caching system. Let it do it's job.
Which name should I use to reference my image?
Forget the name of the file image, the name you assign to the image into Asset Catalog is the only name you will need.
How can I create a sprite from an image into a texture atlas?
let texture = SKTextureAtlas(named:"croc").textureNamed("croc_walk01")
let croc = SKSpriteNode(texture: texture)

How to make animated spritekit background?

I want to make animated space background in my game, i tried using nodes on spritekit "stars nodes" but the game become laggy because of the amount of the stars, is there any program or way to make HD animated background ?
You just need one node for the background ya know.
Basically, you create each frame of your animated background as images. You can put these images into an image atlas in the asset catalogue.
Now, you can add a single sprite node that covers the whole scene as the "background". You just set the texture of the sprite node to the first frame of your animation.
Then, in didMoveToView or some methods like that,
get your image atlas as an SKTextureAtlas object
get each texture in the atlas using textureNamed and put each of them into an [SKTexture]
Now you have the array, you can do something like this:
-
yourBackgroundSprite.runAction(SKAction.repeatForever(
SKAction.animateWithtextures(theTexturesYouCreatedInStep2, timePerFrame: 30)
))
This link might also help you.

Using my own alternate images to those in the "SpriteKit with Swift" Tutorial in Xcode 7 Swift 2 Project

I am fairly new to programming and, as such, am still in the follow-the-tutorials stage of coding. Specifically, my most recent undertaking is "SpriteKit with Swift" (had to delete this link because I don't have 10 reputation)
Anyway, my issues lie with images. I have been doing everything else in accordance with the tutorial, but I wanted to use my own images for the SpriteNodes instead of the satellite and asteroid. Additionally, I want to set a specific image as my background, but every time I go about that I see that image alone in the Simulator. I just don't want to make the game verbatum; I want my own twist.
I am using Swift 2 in Xcode 7
Thanks in advance
this is what came up whilst I was putting in the background
this is what my GameScene looks like
Always try to post code when using stack overflow. I am not 100% sure this is what you are asking but Ill give it a shot.
By default SpriteKit optimises how it adds sprites.
skView.ignoresSiblingOrder = true // in gameViewController
This should stay true most likely because it optimises SpriteKits performance. It basically means sprites will not always get added to the SKScene in the order you are adding them to the scene.
You need to start using zPosition when layering multiple images in a scene with a defined order.
To add a background you would do this
let background = SKSpriteNode(imageNamed: "image name in asset catalogue"
background.zPosition = 1 // 1st layer
background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
addChild(background)
To add sprites on top of the background you would do this
let sprite1 = SKSpriteNode(imageNamed: "image name in asset catalogue"
sprite1.zPosition = 2 // above background
sprite1.position = ...
addChild(sprite1)
let sprite2 = SKSpriteNode(imageNamed: "image name in asset catalogue"
sprite2.zPosition = 2 // if 3 also above sprite 1
sprite2.position = ...
addChild(sprite2)
I presume this is whats causing your problem, you are adding a background but the sprites after are not visible because they are below the background.

How to use a sprite sheet in swift and sprite kit?

Title says it all. How do i use a sprite sheet in swift and sprite kit? I've searched google, stack exchange, and the apple documentation and I can't figure this one out.
In xcode 7, you can use Images.xcassets to create a sprite atlas.
Click on Images.xcassets
Click on the plus bottom in the bottom left
Select "new sprite atlas"
Then you can drag and drop all your images into the atlas
If you drag in all three image sizes with the proper suffix (#2x and #3x) it will automatically populate the images for you.
Then to use these assets in code simply write:
let atlas = SKTextureAtlas(named: "Sprites")
let texture = atlas.textureNamed("ball")
let sprite = SKSpriteNode(texture: texture)
you can be less specific and just specify a texture:
let texture = SKTexture(imageNamed: "ball")
let sprite = SKSpriteNode(texture: texture)
If you're looking to use an already created sprite sheet, check out this answer on SO: Using sprite sheets in xcode.

Resources