Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Dids

Pages: [1]
1
iOS / Texture Atlas Tutorial
« on: Fri, Apr 27, 2012 »
Recently I noticed that Canabalt uses texture atlases instead of individual sprites and upon researching these further, I noticed that they (supposedly) have an impact on performance, especially in flixel-ios's case, because you can preload (cache) them on startup, so they only have to be loaded in to memory once.

After much trial and error, I found the right "path" to succesfully using texture atlases on all iOS devices, using the latest iOS SDK and latest XCode. The following tutorial is based on what worked for me.

1. Get an app that produces atlases. I experimented with many (including TexturePacker and ShoeBox) but ultimately went with the one that worked the best: Zwoptex. The free version should do just fine.

2a. Get all your sprite graphics ready and import them in to Zwoptex.

2b. It's important to note that you need to (I had to) fit everything inside a 512x512 texture atlas, so in case they just won't fit, you'll have to create multiple atlases and link them together (which is what I did), more on this later.

3. In Zwoptex, select all your sprites and uncheck the Trim(med) option, we don't want that. Also set all padding/margins/etc to zero (0). Remember to set the width and height to 512, as previously discussed.

4. Open up Zwoptex preferences, open up the Coordinates Formats tab and click the + sign to add a new format. I named mine Flixel iOS. Set the extension to .plist and paste the following in to the source box.
Code: [Select]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>images</key>
<dict>{% for sprite in sprites %}
<key>{{ sprite.name }}</key>
<dict>
<key>atlas</key>
<string>{{ metadata.target.textureFileName }}{{ metadata.target.textureFileExtension }}</string>
<key>x</key>
<real>{{ sprite.textureRectX }}</real>
<key>y</key>
<real>{{ sprite.textureRectY }}</real>
<key>width</key>
<real>{{ sprite.sizeWidth }}</real>
<key>height</key>
<real>{{ sprite.sizeHeight }}</real>
</dict>{% /for %}
</dict>
</dict>
</plist>

5. Close the Preferences window and click on the big Layout-button in the upper left corner. This will automagically move your sprites around to fit the space of the atlas. Remember, if it seems like it's unable to fit them (ie. most of them are top of eachother in the upper left corner), remove some of them and add the removed sprites to a new atlas (using the same settings as before).

6. Once the layout process is done and it looks like it worked, click on Publish Settings in the upper right corner. For simplicitys sake, I changed the Save To File fields of both the atlas and the plist to say "MyAtlas.png" and "MyAtlas.plist", just seemed easier that way. From the Format-dropdown menu, select the previously created Flixel iOS format template and click Done.

7. You're ready to Publish, so go on ahead and click that big button (you've already set up the Publish Settings, so if it warns you about them, just click Done).

8. Repeat this process for any extra atlases that you might need, I separated my big and small sprites, so I had two atlases (SmallAtlas.png/plist & BigAtlas.png/plist).

9a. As Zwoptex doesn't seem to support multiple texture atlases using only one plist, we'll need to do a bit of work here.

9b. Open up your favorite text editor and open all of the plist files of the previously created atlas(es).

9c. Create a new file (I called mine CombinedAtlas.plist), which will hold all the atlas data combined. You'll need the basic plist structure, but you'll also need to copy and paste the relevant data from all of the plist files you've previously created. To recap: you'll create a plist template, then fill in the items from all the atlas plists you have, it should be pretty simple. Here's something to visualize that a bit better.
Code: [Select]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>images</key>
<dict>
<key>BigSprite.png</key>
<dict>
<key>atlas</key>
<string>BigAtlas.png</string>
<key>x</key>
<real>160</real>
<key>y</key>
<real>0</real>
<key>width</key>
<real>32</real>
<key>height</key>
<real>224</real>
</dict>
<key>SmallSprite.png</key>
<dict>
<key>smoke.png</key>
<dict>
<key>atlas</key>
<string>SmallAtlas.png</string>
<key>x</key>
<real>464</real>
<key>y</key>
<real>74</real>
<key>width</key>
<real>16</real>
<key>height</key>
<real>16</real>
</dict>
</dict>
</dict>
</plist>

