Accessing tile animation data

May 11, 2013 at 8:21 AM
Hi!
Been using tIDE and it works very well. I've decided however to use my own code for rendering in XNA, and i'm having trouble figuring out how to access animation data for a tile. I want access to the actual frame indices of an animated tile.

From what I can tell, Tile.Properties is only for custom properties set in the editor for a given tile. Tile.TileIndexProperties would seem like it could prove helpful but it is always empty.

Anyone had any luck with this?

/Jakob
Coordinator
May 12, 2013 at 6:42 PM
Animation data is not stored in the form of custom properties, but as an <Animated ... /> tag as in the following example:
<Animated Interval="100">
    <Frames>
        <TileSheet Ref="TileSheet01" />
        <Static Index="56" BlendMode="Alpha" />
        <Static Index="57" BlendMode="Alpha" />
        <Static Index="58" BlendMode="Alpha" />
        <Static Index="57" BlendMode="Alpha" />
    </Frames>
</Animated>
The above is the actual data for the waterfall tile animation used in the demo code.

Here you can see that the <Animated> tag specifies a frame interval in milliseconds (100ms in this case). It contains a <Frames> child element that in turn contains a mix of <TileSheet> and <Static> child elements. The <TileSheet> tag is required whenever a tilesheet is changed (you might have more interspersed within the <Frames> tag if the animation spans several tilesheets. The <Static> tag essentially refers to a particular tile by index (assuming the last specified tilesheet) and the BlendMode specifies the blending mode to be applied (xTile supports Alpha and Additive blending). Note that the <Static> tag is identical to the one used for regular non-animated tiles, except that when specified within an <Animated> tag, they describe one particular frame within the animation.

Hope that helps.
May 14, 2013 at 7:24 PM
Cool! I've looked through my map (.tide) file with a text editor and can indeed see the xml structure you described.

I guess one way to access the data would be to parse this file and extract the animation data, or perhaps rewrite the custom content importer that you wrote. Am I right though that there's currently no way to access this data through the provided api?

Example psedo code:
Tile t = tileMap.GetLayer(layerName).Tiles[x, y];
var animation = t.GetAnimation(); //or something similar?

/Jakob
Coordinator
May 15, 2013 at 10:02 AM
Tile is actually a an abstract base type so in actual fact you will get either a StaticTile or AnimatedTile instance (both being derived from Tile).

Keep also in mind that Tiles[x, y] can return a Null instance when there is no tile at the given coorodinates, so you will need to check for this.

So basically you have two approaches to get the tile details:
1) Check the type of the returned Tile (if not null) to determine if it is a StaticTile or AnimatedTile, and downcast the tile accordingly. In the case of a static tile, you can access the corresponding TileSheet and TileIndex properties. In the case of an animated tile, you can access a Frames collection property and determine the current frame yourself. An individual tile frame is actually an instance of StaticTile.

2) If you invoke Map.Update(...), which takes care of the animation timings, you need not downcast the Tile to either of the above classes. You can instead simply get the TileSheet and TileIndex properties from the Tile instance. If the tile is an animated one, it will actually give you the tile sheet and index corresponding to the current animation frame.

I think option (1) is messier (due to the type checking and downcasting) and more complex to implement, whereas option (2) is both cleaner and simpler.

On a related note, is there a reason why you wish to implement the rendering code yourself. Did you experience any performance issues or found the API limiting?
May 15, 2013 at 3:10 PM
It looks like this is exactly what I needed. I'll check it out when I get the chance :)

The reason why I'm doing the rendering myself is that I've already begun writing platformer game using my own rendering engine. I'm using a quad with animated uv coordinates for sprites (such as the player) and use a camera (so it is actually all done in 3d, only the assets are all quads and the camera projection is orthogonal). It appeared difficult to marry this approach with your spritebatch implementation for the level. Further, working in full 3d seems to me to give many benefits for free such as easy camera zooming. I'm unsure how one would go ahead and implement particle effects and screen space effects easily using spritesheet. Primarily, i'm much more comfortable working in full 3d and have little experience with xna spritesheet.

For these reasons, I didn't work alot with your rendering code and can't really comment on the api or performance. From what I did try, I had no issues at all.
I might reconsider and rewrite my rendering code using xna spritesheet and use it together with your code.

Thanks again for the help and thanks a lot for tIDE, it has really helped me along!
/Jakob
Coordinator
May 15, 2013 at 5:14 PM
Thanks for clarifying. Depending on how much time you have invested in your rendering engine, you might want to write your own implementation for IDisplayDevice. IDisplayDevice is intended to abstract the tile engine from the underlying graphics api. The project's codebase has a spritebatch and a gdi+ implementation you might want to look at. Obviously you know what's best for your project but I thought this might be a viable option.

Hope that helps
Colin
May 15, 2013 at 8:50 PM
Hmm for sure something to think about. I'm going to look into that. :)

/Jakob