Scrolling through the tile engine is a little off.

Started by
6 comments, last by thewayout_is_through 18 years, 6 months ago
I am trying to scroll through the tile engine terrain, however, when moving down, the engine gradually gets off as in, the bottom of the screen stops drawing and moves up the screen the further down I move. I am trying to only draw tiles on the screen which is what generated the problem (If i just draw every tile on the map it works properly). This is how I am doing it:

//lStartX, lStartY is just the top left position of the screen on the map, for example, 100, 203 would mean 
//100 px from the left and 203px from the top assuming the topleft = (0,0)
void CIsoTile::RenderLayerOne( long lStartX, long lStartY )
{ 
	//need to determine which starting coodinate on the tile map we are starting on.  ucTileWidth is mamber value which containes the Tile Width
	long lStartXCompute = lStartX / this->m_ucTileWidth;
	//cast this to a float first so that we will keep the decimal until after the x2. I tried to divide by 2 because I am using a 2:1 (width:height) ratio.
	long lStartYCompute = static_cast<long>( (static_cast<float>(lStartY) / (static_cast<float>(this->m_ucTileHeight)/2) ) );


	for( unsigned short i=lStartYCompute; i<=(lStartYCompute+this->m_ucMaxHorizTilesOnScreen); i++ )
	{
		for( short j=(i%2==0 ? (this->m_ucMaxVertTilesOnScreen-1) : (this->m_ucMaxVertTilesOnScreen) ); j>=lStartXCompute; j-- )
		{
			RECT rc;
			SetRect( &rc, 
				//X
				lXOffset,		
				//y
				( this->m_Tiles[j].sTileHeight != this->m_ucTileHeight ?
				(sY - (this->m_Tiles[j].sTileHeight - this->m_ucTileHeight) ) : 
				sY ), 
				//x
				lXOffset + this->m_Tiles[j].sTileWidth, 
				//y
				sY + ( this->m_Tiles[j].sTileHeight != this->m_ucTileHeight ?
				- (this->m_Tiles[j].sTileHeight - this->m_ucTileHeight ) + this->m_Tiles[j].sTileHeight :
				+ this->m_Tiles[j].sTileHeight ) );

			//for now we always want the src rect to = the tile
			RECT ImageSrc;
			
			SetRect( &ImageSrc, 0, 0, this->m_Tiles[j].sTileWidth, 
				this->m_Tiles[j].sTileHeight);


edit: The X doesn't work either. thanks in advance, guyaton [Edited by - guyaton on October 10, 2005 10:05:29 AM]
~guyaton
Advertisement
I didn't read your code but I have seen the problem before(If I understand correctly.) When drawing tiles you actualy need to draw more tiles than will evenly fit onto the screen.

Lets say you can draw 15 full rows of tiles evenly on the screen at one time. When you scroll down a little your top row that is still partly visible is no longer taking up as much space. That leaves room at the bottom of the screen which you need to fill up with something. Another row of tiles. 16 rows should be visible now not 15. Thats why it works if you draw everything. Try adding plus one to your drawing rows and see if that helps(just don't draw tiles that dont exist at the limmit of your map!)

Hope that helps.
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork
When the screen is first drawn with the Coordinates( 0, 0 ), it draws properly. Eventually as I scroll down, it becomes off by 1, then 2, and eventually it is off by about 1/2 the screen.

~Guyaton
~guyaton
I guess then thats a totaly different deal. Does it go back to normal when you return to 0,0 ? I'm on the run so I cant scan the code. Are you referencing a simmilar but incorrect var? A width vs max_width sort of thing. or may be a if/while/for(x=1) vs (x==1) sort of thing modifying a var that should be stable? Just quick thoughts
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork
yeah...if I return to (0,0) it is fine. I'm guessing that I'm either incrementing something too much or not enough but alas I can't find it.

~guyaton
~guyaton
Make sure you are calling the function with lStartX and lStartY in units of pixels. Not Tiles.
My tiling is working alot better now, however I am trying to keep the level centered on the character in the screen at all times to allow the player to see the largest portion of the map in all directions. This works except when I approach 0, 0 (the back most tile and the right most tile). The problem arises when I try to calculate the offset from the top of the window or from the right side of the screen. If I start with 0,0 being centered, it moves faitly smoothly but when I change algorithms from the offset algorithm for the 0,0 to the "other" algorithm with 0,0 is off the screen there is a small jump because the 2 calculations do not line up (if you know what I mean). The normal way i calculate where to start drawing (it is always negitive so that it starts drawing at the top of the screen (which using DirectDraw is 0)) is with this algorithm:

sY = -( static_cast<short>( ( fStartY - ( static_cast<float>(this->m_sWindowHeight) / 2 ) ) )
% (this->m_ucTileHeight/2) );

where: sY is the top Coordinate, fStartY is the where the character is on the map, m_sWindowHeight is the window height (600), and m_ucTileHeight is the height of the tile (40).

This algorithm has had the best success so far...but creates a small skip:

sY = static_cast<short>( std::abs( sStartYCompute ) * (this->m_ucTileHeight/2) ) - ( ( ( sStartYCompute - 1 ) + ( this->m_ucMaxVertTilesOnScreen / 2 ) ) % (this->m_ucTileHeight / 2 ) );

where sStartYCompute is the first tile to be drawn in the back (say 0 for the backmost tile), m_ucMaxVertTilesOnScreen is the maximum number of verticle tiles that can be on the screen at any time.

thanks for you help in advance,

~guyaton
~guyaton
At a quick glance I'd suggest:

Using powers of 8 for tiles/screensize due to storage/speed/precision and sticking to fixed point math unless you have a compelling reason not to.

Avoid mixing integer with floats in an equation as it introduces conversion between the data types when you cast, which can add some inaccuracy to the result.
"Who are you, and how did you get in here?""I''m the locksmith, and I''m the locksmith."

This topic is closed to new replies.

Advertisement