Flipping sprites, tiles and hotspots

Started by
1 comment, last by OrangyTang 16 years, 3 months ago
I came across an interesting little problem that I'd like to hear what other people think is the most intuitive and least surprising way of resolving. Here I've got a simple sprite, and the black x represents where it's feet are for collision purposes. Now since each sprite may be varying size and dimensions, I've got a "hotspot", which is an offset applied to the sprite so that the collision position lines up with where the feet are in the sprite. I think here it's about (80, 5). In "A" all is normal and correct. Now to save on art, it's nice to be able to flip sprites so we can reuse the running animation etc. for both left and right. If we just flip the texture coords, we get situation "B", where it's facing the right way, but the hotspot is now in the wrong place. So as well we also need to flip the hotspot (easily enough) which ends up with "C". Which is pretty much what we expect for sprites. Except that sometimes we don't want this behaviour. Maybe we're doing tiles, in which case the hotspot would be (0,0) (bottom left). In which case a flipped tile should be in the same position, but drawn mirrored (ie. case B). The obvious approach would be to extend the interface to have two flip settings, one to flip the tex coords, and one to also flip the hotspot coords. Flexible, but I think the interface is somewhat non-intuitive and surprising. Or I could ignore case B and always do the C approach, and say that tiles have to be handled separately (perhaps by a separate Tile class), but that would impose a certain amount of unnessesary duplication for what should be a simple task. Anyone any preferences/opinions? I don't know what other people would find more intuitive. Ta
Advertisement
Ah, I remember this very problem. Caused me a bit of a headache.

For basic rendering, I made my own class, GameTexture, that contains a texture and methods to get specific cells and render them at a given location. This class has no knowledge of hotspots. It has a Draw() method to render the image.

For animated characters, instead of directly containing a GameTexture reference they have another class which handles the more complicated aspects of rendering that other objects don't need. This object does all the hotspot calculations, and then uses the GameTexture object to draw the sprite in the appropriate manner.

So the rendering path for tiles is: Scene manager calls Draw() on the tile map, and the tile map calls Draw() on the GameTexture object for all visible tiles. For animated objects, the Scene manager calls Draw() on the object, the object calls Draw() on the special rendering class, and the special rendering class calls Draw() on the GameTexture. It's just one extra step.

If you have to use the same class to handle both tiles and animated objects, you might want to delegate their rendering to another class. So tiles would contain an instance of TileRenderer, and sprites would contain an instance of SpriteRenderer, but they both implement the same interface so outside classes don't need to be aware of the different ways they both render.

Yeah, that seems to be pretty similar to my second option (having separate Sprite and Tile classes, with different flip behaviour). It does make sense, but I worry that a whole new type just for this one bit of behaviour is a bit of overkill. Although I suppose the tile class wouldn't need to support rotation or scaling so could be a much more simplified class.

This topic is closed to new replies.

Advertisement