gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Isometric tiles & overlapping

#25311 - Istondil - Fri Aug 20, 2004 11:09 am

Isometric tiles & overlapping

I?m currently rather busy with designing a small puzzle game in an isometric environment. I intend the levels themselves to be tiled backgrounds, but I?m unfamiliar how to place sprites so that overlapping is properly displayed. I?ve tried searching the forum and websites for tips & tricks but haven?t found anything helpful thus far. Hope some of you will be able to give me some pointers.

Code:

Image 1: Sample iso map
                                     _ _
                                 _ /     \ _
                             _ /             \ _
                        _ _/                     \_ _
                     _ /   \ _   _ / - - \ _   _ /   \ _
                 _ /         _ /             \ _        \ _
           _ _ /           /                     \           \ _ _
       _ /     \ _        |\ _                 _ /|        _ /     \ _
   _ /             \ _    |    \ _         _ /    |    _ /             \ _
_/                     \_ |        \ _ _ /        |_/                     \_
 \ _                 _ /   \ _        |        _ /   \ _                 _ /
     \ _         _ /           \ _    |    _ /           \ _         _ /
         \ _ _ /                   \ _|_ /                   \ _ _ /
               \ _               _ /     \ _               _ /
                   \ _       _ /             \ _       _ /
                       \_ _/                     \_ _/
                           \ _                 _ /
                               \ _         _ /
                                   \ _ _ /


Here?s a sample iso map with height difference. Height/location data is stored in an array for mathematical purposes. This map can be generated using a standard tileset.

Code:

Image 2: An added sprite
                                     _ _
                                 _ /     \ _
                             _ /             \ _
                        _ _/                     \_ _
                     _ /   \ _   _ / - - \ _   _ /   \ _
                 _ /         _ /             \ _        \ _
           _ _ /           /                     \           \ _ _
       _ /     \ _        |\ _                 _ /|        _ /     \ _
   _ /             \ _    |    \ _         _ /    |    _ /             \ _
_/                    @@@@@@       \ _ _ /        |_/                     \_
 \ _                @@@@@@@@@@        |        _ /   \ _                 _ /
     \ _         _ /@@@@@@@@@@ \ _    |    _ /           \ _         _ /
         \ _ _ /    @@@@@@@@@@     \ _|_ /                   \ _ _ /
               \ _    @@@@@@     _ /     \ _               _ /
                   \ _       _ /             \ _       _ /
                       \_ _/                     \_ _/
                           \ _                 _ /
                               \ _         _ /
                                   \ _ _ /


Pretty straightforward, we place a sprite on one of the tiles on the foreground. Visually this is a correct placement of the sprite. The sprite overlaps the elevated tile in the center. The height/location array is used for determining the position of the sprite.

Code:

Image 3: Moved the sprite            _ _
                                 _ /     \ _
                             _ /             \ _
                        _ _/       @@@@@@        \_ _
                     _ /   \ _   @@@@@@@@@@_   _ /   \ _
                 _ /         _ / @@@@@@@@@@  \ _        \ _
           _ _ /           /     @@@@@@@@@@      \           \ _ _
       _ /     \ _        |\ _     @@@@@@      _ /|        _ /     \ _
   _ /             \ _    |    \ _         _ /    |    _ /             \ _
_/                     \_ |        \ _ _ /        |_/                     \_
 \ _                 _ /   \ _        |       _ /   \ _                 _ /
     \ _         _ /           \ _    |     _ /           \ _         _ /
         \ _ _ /                   \ _|_ /                   \ _ _ /
               \ _               _ /     \ _               _ /
                   \ _       _ /             \ _       _ /
                       \_ _/                     \_ _/
                           \ _                 _ /
                               \ _         _ /
                                   \ _ _ /


Here the sprite is moved to the north (visually northeast). Once again the height array is used to give the sprite an additional y-offset. All still fine and dandy.

Code:

Image 4a: Incorrectly displayed sprite
                                     _ _
                                 _ /     \ _
                             _ /             \ _
                      @@@@@@                     \_ _
                    @@@@@@@@@@   _ / - - \ _   _ /   \ _
                 _ /@@@@@@@@@@ /             \ _        \ _
           _ _ /    @@@@@@@@@@                   \           \ _ _
       _ /     \ _    @@@@@@ _                 _ /|        _ /     \ _
   _ /             \ _    |    \ _         _ /    |    _ /             \ _
_/                     \_ |        \ _ _ /        |_/                     \_
 \ _                 _ /   \ _        |        _ /   \ _                 _ /
     \ _         _ /           \ _    |    _ /           \ _         _ /
         \ _ _ /                   \ _|_ /                   \ _ _ /
               \ _               _ /     \ _               _ /
                   \ _       _ /             \ _       _ /
                       \_ _/                     \_ _/
                           \ _                 _ /
                               \ _         _ /
                                   \ _ _ /


Image 4b: Desired: Partially hidden sprite
                                     _ _
                                 _ /     \ _
                             _ /             \ _
                      @@@@@@                     \_ _
                    @@@@@@@@@@   _ / - - \ _   _ /   \ _
                 _ /@@@@@@@@@@ /             \ _        \ _
           _ _ /    @@@@@@@/                     \           \ _ _
       _ /     \ _    @@@@|\ _                 _ /|        _ /     \ _
   _ /             \ _    |    \ _         _ /    |    _ /             \ _
_/                     \_ |        \ _ _ /        |_/                     \_
 \ _                 _ /   \ _        |        _ /   \ _                 _ /
     \ _         _ /           \ _    |    _ /           \ _         _ /
         \ _ _ /                   \ _|_ /                   \ _ _ /
               \ _               _ /     \ _               _ /
                   \ _       _ /             \ _       _ /
                       \_ _/                     \_ _/
                           \ _                 _ /
                               \ _         _ /
                                   \ _ _ /


