How to represent diagonal walls dividing two zones in tile based game?

Started by
6 comments, last by FrankEnCode 6 years, 11 months ago

Hi

I have my data setup where by each zone is a collection of tiles, and so my walls separate each zone by the edges of the grids.

So pseudo data setup i have:


Class: Zone¬
         List<Tile> tiles;

Class: Tile¬
          Vector2 gridPosition
          Zone zone;

My problem is - for diagonal walls separating 2 zones, two different zones share the same tile, half each. Which kind of complicates how the setup works. If a tile can be part of both zones, I then can't tell what zone an NPC is in, since I check the zone the NPC is in via checking the tile's zone reference.

Plus if the zones do have a dividing diagonal wall, how do i represent which direction, whether the wall is SW to NE " // " or " \\ " NW to SE etc. I need some way to check this by checking it's neighbours.

Advertisement

Why are the zones overlapping on just one corner?

Are the zones themselves not in a grid also? (theoretically meaning that the edge-most sides of the tiles touch, rather than overlap)

If there is an overlap between zones, why does it overlap on just the corners and not the edges entirely? How can a corner tile only be shared between two zones as opposed to all four zones?

Just trying to get a grasp on what the actual problem is :)

Lecturer and semi-domesticated Code-Panda for Polygon College

If a tile isn't mapped precisely to a single zone then checking a character's zone via its tile is probably the wrong thing to do. :)

And if a character is on a tile with 2 zones, how are you to know which side they're on?

But it also implies there's an unclear relationship between a zone and its tiles, since most of them will be 'owned' but a few are 'shared'... sounds awkward.

Perhaps you could share more information about your project and we might be able to suggest other approaches.

@FrankEnCode, i never mentioned anything about corners? Not sure what you were meaning with your question there? :)

@kylotan perhaps this image might help explain better:

NkyH76w.png

So each zone, or lets say rooms, can have diagonal walls, but they also share the tiles underneath, since a wall separates two rooms.

And thats why i made the thread in the first place, because my current data setup does not really allow tile sharing per zone/room. So i need to change the way i have it setup, but i don't know how.

Even if the tile does share 2 zones/rooms, how do i check the neighbours correctly so i know the wall between them travels say NW -> SE or NE->SW and so on for when the time comes to place the wall meshes.

Am I correct in assuming "split tiles" only happen with 45 degrees angles, ie not a wall that crosses 1 tile horizontally and 3 tiles vertically? (Such a setup would basically mean the wall can be anywhere.)

For 45 degrees only, I can think of several solutions, each with some pros and cons

- Have normal tiles, but special tile values for split tiles. That means that for many operations you first look at the tile value, and if it's special you do a special case. Probably generally saves memory, but you always have these special cases.

- Have 2 half-tiles everywhere, in 2 configurations (one for each 45 degrees direction). Unifies the tile system (somewhat, see next option).

- Have 4 quarter-tiles everywhere. Completely unifies the tile system, at the cost of a lot of small tiles. Also gives you more ways to split a tile (a 1/4 allocated to a different zone).

Another direction is to drop the tiles as unit for deciding things. It's a coordinate system but that's about it. Define a zone as a collection of simple geometric shapes, like a triangle or a rectangle.

This becomes more useful if you have other non-tile-aligned elements, like a table or chair (or whatever objects you have in your game), rotated 45 degrees. At least, trying to store a presence of such an object on a tile-grid seems quite non-trivial to me.

Am I correct in assuming "split tiles" only happen with 45 degrees angles, ie not a wall that crosses 1 tile horizontally and 3 tiles vertically? (Such a setup would basically mean the wall can be anywhere.)

For 45 degrees only, I can think of several solutions, each with some pros and cons

- Have normal tiles, but special tile values for split tiles. That means that for many operations you first look at the tile value, and if it's special you do a special case. Probably generally saves memory, but you always have these special cases.

- Have 2 half-tiles everywhere, in 2 configurations (one for each 45 degrees direction). Unifies the tile system (somewhat, see next option).

- Have 4 quarter-tiles everywhere. Completely unifies the tile system, at the cost of a lot of small tiles. Also gives you more ways to split a tile (a 1/4 allocated to a different zone).

Another direction is to drop the tiles as unit for deciding things. It's a coordinate system but that's about it. Define a zone as a collection of simple geometric shapes, like a triangle or a rectangle.

This becomes more useful if you have other non-tile-aligned elements, like a table or chair (or whatever objects you have in your game), rotated 45 degrees. At least, trying to store a presence of such an object on a tile-grid seems quite non-trivial to me.