10. You're almost there! Add (copy) the CombinedAtlas.plist and both the SmallAtlas.png and BigAtlas.png to your XCode project (leaving the Small/Big plists out, because we don't need those anymore).

11. Open up your AppDelegate and mofify the preloadTextureAtlases() function like seen below.
Code: [Select]
void preloadTextureAtlases()
{
    NSDictionary * infoDictionary = nil;
    infoDictionary = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"CombinedAtlas.plist"]];
    NSDictionary *images = [infoDictionary objectForKey:@"images"];
    for (NSString *image in images)
    {
        NSDictionary * imageInfo = [images objectForKey:image];
        CGRect placement;
        placement.origin.x = [[imageInfo objectForKey:@"x"] floatValue];
        placement.origin.y = [[imageInfo objectForKey:@"y"] floatValue];
        placement.size.width = [[imageInfo objectForKey:@"width"] floatValue];
        placement.size.height = [[imageInfo objectForKey:@"height"] floatValue];
NSString * atlas = [imageInfo objectForKey:@"atlas"];
        SemiSecretTexture * textureAtlas = [FlxG addTextureWithParam1:atlas param2:NO];
        SemiSecretTexture * texture = [SemiSecretTexture textureWithAtlasTexture:textureAtlas offset:placement.origin size:placement.size];
        [FlxG setTexture:texture forKey:image];
    }
}

12. Make sure you're calling it in the AppDelegate's didFinishLaunchingWithOptions function after you've initialized your game and before returning YES.

13. You're welcome. (yes, that's it, no more steps!)

Hopefully I didn't forget anything, as I just figured all this out myself, so writing it mostly out of memory. :-)

2
iOS / iPad 3 & Texturebuffer Zooming
« on: Tue, Apr 17, 2012 »
As it stands, flixel-ios doesn't support the new iPad (3), as the previously working iPad solution has been to double the texturebuffer(s), but with the release of the new iPad, that texturebuffer would have to be quadrupled.

Has anyone succeeded in this yet?

3
help / FlxTilemap and FlxTileBlock
« on: Wed, Aug 17, 2011 »
Hey guys,

I'm a bit confused about FlxTilemap, as I need to access individual tiles as sprites, mainly so I can set their alpha value manually.

Does FlxTilemap contain the tiles as FlxTileBlocks and if not, is there a handy way of doing this so I could access them?

My tilemap is 500x500 at the moment, so it's pretty big and takes a while to load.

EDIT: I guess I could draw duplicate tiles with preset transparency, but that seems a bit hacky and overcomplicated.
EDIT2: Also, on a somewhat related note, how would I go about setting the tile graphic to be bigger than the actual tile size? Ie. tile would be 16x16 but the graphic would be 16x20.

4
help / [Flixel 2.5] onFocus crashing FlxSound
« on: Mon, May 16, 2011 »
So, I've been able to reproduce some weird behavious with the way the loss of focus/gained focus detection handles pausing sounds.

I'm playing a looping music track on the background via just FlxG.play(track) and doing the same for all the other sound effects.
If I do an action in-game that causes a sound to start playing, then click outside the play-window, the game pauses just like intended, however, when I click back in FlxSound crashes on the following line:

Code: [Select]
channel = _sound.play(0,9999,_transform);
With a typical Cannot access a property or method of a null object reference.

Am I supposed to handle the sound pausing myself, or is this indeed a bug?

5
help / 2.50 & "fixed" collisions
« on: Thu, May 5, 2011 »
I noticed that setting an object's fixed collisions is gone.

How would I go about implementing collisions where objects simply stop when they collide?

Even though the docs say that setting an objects mass only affects elasticity, setting elasticity to 0 and mass to something really big does make a difference.

At the moment I have several blocks that are supposed to "stack" on top of eachother, without any bounciness, jitter and such.

6
help / Flixel 2.50 & Pausing
« on: Tue, May 3, 2011 »
So, what happened to pausing with the new Flixel release? :-)

Looking to either customize the pause screen or disable it altogether, but there aren't any posts about pausing in 2.50, so I'm a bit lost here.

Pages: [1]