Using Starling Tiles for large game levels

Hello, my name is Nick and I’m going to show you how to use the Citrus Engine’s tile system allowing you to create large game backgrounds.

Sometimes you will want to create levels that are larger than the maximum texture size allowed when using Starling, and converting that 5000 pixel wide background into tiles can be greatly simplified! The TileSystem is setup as the view property of a CitrusSprite. When you create the TileSystem you can use one of 2 methods of loading your graphics in.

  • From a strictly code approach, the TileSystem brings in a 2D array of tile images you have sliced in photoshop. It will arrange and place the tiles for you. This option also allows ATF files for better performance and a smaller GPU memory footprint.
  • In your level layout swf you can place a MovieClip on stage for the TileSystem to convert for you! The TileSystem will take your MovieClip (well, sprite since it can’t have a timeline) with vector or bitmap graphics, convert it to a BitmapData and slices it into tiles of a size you specify. This is a great way to get all of your artwork in one place!

So let’s go over both!

Adding backgrounds via a Sprite

In the CitrusEngine example files, have a look at starlingtiles_demo.fla in the fla directory. On the main timeline, the bottom 3 layers are movieclips with names “tile_background_0″, “tile_background_1″ and “tile_background_2″. Put whatever you want in here, just make sure the graphics don’t bleed outside the bounding rectangle and the registration must be top left.

Now on to the code that puts them together in the StarlingTilesGameState state.

var tileSprite:CitrusSprite = new CitrusSprite("tile_bg_sprite_0", { x:0, y:0, parallax:0.6 } );
var tileSystem:StarlingTileSystem = new StarlingTileSystem(MovieClip(_level.getChildByName("tile_background_0")));
tileSystem.parallax = 0.6;
tileSystem.name = "tile_bg_tiles_0";
tileSystem.tileWidth = 2048;
tileSystem.tileHeight = 1024;
tileSystem.blendMode = BlendMode.NONE;
tileSystem.touchable = false;
tileSystem.init();
tileSprite.view = tileSystem;
tileSprite.group = 0;
add(tileSprite);

There are some variables required for setup.

  • Sprite or MovieClip object for the constructor
  • Tile sizes – adjust for the target devices and your level size. The Starling wiki has great tips on optimizing this, but mostly you want as few tiles as possible, as big as possible. Try to make your total level size divisible by your tile size, like I’ve done here with the level being 4096 x 1024.
  • blendMode is set to BlendMode.NONE on the bottom layer only.

When init() is called, the MovieClip is divided into tiles and you’re done!

Adding backgrounds via a 2D array

Now let’s take the same level and divide it up a bit more to show the 2D array. In the StarlingTilesArrayGameState state you have this:

var tileSprite:CitrusSprite = new CitrusSprite("tile_bg_sprite_0", { x:0, y:0, parallax:0.6 } );
var tiles:Array = MyTiles.tile_0;
var tileSystem:StarlingTileSystem = new StarlingTileSystem(tiles);
tileSystem.parallax = 0.6;
tileSystem.name = "tile_bg_tiles_0";
tileSystem.blendMode = BlendMode.NONE;
tileSystem.touchable = false;
tileSystem.init();
tileSprite.view = tileSystem;
tileSprite.group = 0;
add(tileSprite);

This code is nearly the same. The tiles Array comes from the MyTiles class, which is just a class full of embedded bitmap files. I used jpg for the bottom layer (which take up less memory on the gpu) and png’s for the rest. I won’t paste all the code here but make sure to take a look in the source files. It arranges the tiles as so:

public static const tile_0:Array = [[tile_0_01, tile_0_02, tile_0_03, tile_0_04],
[tile_0_05, tile_0_06, tile_0_07, tile_0_08]];

Where tile_0_01 is the top left tile and tile_0_08 is the bottom right tile. I also removed the tileWidth and tileHeight properties, the TileSystem will figure that out as long as you keep all the tiles the same size as each other.

ATF: get more with less

If you’re using a tile array, you can also pass it embedded ATF data and set tileSystem.atf = true before you call init()

This is a very cool option if it works with your textures. Try them in ATF and if they don’t look good, use the regular jpg and png files. The example level didn’t look good because the compression wasn’t kind to the pixelated graphics. Your mileage will vary.

Have a look at StarlingTilesATFGameState in the demo files for an example. If you haven’t used ATF yet I would have a look here and here for help.

That’s it! 2 easy ways to make some big levels and one way to make really big levels.

Note: There is also functionality in the TileSystem to load and unload tiles depending on their distance from the camera, enabling even larger levels but this operation can take 20-30 ms on a desktop computer (a very long time if you’re pushing for 60 fps!) and upwards of 2 seconds on an iPhone when using png files. If I find a way to help this I will update this tutorial.

