This topic is now archived and is closed to further replies.


Beginner - 640x480 32x32 Tile Scrolling

Recommended Posts

Heyas, i''m worknig with DirectDraw.. i got the hang of it pretty good. I did my own tile based game with it and screen scrolling. 640x480x16 tiles are 32x32. Since i did this all out of the blue.. figuring stuff out as i needed it... i need ur opinion if i got this totally wrong or what Basically what i did was, create a MAP[128][128] (X,Y) of what tiles to draw. Map of 128x128 tiles the world coordinates are in pixels, 128*32 x 128*32 so my charcacter uses X,Y postion of X,Y in pixels in the world. I use 3 buffers Primary, Secondary... these 2 flip around 3rd Buffer = Virgin i use/need the virgin buffer for scrolling. so i draw my tiles on virgin, and then BltFast the RECT offseted by the position, to the Secondary buffer.. draw objects on Secondary buffer and Flip thats the main loop/update frame loop. is this an acceptable/good way of doing this? or is it too slow? I''l continue on next post what i did/think is a way of improving performance...

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
I was doing a 640x480 32x32 game a while ago but I scrapped it for Direct3D tile-rendering (there''s a tutorial on here about it somewhere). But that is perfectly good for a beginner. And they fit perfectly on the screen (20x15 I think).

Good Luck


Share this post

Link to post
Share on other sites
I was doing a 640x480 32x32 game a while ago but I scrapped it for Direct3D tile-rendering (there's a tutorial on here about it somewhere). But that is perfectly good for a beginner. And they fit perfectly on the screen (20x15 I think).

Aah! The stupid message board put up my message before I could stop it and put my name and password

Edited by - Confused on October 3, 2000 5:03:52 PM

Share this post

Link to post
Share on other sites
ok this is a long one

to make things faster in the tile rendering, i use an area of 480x480 for the view of the world, tiles. Thats 15x15 tiles
15 * 32(Size of tile) = 480

everytime i''d draw the tiles its 15*15 tiles to draw... it was fast.. but i wanted it Faster... the faster i render them tiles.. the smoother i can make the scroll even as the person wants to move fast.

So i would use a Virgin Buffer of 1+15+1 * 1+15+1 = 17*17 tiles
1 extra row, 1 extra column of tiles on each side. Supose the person moves South 1 tile size. i would do:
VirginRECT is a RECT with the size of the buffer (17x17 tiles, thats 544x544 + 32
DDS_TempBuffer.BltFast 0,0,DDS_VirginBuffer, &VirginRECT,...
then Blt that back to virgin buffer, = 0
DDS_VirginBuffer.BltFast 0,0, DDS_TempBuffer, &VirginRECT...
basically i needed to Copy Part of the Virgin Buffer, who already had 90% of the tiles that i was gonna redraw... so just copy them already drawn, and offset them to their new position. in this case from 0,32 move them to 0,0
then just draw the last row of Tiles.

By doing all this messy process, instead of redrawing 17x17 tiles (289 Tiles) i''m only drawing 17 tiles... I''m avoiding to draw 94% of the tiles on each move. BUT, i''m doing 2 extra Big Copy''s of buffers :/ 17*32 * 17*32 = like 500k * Color Bytes (16 bits = 2 Bytes) so, each of them BltFast''s to do this whole thing are actually making me copy 1 meg 2 times. hmmm

Whats better? Copying 2 megs or doing 289 steps of drawing 32x32 tiles? which by my calcs = 600k of bytes been tampered.

Ok anyways, that my system...
any feedback would be kewl.. any insults too u can call me an animal or whatever =) like isaid its mah first visual thing, and first time with DX =)
BTW, the grafic part is pretty fast... things are working... but i know i''m missing stuff =)

Share this post

Link to post
Share on other sites
Sanced, you animal!

Anyway... an alternative would be to save all that memory you spend on the "virgin" buffer, and just put that 1-tile buffer area around your secondary buffer. This way, you''re eliminating the step of flipping (which on some video cards really equates to doing a byte-by-byte copy from the secondary surface to the primary surface, not just a pointer move).

Some advantages to this:
- as stated before, you might be doing a video-to-video memory copy from your virgin buffer to your secondary buffer, then from your secondary buffer to your primary buffer... even if the card just changes the pointer address, like it''s supposed to during a flip, this is one more step that you can eliminate.
- if the player is using a video card that has very little memory, (like 2M of video ram) then the virgin buffer will end up in system memory. System-to-video memory writes are VERY slow, and should be avoided. Even on some 4M cards, there is the chance that the virgin buffer will be put in system memory (because of the way that some cards work, and because of pitch). By using less memory, you can avoid this problem.
- other, smaller things, like eliminating redundancy, and freeing up memory for other surfaces (for frequent animations, or video clips)
- it makes it a little easier to operate independantly of the refresh rate, so you can use time-related physics instead of relying on a constant frame-rate

Some disadvantages:
- you can no longer have a flipping chain, since the two buffers will be of a different size. But considering that you were doing the video-to-video memory write before every flip, anyway, then there will be absolutely no speed loss, there can only be a possible speed gain, or if you''re consistent with the vertical-sync, then the fps will remain exactly the same.
- You will have to rework your logic slightly, but not much... you already know how to copy from one surface to another using an offset and a known screen width, now you just have to copy to the primary instead of the secondary, which means you''ll have to watch for the vertical sync (otherwise shearing may occur occasionally)

Hope this helps some!

"Man is the only animal that laughs and weeps; for he is the only animal that is struck with the difference between what things are and what they ought to be."
        --William Hazlitt

Share this post

Link to post
Share on other sites
Ok, i got this function from a Tile Smooth Scrolling here in by Jim Adams (to Credit him for it but i modified a cple of things for my needs

/* map_drawx, map_drawy are the TILEs*TILESIZE coordinates of where to start drawing from, like:
if player.x = 1000 // he's in tile 1000/32
our view zone is 15x15 tiles so start drawing at:
map_drawx = player.x - 15*32 / 2

if he's Column Tile 31, and is 8 pixels west in it
Player.x = 1000 = 31 * 32 + 8
View zone is 480x480 pixels, 15x15 Tiles, we'r in the middle
so start drawing at:
map_drawx = Player.x - 480/2

map[][] conatins tile info of the map

void DoTiles(short map_drawx, short map_drawy)
short i, j;
short mapx, mapy;
short map_xoff, map_yoff;

mapx = map_drawx / 32;
mapy = map_drawy / 32;
map_xoff = map_drawx & 31;
map_yoff = map_drawy & 31;

for(i = 0; i < 16; i++) {
for(j = 0; j < 16; j++)
tile_draw(Map[mapy+i][mapx+j].TileID, j*32, i*32);
RECT rc; + map_yoff;
rc.left=0 + map_xoff;
rc.right=480 + map_xoff;
rc.bottom=480 + map_yoff;

void tile_draw(char TileID, int Sx, int Sy) {
pddsVirgin->BltFast(Sx,Sy,pddsFloorTiles, &FloorTilesRect[TileID], DDBLTFAST_WAIT);

PS: was forgeting, later on, the objects get rendered to pddsBack Surface, and that surface flips. pddsBack is a Flip'n surf

So my question now is, since i see this function as beeing a Well done one, i think its a great Simple, fast func to draw the tiles of the view zone.
Quesiotn: What do u think? Can i base my tile drawing on this func? will it be Fast enough? I like that func()
it works good.. but i dunno...

Feeeedback :D

Edited by - sanced on October 3, 2000 6:19:52 PM

Share this post

Link to post
Share on other sites