Advertisement

Tiling methods (Height map?)

Started by July 13, 2000 10:10 PM
16 comments, last by cyberben 24 years, 5 months ago
first of all, why is it 12 * 9 and not 32 * 4 = 128 which is > 100?

you''re right this requires an entire article. too bad TANSTAAFL''s book is far from publishing (sigh). I''m a bit confused by the part where you have many tiles pointing to one instance of an object. Are you saying that they all point to the same object and in addition to that store an offset value so that it anchors correctly at A1? Is this how to draw the right part of the car eventhough the left part didn''t render?
thanks for the indepth reply. have you come across any articles on this subject on the net? I''ve tried a lot of search engines but it was a bloody waste of time...
quote: Original post by epic709

first of all, why is it 12 * 9 and not 32 * 4 = 128 which is > 100?

you''re right this requires an entire article. too bad TANSTAAFL''s book is far from publishing (sigh). I''m a bit confused by the part where you have many tiles pointing to one instance of an object. Are you saying that they all point to the same object and in addition to that store an offset value so that it anchors correctly at A1? Is this how to draw the right part of the car eventhough the left part didn''t render?
thanks for the indepth reply. have you come across any articles on this subject on the net? I''ve tried a lot of search engines but it was a bloody waste of time...


It should be 16 * 9 , sorry about that b.c the height offset is only one half the height of the tile so maybe be 16 * 7 > 100...

By all tiles pointing to one instance I meant that all the world objects locations should be stored seperately from the location of the tile that it originates in. For instance lets say your world map origin is in the upper left (0,0) you want to originate a tree at tile 10,10. Now you would create a seperate tree object - or for efficiency sake a structure pointing to the tree picture and x, and y coordinate. in my code I store objects like

struct picture_object {
spriteclass *obj; // the picture
int x_pos;
int y_pos;
};

struct ground_tile {
int texture;
ground_tile *next_level; // indicates seperate planes like floor levels
picture_object *p_object;
};

ground_tile MAP[100][100];

its x_pos value would be 10 *64 +-(odd row offset)= 640 and its y value would be 10 * 16 = 160. Then when you went to render it to the screen you would have to subtract the x and y of the window (the upper left screen coordinates in relation to the map) first - say windowx was at a location of 660, and windowy 10- then the object would be drawn to the sreen at -20, 150, and be properly clipped.

This way you can tell WHEN to draw it based on if any tiles containing the object are draw and WHERE to draw it based on its own location.

Now if you where to take the car example - when loading the map you would create a picture object for each tree. then each ''node'' or tile that contains that tree points to *that tree*. When you think of the tree as independant of the ground - it opens up many more possibilities. To get the code working proporly (ex sp) first try to only have only on tile point to the tree (say the origin or the tree upper left tile) you will see when it renders the tree will kind of pop on the screen all at once when that origin tile gets rendered. but it all the tiles containing the tree point to the tree then it should be rendered proporly. BUT if you draw the object when rendering the tiles it will be rendered once for every tile it overlaps and all tiles drawn after it will overlap the object. instead in your rendering loop you need to create a list of objects to draw.

code for that

where
ground_tile ground_map[200][100];
picture_object *object_list[MAX OBJECTS];

////////////////////////////////////////////////////////////////
int startmapx, startmapy, endmapx, endmapy;
int offsetx, offsety;

//--- Determine the starting and ending tiles #s to draw ---

// (windowx / tilewidth % 2) tells wether the row is indented
// ie every other row should be indented
startmapx = (windowx / tilewidth) - ( (windowx / tilewidth) %2);
// because each row overlaps the last, only divide my 1/2 tileheight
startmapy = ( (windowy) / (tileheight/2) );

endmapx = startmapx + numberofcolumns;
endmapy = startmapy + numberofrows;

// Determine the offset for the starting coordinate
offsetx = -(windowx % (tilewidth));

// the offset for an odd COLUMN will require the ROW to be indented one more
// tile to prevent jumping
if (startmapy%2 == 1)
{
offsetx -= offsetx;
}

offsety = -(windowy % (tileheight/2));
offsety -= tileheight;

// Make sure to add another tile if the tile being drawn is starting at 0 ie barely visable
if(offsetx)
endmapx++;
if(offsety)
endmapy++;

int texturex = offsetx;
int texturey = offsety;

int xstart = (windowx/tilewidth);

int number_of_obj = 0;

