I don't find a way to use this sort of images as tile set for my games.
Is there a way to do it, or should I add all object I want one by one ?
I tried to add a new Grid Tile Set then a Single Tile Group, but if I try to use this in a Tile Map Node, it will use all the image as texture for one block.
I don't know if it's possible, but if you can help me, I would be grateful.
Unfortunately you will have to separate the image into smaller images manually..
The functionality you want just doesn't exist.
You can use your image as a texture atlas, but you will not be able to use SKTextureAtlas, you will have to break them out your self.
If you look at SKTexture, you have an init called init(rect: CGRect, in: SKTexture). This will create a new SKTexture object for you, while still referencing the texture memory space of the original texture. You are just going to have to use something like a plist to load in all of the CGRRect info to create this atlas.
Example:
let textureAtlas = SKTexture(imageNamed:"CEm72.png") //I convert your jpg to png somehow
let rectDarkKnight = CGRect(x:0,y:96,width:32,height:32)
let texDarkKnight = SKTexture.init(rect: rectDarkKnight, in: textureAtlas)
Related
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.
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)
Apple recommends to use one SKTexture object if it will be used multiple times (https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKTexture_Ref/).
So I wanted to test if it is really passed as reference:
var fireSpriteTexture:SKTexture = SKTexture(imageNamed: "fire")
let fireSprite = SKSpriteNode(texture: fireSpriteTexture)
fireSprite.position = CGPointMake(50,50)
fireSprite.zPosition = 100
// Change texture -> We should see no fire
fireSpriteTexture = SKTexture(imageNamed: "water")
self.addChild(fireSprite)
In my understanding this swift code should make the water texture visible in my app BUT in fact the fire texture is placed on the screen.
Why? Is it a bug?
To make it more clear I would also like to know what happens if I init my node with SKSpriteNode(imageNamed: "fire") and then copy it with its copy() method, do both objects share the same "fire" resource?
I do not think you are understanding pass by reference correctly, you pass the reference of fire into your sprite, the sprite will then retain a reference of this texture.
You are changing the fire texture to a new texture with a new reference. This does not mean the sprite with the old reference is going to automatically change to the new reference.
If you want to check for reference, you want to compare the fire texture to the sprite texture, not create a whole new texture.
If you want to change the texture, then you need to edit the data of the texture without creating a new reference.
Is it posible to create a drawable object out of some other drawable objects? And How would I do it?
Use a Canvas and draw the smaller images into it.
bigger = love.graphics.newCanvas(100, 100)
bigger:renderTo(function()
-- draw images here using love.graphics.draw etc...
end)
and then later use the canvas instead of the smaller images:
love.graphics.draw(bigger)
First of all, I would like to say that I'm fairly new to AS3, so feel free to correct me when needed.
So I'm trying to create a moving background, made out of different types of isometric tiles, like a floor or a wall, disposen in a grid like fashion.
At first, I tried creating a symbol containing the floor and the wall on different frames, and alternate between the frames as needed. Then I would add multiple instances of this symbol to a container and move the container around. Quickly I realized that this probably wouldn't be an ifficient method, as confirmed by the unsmooth movement of the container. (I gave up on this method).
So I did a little digging around, and then I converted the tile symbol to a png file, created a bitmap container to where I would copyPixels from the png as many times as the map required it.
The problem now is that when I do this:
var pngBitmapData:BitmapData=new tilePng
the bitmapData height and width don't match the height and width of the actual tile. There seem to be some transparent pixels around the tile and I have no idea how to remove them. This causes the tiles to be misaligned on the background's grid, with some small empty spaces around them.
So I have a couple of questions:
Is this an effective way to build the background?
Is there a way to avoid that transparent pixels "problem" ?
Hmm, it's hard to tell without seeing your png.
Are you doing this?
var pngBitmapData:BitmapData = new tilePng();
var bmp:Bitmap = new Bitmap(pngBitmapData);
To initialize your bitmap?
Also, check the anti-aliasing on your bitmap, that could be it. I'd set it to none.