help with scrolling and tiling

Started by
6 comments, last by always_learning 15 years, 10 months ago
Ok I'm writing a function to draw tiles and it's acting really weird, it's totally buggy and I suspect that there are many things wrong with it so anyone willing to look at my code maybe? thanks
void CGame::DrawTiles()
{
	int CurrentTile; 
	int StartTileX, StartTileY, EndTileX, EndTileY;
	int OffsetX, OffsetY;
		
	// compute starting map indices by dividing position by size of cell
	StartTileX = m_WorldX / 32;
	StartTileY = m_WorldY / 32;

	// compute end of map rectangle for best cast i.e. aligned on 32x32 boundary
	EndTileX = StartTileX + VIEWPORTSIZE_X - 1;
	EndTileY = StartTileY + VIEWPORTSIZE_Y - 1;
	
	// now compute number of pixels in x,y we are within the tile, i.e
	// how much is scrolled off the edge?
	OffsetX = -(m_WorldX % 32);
	OffsetY = -(m_WorldY % 32);

	// adjust end_map_x,y for offsets
	if (OffsetX)
		EndTileX++;

	if (OffsetY)
		EndTileY++;

	// set starting position of first upper lh texture
	SDL_Rect src, dest;
	dest.x = OffsetX;
	dest.y = OffsetY;
	src.w = 32;
	src.h = 32;

	for (int i = StartTileY; i < EndTileY; i++)
	{
		for (int j = StartTileX; j < EndTileX; j++)
		{
			CurrentTile = m_Levels[m_CurrentLevel].m_MapData[j];
			src.x = CurrentTile * 32;
			src.y = 0;
			
			SDL_BlitSurface(m_Tilesets[m_CurrentTileset],&src,m_Screen,&dest);

			// update tile position
			dest.x += 32;
		}

		// reset x postion, update y
		dest.x = OffsetX;
		dest.y += 32;
	}
}

[Edited by - always_learning on May 28, 2008 5:03:21 AM]
Advertisement
1. Are VIEWPORTSIZE_X(/Y) in pixels or tiles? If in pixels, you need to divide them by the tile size as well. And it should be in pixels.

2. Don't do the - 1 on EndTile, nor the test on the offset. Non-intuitive logic, and wasted cycles, in that order.

3. You probably want to add tests for scrolling off-map; make sure StartX(/Y) are no less than zero (and adjust starting top/left to compensate), make sure EndX(/Y) are within the map bounds, etc. Skip rendering entirely if you're completely outside map bounds.

4. Don't give this method access to all levels, or make it dependant on a "currentLevel" variable; pass it a level to use, or give a level to use to the map renderer object.

Beyond that, what's wrong with it?
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
1. Are VIEWPORTSIZE_X(/Y) in pixels or tiles? If in pixels, you need to divide them by the tile size as well. And it should be in pixels.

Tiles

2. Don't do the - 1 on EndTile, nor the test on the offset. Non-intuitive logic, and wasted cycles, in that order.

So just change that to
	EndTileX = StartTileX + VIEWPORTSIZE_X;	EndTileY = StartTileY + VIEWPORTSIZE_Y;


3. You probably want to add tests for scrolling off-map; make sure StartX(/Y) are no less than zero (and adjust starting top/left to compensate), make sure EndX(/Y) are within the map bounds, etc. Skip rendering entirely if you're completely outside map bounds.

I have that coded in a different area.

4. Don't give this method access to all levels, or make it dependant on a "currentLevel" variable; pass it a level to use, or give a level to use to the map renderer object.

Why?

Beyond that, what's wrong with it?

Well I don't know how to describe it but it just behaves really odd. Like the very leftmost columan will scroll but nothing else. Should I record a video of it or something?
Quote:Original post by always_learning
Why?

Mostly because it's bad design. Leave it in if you want, but be aware.

Quote:Original post by always_learning
Well I don't know how to describe it but it just behaves really odd. Like the very leftmost columan will scroll but nothing else. Should I record a video of it or something?

Are you certain SDL doesn't trash the dest rect when used in a call? Try setting it up before each drawing call {dest.x = i*32 - StartTileX + OffsetX; dest.y = j*32 - StartTileY + OffsetY;}.

If you are seeing a full but static grid, with a sliding or jumping leftmost column, that's probably what is happening. If you're seeing only a leftmost column, it still makes little sense, but it is almost certainly happening. I had a similar problem back when I was working with DirectX 7; some DirectDraw blit functions would trash the source rectangle if you used DirectX clipping boxes instead of doing it yourself.

Take three screenshots; one at 0,0 camera position, another at 10,0, and another at 42,10 pixels camera position, and use a plain checkers grid; (x+y) odd one tile, (x+y) even use another tile. That should let us see clearly what's going on.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
Mostly because it's bad design. Leave it in if you want, but be aware.

Why is it a bad design? I'm not trying to sound like an ass or anything and it sounds like you know what you're talking about. Though I have never understood how data should be organized when programming with classes (ie OOP)

Are you certain SDL doesn't trash the dest rect when used in a call? Try setting it up before each drawing call {dest.x = i*32 - StartTileX + OffsetX; dest.y = j*32 - StartTileY + OffsetY;}.

...

Edit: Posted 3 pics

[Edited by - always_learning on May 28, 2008 6:11:47 PM]




Quote:Original post by Wyrframe

Are you certain SDL doesn't trash the dest rect when used in a call? Try setting it up before each drawing call {dest.x = i*32 - StartTileX + OffsetX; dest.y = j*32 - StartTileY + OffsetY;}.

If you are seeing a full but static grid, with a sliding or jumping leftmost column, that's probably what is happening. If you're seeing only a leftmost column, it still makes little sense, but it is almost certainly happening. I had a similar problem back when I was working with DirectX 7; some DirectDraw blit functions would trash the source rectangle if you used DirectX clipping boxes instead of doing it yourself.


This seems to be a step in the right direction. Now what it does is the entire world is drawn but it doesnt draw it in the same place. Like it'll move the entire viewport which is NOT what I want to do. I want the actual viewport to remain where it is but I want the display to scroll. I hope you know what I mean.

anyone?

This topic is closed to new replies.

Advertisement