for (int indexy = startmapy; indexy <= endmapy; indexy++)
{
////////////////////////////////////////////////////////////////////
// Needs to be done every loop *need to find better way to do this*
// basically determines offset for even odd tiles
// if you add a texturex -= 32 or += 64 at the end of the loop it wont work
// proporely requires large article or more explanation
////////////////////////////////////////////////////////////////////
startmapx = xstart - (indexy %2);
offsetx = -(windowx % tilewidth);
offsetx -= tilewidth/2;
if (indexy%2 == 1)
{
offsetx = offsetx-tilewidth/2;
}
texturex = offsetx;

for (int indexx = startmapx; indexx <= endmapx; indexx++)
{
background.x = texturex; // Background is a picture BOB ala LeMothe''s engine
background.y = texturey;
background.curr_frame = ground_map[indexy][indexx].texture;
Draw_BOB16(&background,lpddsback);
// If an object is on that tile, add to draw list
if (ground_map[indexy][indexx].p_object.obj != NULL)
{
ground_map[indexy][indexx].p_object.x_pos -= windowx;
ground_map[indexy][indexx].p_object.y_pos -= windowy;
object_list[number_of_obj] = &ground_map[indexy][indexx].p_object;
number_of_obj++;
}
texturex += tilewidth;
}
texturey += tileheight/2;
}

// Iterate through object list and draw all picture objects
int r = 0;
while (object_list[r] != NULL)
{
object_list[r]->obj->move_picture(object_list[r]->x_pos,object_list[r]->y_pos);
object_list[r]->obj->draw();
object_list[r] = NULL; // Resetting the object list to NULL
r++;
}
///////////////////////////////////////////////////////////////////////////////////////

the code might be fairly criptic but thats how i fixed the tile overlap problem -its somwhat well documented so hopefully you can see my logic in there somewhere. the other problem with drawing the object multiple times might be solved *working on a good way now* by having a 4th variable in the picture object class thats a bool to wether its been draw or not in the frame....

As far as articles go this forum ive found to be the best, by far for iso engines. People have been kind enough to write many good articles for it - Check out Dino, TANS and Brackets article on D3D *pretty interesting*

Lep
Advertisement
ACK forgot to enter my name and cant change an error - ignore last

quote: Original post by epic709

first of all, why is it 12 * 9 and not 32 * 4 = 128 which is > 100?

you''re right this requires an entire article. too bad TANSTAAFL''s book is far from publishing (sigh). I''m a bit confused by the part where you have many tiles pointing to one instance of an object. Are you saying that they all point to the same object and in addition to that store an offset value so that it anchors correctly at A1? Is this how to draw the right part of the car eventhough the left part didn''t render?
thanks for the indepth reply. have you come across any articles on this subject on the net? I''ve tried a lot of search engines but it was a bloody waste of time...


It should be 16 * 9 , sorry about that b.c the height offset is only one half the height of the tile so maybe be 16 * 7 > 100...

By all tiles pointing to one instance I meant that all the world objects locations should be stored seperately from the location of the tile that it originates in. For instance lets say your world map origin is in the upper left (0,0) you want to originate a tree at tile 10,10. Now you would create a seperate tree object - or for efficiency sake a structure pointing to the tree picture and x, and y coordinate. in my code I store objects like

struct picture_object {
spriteclass *obj; // the picture
int x_pos;
int y_pos;
};

struct ground_tile {
int texture;
ground_tile *next_level; // indicates seperate planes like floor levels
picture_object *p_object;
};

ground_tile MAP[100][100];

its x_pos value would be 10 *64 +-(odd row offset)= 640 and its y value would be 10 * 16 = 160. Then when you went to render it to the screen you would have to subtract the x and y of the window (the upper left screen coordinates in relation to the map) first - say windowx was at a location of 660, and windowy 10- then the object would be drawn to the sreen at -20, 150, and be properly clipped.

This way you can tell WHEN to draw it based on if any tiles containing the object are draw and WHERE to draw it based on its own location.

Now if you where to take the car example - when loading the map you would create a picture object for each tree. then each ''node'' or tile that contains that tree points to *that tree*. When you think of the tree as independant of the ground - it opens up many more possibilities. To get the code working proporly (ex sp) first try to only have only on tile point to the tree (say the origin or the tree upper left tile) you will see when it renders the tree will kind of pop on the screen all at once when that origin tile gets rendered. but it all the tiles containing the tree point to the tree then it should be rendered proporly. BUT if you draw the object when rendering the tiles it will be rendered once for every tile it overlaps and all tiles drawn after it will overlap the object. instead in your rendering loop you need to create a list of objects to draw.

code for that

where
ground_tile ground_map[200][100];
picture_object *object_list[MAX OBJECTS];

////////////////////////////////////////////////////////////////
int startmapx, startmapy, endmapx, endmapy;
int offsetx, offsety;

//--- Determine the starting and ending tiles #s to draw ---

// (windowx / tilewidth % 2) tells wether the row is indented
// ie every other row should be indented
startmapx = (windowx / tilewidth) - ( (windowx / tilewidth) %2);
// because each row overlaps the last, only divide my 1/2 tileheight
startmapy = ( (windowy) / (tileheight/2) );

endmapx = startmapx + numberofcolumns;
endmapy = startmapy + numberofrows;

// Determine the offset for the starting coordinate
offsetx = -(windowx % (tilewidth));

// the offset for an odd COLUMN will require the ROW to be indented one more
// tile to prevent jumping
if (startmapy%2 == 1)
{
offsetx -= offsetx;
}