You are correct they only go 45 degrees. Beyond that is probably too complex for a level editor in a game and not much return in terms of visual results.

I am not sure i understand the half tile suggestion, it seems that the sims (see the image in previous post) sub divided their main tiles to 4 smaller tiles, but even then the smaller tiles are still "shared" on a dividing wall.

I am curious about your first suggestion, namely how that kind of data would be setup in a Tile Class.

For example would it be something like:


Tile Class¬
         //cannot be null
         Zone zoneA;
         Zone zoneB = null  // if not null which way is the wall going? 
         
         Vector2 position;

But i would need to also find a good way to define which direction the wall travels - since there are four possible directions involved here.

I am not sure i understand the half tile suggestion, it seems that the sims (see the image in previous post) sub divided their main tiles to 4 smaller tiles, but even then the smaller tiles are still "shared" on a dividing wall.

Don't confuse looks with the underlying technical structure. Having line-like pixels in the sprite doesn't mean the tile is partitioned in that way. Maybe the artist wanted to have a "technical" look, and added some lines.

Having halftiles (in the way I proposed) means to me, a tile is either
[attachment=35888:splittiles.png]
Each half has mostly the same information you have now for a whole tile (so you have that information twice in the tile now). In addition, they have an additional field if the tile is split like the left or the right picture. Something like


class Tile {
    ... ///< Common values (valid for the entire tile).
    bool topleft; ///< If set, split runs from top-left to bottom-right, else, it's from top-right to bottom-left.

    Zone zoneA; ///< Zone of the 'A' subtile.
    Image imageA; ///< What to draw for the 'A' subtile.
    ... ///< other A values.

    Zone zoneB; ///< Zone of the 'B' subtile.
    Image imageB; ///< What to draw for the 'B' subtile.
    ... ///< other B values.
};

I have no idea what data you want to store in a subtile, my data values are just illustration. Obviously, you can make a "SubTile" class (or "HalfTile" class), and have two instances here if that seems better to you.

As you might see, the tricky bit here is the "topleft" boolean, which affects how to interpret the subtile data. "zoneA" is valid for a different part of the tile, depending on the value of that bit. "imageA" must be drawn at a different spot, depending on that boolean, etc.
The quarter-tiles suggestion fixes that. Basically, you put both layouts on top of each other, and you end up with 4 quarter tiles, one for each edge. In code, you drop the "topleft" boolean, and make 2 more set of subtile daya, so you have a subtile for each quarter tile. Now zoneA always has the same meaning (eg zoneA would always be the quarter tile against the north-edge). The cost is having these 2 more sets of subtile-data that you must deal with.

since there are four possible directions involved here

I can see only 2 ways to split a tile. You can define "inside" or "outside" relative to a zone. Relative to zoneA, he outside would be whatever is stored in the second subtile (if zoneB != zoneA).

This morning I thought of another solution, which is way simpler. Simply omit split tiles from the game, and treat them as a decoration instead. You have split tiles, but an NPC can't use them, you cannot add a chair or table there, etc. It looks better than rectangular walls, but they are not that interesting to the game, so restrict gameplay to the full tiles only. This solves all your "I need to have double data in split tiles" problems, and simplifies stuff a lot, since a tile is simply a tile, but some tiles are unusable (but you have those anyway, I guess).

I made the assumption that all zones are quadrilateral, so I also assumed that the diagonals you mentioned were the corners of said zones! Thanks for clearing that up - my mistake.

In the case of the Sims (3 at least), Sims couldn't actually occupy any diagonal tile. Perhaps a similar approach might work for you? In other words, the tile is part of both zones but it is totally 'solid' as far as the NPC is concerned. (EDIT: Like Alberth suggested)

If you do go for this, but find a lot of space is wasted, double the size of the tiles in relation to the NPCs (or half the size of the NPC in relation to the tile).

You could also reconsider the way you're determining which zone an NPC is in. For example:

- Zone A shares a diagonal tile with Zone B.

- NPC Gerald is in Zone A and tries to move into this diagonal tile.

- Gerald knows he was in Zone A, we also know that this diagonal tile is part of Zone A and Zone B.

- Since Gerald moved into the diagonal from a tile that belongs purely to Zone A, he assumes that he's in the 'Zone A half' of the tile.

EDIT: That last suggestion poses some obvious flaws. For example, if a room is entirely made of shared diagonals, or if a diagonal can contain a 'door' (or whichever noun is more appropriate for your game). If neither of those are realistic conditions, I reckon that would work pretty well.

Lecturer and semi-domesticated Code-Panda for Polygon College

This topic is closed to new replies.

Advertisement