10 thoughts on “Using Starling Tiles for large game levels

  1. Great tutorial, Nick! This is Paul from the game jam, just trying to get in contact with you. You can delete this comment of you want. Hit me up on email or through tumblr when you get a chance.

    • Hi Paul! Thanks, it was great to meet you! I’ll shoot you an email. I’ll be posting some things on our game soon, I’d love to keep up with the progress of your game too!
      -Nick

  2. Hi, I’ve been porting a game we did at a game jam to mobile, and I have had troubles with this. “Out of the box” (almost) the game worked great on my iPad2 but it crashed on all iPhones.

    I quickly found out that it was because the “tiling” background used too much VRAM. I thought that was logical since we used flash as some kind of level editor, with a movieClip making up the level background. Since the MC gets cut and textures created from it I thought “ok I’ll just switch to providing a list of bitmaps”

    Before I did I looked at the StarlingTileSytem code and was surprised to see that the code didn’t track bitmaps to re-use textures : it creates a new texture for every tile !

    Is there any reason for this ?

    I quickly wrote a simple class for testing : it takes a Vector of textures and a Vector of Vector of ints that are just texture indexes, the code is very simple.

    Result is now it works on every device I tested, and the level loads *much* faster. Performance seems to be exactly the same : great.

    So I’m just wondering if I missed something, is there any problem/flaw doing it that way ?

    • Hello and thanks for your feedback!
      Yes, this is not designed for use with repeating backgrounds. Repeating backgrounds would be best implemented using methods from other demos in the Citrus Engine package. This is a good example here: http://citrusengine.com/bin/Citrus-Engine-Mobile-Nape-Starling.html
      This tile system was designed for levels with unique content. A good example of this is a game like Rayman Origins, the artwork is very elaborate and doesn’t repeat as much as other games.

      I am imagining something a little different for this. If you have your movieclip for use as a TileSystem, and we loop through all the children of that movieclip, creating new textures for each unique object in the movieclip and re-using anything that repeats. This would recycle things like platform textures while still allowing you to add elaborate artwork. What do you think?

      • Hey Nick !

        Thank you so much for the quick and detailed answer. I’m gonna have a look at the example you pointed me to.

        We used the movieclip technique because it was a game jam and I was just discovering citrus : it was a blazing fast and effective solution, I just had to code a function that loops in the children, ignore the background and create corresponding platforms / hero / baddies. Then the StarlingTileSystem took care of the background and that just worked :)

        I won’t stick with this solution now, I can take some time to find or create a more appropriate one. I’d like to have it very generic to ease the way for possible future games with citrus.

        Still trying to reuse stuff in the movieclip would be cool for other users I think, although I’m not too sure as it would only really work when one uses a set of bitmaps and/or movieclips… I mean the movie clip solution lets the user go really “freestyle” : he can use a set of bitmap, and put other graphics on top of these or stuff like that.

        Then I guess it could turn out complicated, as before re-using anything you’d have to check for other graphic elements that could overlap… not sure if I’m clear, I didn’t put much thinking into this as my idea right now is more like creating a simple grid based editor with layers, each layer could have a different grid size… using the movie clip was great to get something out very quick but it’s not as efficient and can lead to problems like some platforms not exactly aligned because the designer was not careful enough etc

        sorry for the long answer, I think I’ll be back on the forum once I’m done looking at your example, if I still have questions ^^

        also Citrus ROCKS !

        • Ok I looked at the example’s source and that’s quite like what I have in mind. I think I’ll start writing my little level editor tool, and while I’m at it I’d like to make it easy to add to a citrus game and allow players to create their own levels :)

          I’ll keep you posted with the results.

          • Were you at the Game Jam in Chicago? I was there too! My friend Chris and I teamed up with a guy we met there, Jonah and we made the firefighter game. For a tile solution have you tried the Tile Map Editor? There are tutorials on that here, I have not used that method personally but Aymeric has some great info put together on it. I just like to use Flash Pro because I use it at work all day and know it pretty well. Sorry for the delayed response, it is a busy holiday season for me! When I have more time I will experiment more, I would like to improve the Flash Pro tools to be able to be more flexible and recycle more assets.

  3. Sorry just noticed your answer now Nick : I wasn’t in Chicago, too far from France :)

    I have tried some tile editors yeah but I’m looking for more flexibility, and I’d like to be able to easily provide players with in-game editors. Also have an easy and optimized workflow.

    So I’m still working on my own solution right now, been delayed by freelance work but still making good progress. When I have something ready, hopefully in a few weeks, I’ll look into making it open source and put it on a public github repo (currently on a private one) : I have no experience on that side so I may ask for guidance then ^^

  4. He Guys, i’m getting lost with the tileSystem, my tiles seemed to be scaled up quit a bit, but i can’t figure out how to get them to show 1 to 1 (pizel size is 768 height, but only about half is shown on a stage with a height of 768…

    • Hi,
      Can you post your code? Which method are you using? Are you bringing in the graphics from a movieclip in flash or through bitmaps? What are your parallax settings?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>