offsety = -(windowy % (tileheight/2));
offsety -= tileheight;

// Make sure to add another tile if the tile being drawn is starting at 0 ie barely visable
if(offsetx)
endmapx++;
if(offsety)
endmapy++;

int texturex = offsetx;
int texturey = offsety;

int xstart = (windowx/tilewidth);

int number_of_obj = 0;

for (int indexy = startmapy; indexy <= endmapy; indexy++)
{
////////////////////////////////////////////////////////////////////
// Needs to be done every loop *need to find better way to do this*
// basically determines offset for even odd tiles
// if you add a texturex -= 32 or += 64 at the end of the loop it wont work
// proporely requires large article or more explanation
////////////////////////////////////////////////////////////////////
startmapx = xstart - (indexy %2);
offsetx = -(windowx % tilewidth);
offsetx -= tilewidth/2;
if (indexy%2 == 1)
{
offsetx = offsetx-tilewidth/2;
}
texturex = offsetx;

for (int indexx = startmapx; indexx <= endmapx; indexx++)
{
background.x = texturex; // Background is a picture BOB ala LeMothe''s engine
background.y = texturey;
background.curr_frame = ground_map[indexy][indexx].texture;
Draw_BOB16(&background,lpddsback);
// If an object is on that tile, add to draw list
if (ground_map[indexy][indexx].p_object.obj != NULL)
{
object_list[number_of_obj] = &ground_map[indexy][indexx].p_object;
number_of_obj++;
}
texturex += tilewidth;
}
texturey += tileheight/2;
}

// Iterate through object list and draw all picture objects
int r = 0;
while (object_list[r] != NULL)
{
object_list[r]->obj->move_picture(object_list[r]->x_pos - windowx,object_list[r]->y_pos-windowy);
object_list[r]->obj->draw();
object_list[r] = NULL; // Resetting the object list to NULL
r++;
}
///////////////////////////////////////////////////////////////////////////////////////

the code might be fairly criptic but thats how i fixed the tile overlap problem -its somwhat well documented so hopefully you can see my logic in there somewhere. the other problem with drawing the object multiple times might be solved *working on a good way now* by having a 4th variable in the picture object class thats a bool to wether its been draw or not in the frame....

As far as articles go this forum ive found to be the best, by far for iso engines. People have been kind enough to write many good articles for it - Check out Dino, TANS and Brackets article on D3D *pretty interesting*
thanks for all the help. i definitely need a few days to digest all this. hope this topic is still active by then...

also, if you like take a peek at my code at

http://www.geocities.com/epic709

currently i''m having problems blitting objects from an offscreen surface to the backbuffer. The backbuffer already contains a D3D scene as in Bracket''s 3d in 2d iso article. BltFast() inside Layer1Render() returns an unknown HRESULT so I don''t know what''s going wrong.
thanks for all the help. i definitely need a few days to digest all this. hope this topic is still active by then...

also, if you like take a peek at my code at

http://www.geocities.com/epic709

currently i''m having problems blitting objects from an offscreen surface to the backbuffer. The backbuffer already contains a D3D scene as in Bracket''s 3d in 2d iso article. BltFast() inside Layer1Render() returns an unknown HRESULT so I don''t know what''s going wrong.
quote: Original post by epic709

thanks for all the help. i definitely need a few days to digest all this. hope this topic is still active by then...

also, if you like take a peek at my code at

http://www.geocities.com/epic709

currently i''m having problems blitting objects from an offscreen surface to the backbuffer. The backbuffer already contains a D3D scene as in Bracket''s 3d in 2d iso article. BltFast() inside Layer1Render() returns an unknown HRESULT so I don''t know what''s going wrong.


I just took a look at the code briefly but
BBuffer->BltFast(400,300, /*&dest_rect,*/ OffScr1, &source_rect,
DDBLTFAST_NOCOLORKEY /*DDBLT_KEYSRC | DDBLT_WAIT, NULL*/);

OffScr1 might need to be &OffScr1 -- although id have to disect the code - ill take a look at it... lemme know if that works.. I dont use blt fast often so who know good luck.
Advertisement
nope, that didn''t work. gave this:

error C2664: ''BltFast'' : cannot convert parameter 3 from ''struct IDirectDrawSurface7 ** '' to ''struct IDirectDrawSurface7

what stumps me completely is the HRESULT. it DOESN''T match any of the possible values returned by BltFast()! When I debug, HRESULT is just a long number - is there a way to find out what this number means? All I know is that HRESULT != DD_OK

I thought it was the format of my Layer1.bmp bitmap which was 8bit but I changed it to 16bit but still no luck. I practically followed the DirectDraw tutorial 3 step for step to do this (which BTW works fine on its own).
figured out what was wrong. apparently my offscreen surface had a clipper attached (although my code only SetClipper() for my primary surface). guess clippers are inherited by other surfaces created from the same DDraw object. anyway, changing to Blt() saved the day.

This topic is closed to new replies.

Advertisement