• 9
• 9
• 11
• 12
• 9

# Seeking assistance - TileMap, TileChunks, Placing terrain tiles

This topic is 810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am having a surprising amount of difficulty with this stuff. I'll try to give a super brief breakdown, in the form of code definitions, of the concepts at play.

struct Terrain
{
std::vector<short> m_Space;
};

class TileChunk
{
friend class TileMap;
std::vector<short> m_Region;
};

class TileMap
{
std::map<uint64, TileChunk*> m_Map;
public:
void Place(Terrain* t, uint32 x, uint32 y);
};


Alright that should be adequate for understanding the structure of things. Now for the coordinate systems...

All three classes have their own coordinate systems. The TileMap can be considered to be using the "world" coordinate system, as it needs to map tile coordinates to the correct locations inside the appropriate objects.

*The Problem*

I am having a problem with the class method below. The calculations I am performing provide the correct values if I avoid coordinate underflows in the tile map; I know this from a unit test designed to test the calculations when/if placing across 6 TileChunks, moving forward on the coordinate system. As soon as an underflow takes place however the Current_Terrain_Offsets have the wrong values. I am only able to make one transition between two separate terrains, so I can't inspect the behaviour as deeply as I'd like to. Otherwise I'd see if errors happened if I reached a new TileChunk or what would happen if I traveled many many screens of TileChunks. The terrains usually intersect a 0 boundary before I can make it very far. So the only inspecting I can really do is to move leftward or downward and force an underflow, or move in the other directions and wait for the terrain to intersect across that boundary.

I don't know what I hope to achieve posting this here, but maybe somebody can take a look and make sense of the calculations and figure out the logical flaw in the math/code.

One more thing, the result of the miscalculations is a subscript out of bounds error with the Terrain's vector; located inside the SetTiles method of the TileChunk being configured. Since the terrain is likely below 15 tiles on either axis, and the offset is massively huge due to the underflow.

void TileMap::Place( Terrain* t, uint32 starting_tile_x, uint32 starting_tile_y )
{
uint32 increment = IncrementAtBit<uint32>( 0, LOWBITS + 1 );
const coordinate Starting_Chunk( MapLocalCoord( starting_tile_x ), MapLocalCoord( starting_tile_y ) );
const coordinate Starting_Chunk_Offset( ChunkLocalCoord( starting_tile_x ), ChunkLocalCoord( starting_tile_y ) );

const uint8 c_cw = TileChunk::width; //Width of a Chunk
const uint8 c_ch = TileChunk::height; //Height of a Chunk
const uint16 c_ChunkColumns = (uint16)ceil( ( Starting_Chunk_Offset.x + t->width ) / (float)c_cw );
const uint16 c_ChunkRows = (uint16)ceil( ( Starting_Chunk_Offset.y + t->height ) / (float)c_ch );

coordinate Current_Chunk;
coordinate Current_Chunk_Offset;
coordinate Current_Chunk_Offset_Tile;
coordinate Current_Terrain_Offset;

TileChunk* chunk = nullptr;
for ( uint32 r = 0; r < c_ChunkRows; ++r )
{
for ( uint32 c = 0; c < c_ChunkColumns; ++c )
{
Current_Chunk.x = Starting_Chunk.x + ( c * increment );
Current_Chunk.y = Starting_Chunk.y + ( r * increment );

Current_Chunk_Offset.x = ( c == 0 ? Starting_Chunk_Offset.x : 0 );
Current_Chunk_Offset.y = ( r == 0 ? Starting_Chunk_Offset.y : 0 );

Current_Chunk_Offset_Tile.x = Current_Chunk.x + Current_Chunk_Offset.x;
Current_Chunk_Offset_Tile.y = Current_Chunk.y + Current_Chunk_Offset.y;

Current_Terrain_Offset.x = Current_Chunk_Offset_Tile.x - Starting_Chunk_Offset.x;
Current_Terrain_Offset.y = Current_Chunk_Offset_Tile.y - Starting_Chunk_Offset.y;

uint64 key = MergeIntegers( Current_Chunk.x, Current_Chunk.y );
auto it = m_Map.find( key );
if ( it == m_Map.end() )
{
chunk = new TileChunk();
chunk->m_TileSet = m_TileSet;
it = m_Map.emplace( key, chunk ).first;
}
else
{
chunk = it->second;
}
chunk->SetTiles( t, Current_Chunk_Offset, Current_Terrain_Offset );
}
}
}

Edited by coope

##### Share on other sites

It doesn't seem like anybody was likely able to figure it out, or perhaps even try. Either way, I eventually figured out the fallacy.

The problem was I was subtracting an offset. When what I really needed to do was subtract the starting tile coordinates

Current_Terrain_Offset.x = Current_Chunk_Offset_Tile.x - starting_tile_x;
Current_Terrain_Offset.y = Current_Chunk_Offset_Tile.y - starting_tile_y;


edit:
Not sure replying to one's own post with the solution a day later is bad, but I don't like incomplete things. Maybe this thread will be good for a laugh to someone someday or help that 1 in 20 billion person working on the exact same situation in 20 years?

Edited by coope