Here the trouble starts. I moved the sprite a tile westward. The x/y position is correct but because the elevated tile doesn?t overlap the sprite image it looks like the graphic is floating several squares above the original position. The desired effect would be to partially hide the sprite as shown in 4b. This could be achieved by adding another tiled background layer which contains the elevated tiles that should overlap, but? I?m afraid the following flaw would occur:

Code:


Image 5: My fears                    _ _
                                 _ /     \ _
                             _ /             \ _
                        _ _/                     \_ _
                     _ /   \ _   _ / - - \ _   _ /   \ _
                 _ /         _ /             \ _        \ _
           _ _ /           /                     \           \ _ _
       _ /     \ _        |\ _                 _ /|        _ /     \ _
   _ /             \ _    |    \ _         _ /    |    _ /             \ _
_/                    @@@@|        \ _ _ /        |_/                     \_
 \ _                @@@@@@@\ _        |        _ /   \ _                 _ /
     \ _         _ /@@@@@@@@@@ \ _    |    _ /           \ _         _ /
         \ _ _ /    @@@@@@@@@@     \ _|_ /                   \ _ _ /
               \ _    @@@@@@     _ /     \ _               _ /
                   \ _       _ /             \ _       _ /
                       \_ _/                     \_ _/
                           \ _                 _ /
                               \ _         _ /
                                   \ _ _ /


A rather awkward picture - The sprite is closer to the viewer than the elevated tile, but it still gets overlapped by something that is visually further away.

The question:

How would I solve the problem of overlapping or displaying partial sprites to display a visually correct isometric environment? At certain x,y locations the sprite should be overlapped, and at other x/y locations the sprite should be overlapping. Is this even possible by using tiles for the level layout or should I use sprites to overcome difficult level sections that require complicated overlapping?

#25313 - poslundc - Fri Aug 20, 2004 1:51 pm

I've not done an iso-tile engine, but it would seem to me that you can easily use the sprite's x-coordinate to test to see if it is obscured by a tile on the lower-right (y-coordinate to see if it is obscured on the lower left). I would then simply assign the sprite a priority level either above or below the priority level of your obscuring layer, depending on if it should be obscured or not.

(I've assumed that the x-axis is in the direction of the down-right diagonal and the y-axis is in the direction of the down-left diagonal.)

There may be practical limitations on your design, especially if you can only afford two backgrounds. In particular, a sprite should not be tall enough (or walls set close together enough) so that it could "straddle" two planes of obscurement. But this is probably not a major encumbrance.

Dan.

#25329 - Miked0801 - Fri Aug 20, 2004 6:17 pm

What you do is put the obscuring layer on a seperate BG with a lower display priority than the layer below it. Put the sprite above those. When you detect that the sprite has touched an area where it should overlap (using map position), increase the sprite priority by one so that it goes behind the obscuring layer and in front of the BG layer.

That's how we do it - BTW it will cause issues with sprite/sprite sorting. No matter what draw order you place your sprites in, they sort against the priority first - thus even with a Y sort, you'll get some bad sorts with this sort of system.

Anyone have a solution to that problem?

#25395 - ScottLininger - Sat Aug 21, 2004 11:35 pm

One (limited) solution is to generate all of the "foreground" stuff as sprites and not tiles, then manage all of the overlap questions with a simple "farthest to closest" sprite stacking algorithm.

So in the example above, the "higher" square in the middle would be drawn as a sprite, not with backgrounds.

This of course depends on the nature of your game. If you have LOTS of things that can overlap, then the maximum number of sprites and the maximum number of sprite tiles can become a barrier.

Which actually brings up an interesting idea: I remember some time ago that there was a post showing that you could choose to have background tiles "spill over" into the sprite tile memory, since the background tile index could hold a number large enough to reference into the sprite tile RAM. Using this trick, you might be able to "share" some tiles between both your backgrounds and your sprites that you would use for your raised platforms.

So Mike, do you guys use all four layers for your iso games? BG3 and BG2 for "behind" tiles and BG1+BG0 for your "foreground" tiles? I'm just wondering, since the iso engines I've seen (and the one I'm building) uses two BGs to create a complete iso layout.

-Scott

#25659 - Miked0801 - Thu Aug 26, 2004 7:05 pm

Yes the spill trick does work, but we've not had to resort to it yet. Almost did in Digimon Racing, but got around it with some clever sprite ram management.

And yes, we use all 4+ layers in our game engine. Usually, 1 layer far, 1 layer that sorts above or below sprites depending on the collision tile they are stepping on, 1 layer always on top, and the 4th layer for envirnoment effects, parallaxing, or doubling the tile/color counts on a layer we want to look especially cool. For dialogs, we hblank the popup box in between the layers on the fly depending on the Y scroll reg loc. Yes, that took time, but allows a virtual 5th layer w/o eating into sprite RAM which is always tight.

#25704 - Istondil - Fri Aug 27, 2004 1:14 pm

Thanks for the replies all,

Currently I'm attempting to get things to work wiith 4 layers and careful level planning (though not as cheap as with Tactics Ogre where from my brief observation basically the most northern edge is usually the highest point in the level and the southernmost point the lowest).

Using 4 layers (and as such requiring planned levels) won't make a true iso game, but it gives the suggestion that is is without eating away at the maximum number of sprites. I might even use the sprite solution for some complex level areas, but will try to avoid using it as a rule. There's enough priority tracking to take care of as it is in tghe proof of concept.