Skip to main content
gamedev.net
🔒 Locked

Tile placement problem

Started by Nokame 6 replies 900+ views
Original Post
Nokame
Nokame
Hey, I was curious if anyone could help me understand why I try to blit 25 tiles by using a couple for loops, but it misses 5 of the objects. I'm thinking my math is a little rusty... but if you could take a look and see if you think it should blit a 5x5 map of tiles. BITMAP_OBJ map[5][5] I am loading the tiles by using for(int x = 0; x < 5; x++) for(int y = 0; y < 5; y++) { Create_Bitmap_Object(↦[x][y], 64, 64, 0, DDSCAPS_SYSTEMMEMORY); Load_Object(↦[x][y], &bitmap, cx, cy, 0); if(cx < 5) cx++; else { if(plus == 0) { cy = 1; plus++; } else { plus = 0; cy = 0; } cx = 0; } map[x][y].x = x*(64-1); map[x][y].y = y*(64-1); } } i want the tiles to look like : 00000 00000 00000 00000 00000 instead i get at position 0, 0 00000 00000 00000 00000 its missing the bottom row. So any help would be appreciated. my email is Nokame@hotmail.com Thanks.
Nokame
Nokame
any help would truely be appreciated i've been stuck for a day with just this crap. *tear*
Captain P
Captain P
Your code doesn't look complete. Can you post both the loading part and the blitting part (and use the code tag to keep the code formatting)?

Anyway, there's a few steps to detect the problem. First, make sure you load all tiles correctly. Then, check if the blitting loop actually blits the last 5 ones. There might be a problem with the location, or with the loop, or something else. With some debugging it shouldn't be too hard to find out what goes wrong - hopefully. :)

// Oh, just a comment: x*(64-1) is the same as x*63... did you intend (x*64)-1 instead?
// Another comment: I assume this is some experimenting code, but in 'production code', you'll want to load images only once, and use them multiple times when they appear more than once on the tile map. Some sort of tile managing. Otherwise you could as well paint the whole map on a single image. :)
Nokame
Nokame
The loading part just loads the image into the created bob structure, and i have it loading all the tiles from my map bitmap into seperate surfaces. This doesn't sound like the best way to me :)... Then after the bitmap object is created and loaded. It draws the object onto a rect the size of the object and blits it onto the backbuffer... then flips. here are the Load_Object function and the Draw_OBJ function... then i have the blitting for loop to draw the tiles.

int Load_Object(BITMAP_OBJ_PTR obj,BITMAP_FILE_PTR bitmap,int cx,int cy,int mode)
{
UCHAR *source_ptr, // working pointers
*dest_ptr;
int index_y;

DDSURFACEDESC ddsd; // direct draw surface description
if (mode==0)
{
// re-compute x,y
cx = cx*(obj->width+1) + 1;
cy = cy*(obj->height+1) + 1;
}
source_ptr = bitmap->buffer +
cy*bitmap->bitmapinfoheader.biWidth+cx;
ddsd.dwSize = sizeof(ddsd);
(obj->image)->Lock(NULL,
&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL);
dest_ptr = (UCHAR *)ddsd.lpSurface;
for (index_y=0; index_yheight; index_y++)
{
memcpy(dest_ptr, source_ptr,obj->width);
dest_ptr += obj->width;
source_ptr += bitmap->bitmapinfoheader.biWidth;
}
unlock the surface
(obj->image)->Unlock(ddsd.lpSurface);
return(1);
}
//draw object to surface rect
int Draw_OBJ(BITMAP_OBJ_PTR obj,LPDIRECTDRAWSURFACE dest)
{
RECT dest_rect, // the destination rectangle
source_rect; // the source rectangle
dest_rect.left = obj->x;
dest_rect.top = obj->y;
dest_rect.right = obj->x+obj->width-1;
dest_rect.bottom = obj->y+obj->height-1;
source_rect.left = 0;
source_rect.top = 0;
source_rect.right = obj->width-1;
source_rect.bottom = obj->height-1;
dest->Blt(&dest_rect, obj->image,
&source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
NULL);
return(1);
}
//This is what actually blits to the tiles
for(int x = 0; x < 5; x++)
for(int y = 0; y < 5; y++)
Draw_OBJ(↦[x][y], lpddsback);
TheAdmiral
TheAdmiral
If you put [source], [/source] tags around your code, it becomes much more readable.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Aardvajk
Aardvajk
To be honest Nokame, your code makes my head hurt a bit so I'll explain a simpler approach for what you are trying to do.

As you surmised above, you don't really need to load a seperate copy of each tile into the map structure. For every two tiles that have the same image, you are loading two copies of the same image which is a waste.

Create an array of your BITMAP_OBJ's, if you are certain they are all working okay, with each image existing in this array once then create your map as a 2D array, in whatever form, of ints that represent indicies into this image array.

So if you have three different tile images in an array numbered 0-2, your map might look like:

1 1 1 1 1
1 0 0 1 1
1 2 0 1 1
1 1 1 1 2
1 2 2 2 1

Now assume that you have written a function a bit like this:

void DrawTile(BITMAP_OBJ &B,int X,int Y);

where X and Y are screen co-ordinates and BITMAP_OBJ &B is the image to be drawn for a given tile. Let's call your BITMAP_OBJ array Bitmaps and your 2D map array Map.

Your drawing code now becomes this:

void DrawMap(){    for(int Y=0;Y<5;++Y)        {        for(int X=0;X<5;++X)            {            int Tile=Map[X][Y];            DrawTile(Bitmaps[Tile],X*64,Y*64);            }        }}


With a rectangluar and regular tile map, there is no need to store the screen position of each tile in the tile structure since these co-ordinates are far more easily calulated as you draw.

Are these BITMAP_OBJ_PTR and BMP_FILE_PTR structures you have written yourself, because perhaps they contain errors affecting your code. There is a utilities file that ships with DirectDraw called ddutils.h and .cpp that contain functions to load images into DirectDraw surfaces using the Win32 and DirectDraw APIs directly.

Finally, before anyone else says it, DirectDraw is well deprecated and hardware support is dying out. Now really is the time to make the transition over to DirectX Graphics, even for 2D stuff.

HTH Paul
Nokame
Nokame
well, what the program does is creates surfaces for each tile. then i just blit the tiles from there. I actually got the problem fixed, it was just a stupid math problem... i'm rusty... but i started two months agro from a rusty memory bank going into an old directx book. the idea is to get this game down... understand how it works... then move on to direct 3d. Could you tell me more about DirectX Graphics? or point me somewhere to read about it please? And thanks for the [/source] comment as well. i'll know better now :)
Aardvajk
Aardvajk
DirectX Graphics is just the name for the amalgamated old DirectDraw and old Direct3D APIs. DirectDraw is not supported from DirectX 8 onwards and 2D stuff is done through the new improved Direct3D API. It really is a hell of a lot easier to use than DirectX 7.

Theres a good tutorial here on GameDev about the basics. It all seems a bit strange and overcomplicated at first to be messing about with verticies and textures to to 2D stuff but once you have a wrapper library written it is no more complex and certain aspects, such as setting up back buffering and swapping between windowed and full screen apps are actually a lot simpler than DirectDraw 7.

Plus you get lots of cool advantages like hardware scaling and alpha-blending as well as more prevalent hardware support on modern graphics cards.

Glad you got your code working by the way.

Topic Locked

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

Sign in to reply to this topic.