Skip to main content
GameDev.net gamedev.net
🔒 Locked

Tile scrolling problems! Here's a lil code!

Started by arwez Sep 23, 2000 at 8:00 AM 16 replies 1k views
Original Post
arwez
arwez
Below is some code of tile blting and scrolling. As you will see I scroll the screen by 40s. My tile size is 40 and my screen res is 800x600. If I try to scroll with any number other than 40, it starts repeating the tiles and distoring on the sides. This is a side scroller BTW. Please include sample code if you can. This problem has stumped me for quite some time now, I have not worked on my game because of it. I know I have posted about this a million times, but I just don''t know what to do so here''s the code:
    
int x,y,camerax = 0;
char map[15] [60] = {

{2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3,3,3,3,3,4,1,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3,3,3,3,4,1,1,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{3,3,3,3,3,3,3,3,3,3,3,4,1,1,1,1,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	
};


////////////////////////////////////////////////////////////


int Game_Main(void *parms = NULL, int num_parms = 0)
{

	int tileid;
	RECT tilescanrect;

	for(int x = 0; x< 60; x++)
	{
		for(int y = 0; y < 15; y++)
		{
			tileid = map[y][x];

			tilescanrect.left   = (tileid-1) * 40;
			tilescanrect.top    = 0;
			tilescanrect.right  = tileid * 40;
			tilescanrect.bottom = 40;
        
  backsurf->BltFast(camerax+x* 40,                              	                y * 40,  
                        tilesurf,      
			&tilescanrect, 
			NULL);			
				 			
		}
		
	}
	


if (KEYDOWN(VK_LEFT))
{
thesprite.celly = 0;
MoveSprite(thesprite,west);
AnimateSprite(thesprite,character,backsurf);
//global coordinate for camera, blts with this above
camerax+=40;
//check boundaries of level

if(camerax >= 0)
camerax = 0; //stop camera

if(thesprite.x <= 0) //check boundaries of sprite

thesprite.x = 0; //stop sprite



}

if (KEYDOWN(VK_RIGHT))
{
thesprite.celly = 1;
AnimateSprite(thesprite,character,backsurf);
MoveSprite(thesprite,east);
//global coordinate for camera, blts with this above
camerax-=40;
//check boundaries of level

if(camerax <= -800)
{
	camerax = -800; //stop camera

}
//check boundaries of sprite

if(thesprite.x >= 760)
thesprite.x = 760; //stop sprite


}

BltSprite(thesprite,
	  character,
	  backsurf,
	  DDBLTFAST_SRCCOLORKEY);


BltSprite(bullet,character,backsurf,DDBLTFAST_SRCCOLORKEY);  	 

FlipSurfaces();
return(1);
} // end Game_Main

    
THX!
gameprogrammerwiz
gameprogrammerwiz
i dont know if this will change anything, but, loose the RECTs...you really dont need them if your engine scrolls one tile per movement.
==============================
whats a signature?
htm[s]l[/s]
Topgoro
Topgoro
Hello.

When you scroll your screen by the tile, note that all tiles remain aligned to the screen. When you scroll them by the pixel, or any distance other than a full tile, these become misaligned with respect to the screen, causing some tiles to be partially drawn in screen limits, and partially off screen limits.

The "BltFast" can''t handle rectangles which are partially inside of the screen and partially outside of it. In order for it to work correctly the reactangle must be either completelly in the screen or completelly outside of it.

If you insist in using BltFast, you need to special case the tiles which are partially off the screen by changing the parameters passed to to the function in such a way that only the rectabgle that is within screen limits is blitted.

I am not ure about this, but I think that, alternatively, you can usse the "Blt" function, as the DirectX documentation does not say that it can''t handle clipping, as it does for the BltFast function. Unfortunatelly, unless you have hardware assistance, the Blt function is slower than BltFast.

Topgoro


We emphasize "gotoless" programming in this company, so constructs like "goto hell" are strictly forbidden.
MatrixCubed
MatrixCubed
Also, why are you checking sprite boundaries after moving them? Maybe I'm missing something, but telling a sprite to move west, then checking if it went beyond boundaries might cause problems...

(Also, how do you post code in a white box like that?)



Edited by - MatrixCubed on September 23, 2000 2:06:47 PM
arwez
arwez
Thx all. Should I check the boundaries before blting then? Is it true that I need clipping? If so any code for ddraw clippers? I don''t want anything unnecessary, I just want to get my game scroll correctly, don''t really care about speed at the moment. To make the white box u do:

//
    
//your code

//


with out the slashes of course.
Ironblayde
Ironblayde
I just finished a tutorial that covers basic clipping, among other things. It''s on my site (link below), under Resources. There''s also some sample source code you can download if it helps any. Good luck!

-Ironblayde
 Aeon Software
"Your superior intellect is no match for our puny weapons!"
arwez
arwez
Thx for the site, I''ll check it right now! oh I screwed up, to make the white box u do:


asdf...
    
asdf... your code here
asdf...


of course not with the asdf...

arwez
arwez
damn I screwd up again, hope it works this time

[.source]
your code here
[./source]

of course with out the .


arwez
arwez
More tips if u can all
arwez
arwez
so Directdraw clippers clip and decide which part of the x,y of the image to display after clipped?
Tornado
Tornado
Basically the clipper prevents the surface from being drawn outside of the screen area.
It will clip the surface so only the visible part will be drawn.
Because if you try to write outside the screen, you will write on/destroy memory that doesn''t belong to you.
That''s bad



- Goblineye Entertainment
The road to success is always under construction
Goblineye EntertainmentThe road to success is always under construction
Ironblayde
Ironblayde
Yes, plus you don''t necessarily have to use the whole screen as the clipping area. You can define any number of RECTs on the screen to clip to, as long as they don''t overlap.

-Ironblayde
 Aeon Software
"Your superior intellect is no match for our puny weapons!"
arwez
arwez
That''s all I needed to know! So just let directdraw do all the clipping for me right? Why do people use the directdraw clipper and use their own code for clipping? Like lamothe:
    

// compute starting map indices by dividing position by size of cell

start_map_x = world_x/64; // use >> 6 for speed, but this is clearer
start_map_y = world_y/64;

// compute end of map rectangle for best cast i.e. aligned on 64x64 boundary

end_map_x = start_map_x + 10 - 1;
end_map_y = start_map_y + 7 - 1;

// now compute number of pixels in x,y we are within the tile, i.e
// how much is scrolled off the edge?

offset_x = -(world_x % 64);
offset_y = -(world_y % 64);

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

if (offset_y)
end_map_y++;


// set starting position of first upper lh texture

int texture_x = offset_x;
int texture_y = offset_y;

// draw the current window

for (index_y = start_map_y; index_y <= end_map_y; index_y++)
{
for (index_x = start_map_x; index_x <= end_map_x; index_x++)
{
// set position to blit

textures.x = texture_x;
textures.y = texture_y;

// set frame

textures.curr_frame = world[index_y][index_x] - ''0'';

// draw the texture

Draw_BOB(&textures,lpddsback);

// update texture position

texture_x+=64;

} // end for map_x


// reset x postion, update y
texture_x = offset_x;
texture_y += 64;

} // end for map_y


He also attaches a directdraw clipper, he says it''s so the mouse doesn''t get messed up at the edge. Why does he use both and if it is required can someone explain all that stuff hes doing above? Hes comments don''t really mean much to me.

THX
Tornado
Tornado
What do you mean "he uses both"?
He uses the directx clipper.
He initliazes it when the game starts (Right after DirectDraw is initaliazed) and uses it in his demos and stuff
Some quick explanation of the code (Commented by Tornado ):

        
// This is the tiles scrolling demo, right?
// First he figures out which tiles needs to be drawn

// Each tile is 64x64 (I guess)

start_map_x = world_x/64; // What tile does the map starts with?

start_map_y = world_y/64; // same for y axis


// Lamothe knows there can be only 10 tiles per width and 7 per height

// That's because he uses 640x480

// 640 / 64 = 10, 480 / 64 = ~ 7

end_map_x = start_map_x + 10 - 1;
end_map_y = start_map_y + 7 - 1;

// Now we calc the offset

// Some of the tiles are drawn clipped

offset_x = -(world_x % 64);
offset_y = -(world_y % 64);

if (offset_x) // If there's an offset in the x axis

end_map_x++; // Draw one more tile per width


if (offset_y) // same for y axis

end_map_y++;

int texture_x = offset_x; // set where we start drawing (What texture)
int texture_y = offset_y; // same for y axis


for (index_y = start_map_y; index_y <= end_map_y; index_y++)
// We loop across the y axis

{
for (index_x = start_map_x; index_x <= end_map_x; index_x++)
// same for x

{
// set position to blit

textures.x = texture_x;
textures.y = texture_y;

// get the texture that needs to be drawn here (From the world array)
textures.curr_frame = world[index_y][index_x] - '0';

// draw the texture

Draw_BOB(&textures,lpddsback);

texture_x+=64; // goto next texture


} // end for map_x


texture_x = offset_x; // reset x to start of line

texture_y += 64; // goto next row in height


} // end for map_y




And That's, pretty much it

Edited by - Tornado on September 26, 2000 6:23:13 AM
Goblineye EntertainmentThe road to success is always under construction
arrogantgod
arrogantgod
I am not sure of his exact intentions but I belive Andre'' shows how to make your own clipper in case you are not using DirectDraw per se. Or maybe just in case you want to know how to make one.

Like they always say, if someone might want to know, put it in there.

Tornado
Tornado
He calculates the offset to know where to draw the tiles.
That is, Let''s say you just ran the game
Now the offset is 0, All tiles that are supposed to be drawn are drawn complete (Not clipped).
If you move the map to the right, the offset will change:
When he does the calculation -(world_x % 64) he figures out where to draw the first tile.
So if you didn''t move the map, it''ll stay on -(0 % 64) = 0
But if you move 1 pixel to the right it''ll be -(1 % 64) = -1
So the function will draw the first tile starting from -1.
Andre doesn''t clip with this function. The DirectX clipper does it for him.
Goblineye EntertainmentThe road to success is always under construction

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.