Rendering Technique

Started by
14 comments, last by GameDev.net 17 years, 10 months ago
What would you do for larger maps...rendering all of mine would be bad...to say the least. My map is H U G E so I changed mine up to render a set number of tiles and just update which tiles are being rendered based on the screen offset position. The only problem i find is that i cant really have fine tile coords this way.

what i do now:

for( int y = 0; y< MapViewHeight; y++)
{
for(int x = 0; x< MapViewWidth; x++)
{
Tile t = Tiles[x + screenOffsetX, y + screenOffsetY];
DrawTile(t,x,y);
}

}

so i am rendering MapViewHeight * MapViewWidth tiles out of a large super set which is good for performance but i cant do fine map scrolling because it has to move by an entire tile.

So i need to find a way to draw the view section of the map the way it would be in worldspace so that i can move it by pixel instead of by tile.

did that make sense?
Advertisement
Quote:Original post by nex7
the mouse mapping logic was a bit tricky but the tile plotting was a LOT easier than the staggered map.


The mouse-to-tile mapping should be fairly straight forward (assuming you store your tiles as described in the second image in the original post - ie. as a standard 2D array). Just use the formulae given by Luctus, ie:

tile_x = (screen_y / tile_height) + (screen_x / tile_width)
tile_y = (screen_y / tile_height) - (screen_x / tile_width)

(I converted from matrices.)

Screen_x & Screen_y need to be the pixel location of the point you're converting, relative to the origin of the tile-map (ie. the top point of the diamond in the second picture). So you have to take into account any scrolling, basically.

Yeah, drawing the whole map will be too slow. Just draw the tiles that are going to be on screen. This is pretty easy to calculate in this example. Use the above formulae to calculate the tile-map location of the upper-left and lower-right corners of the screen, and then draw the tiles in lines that are horizontal in screen-space - ie. diagonal in tile-space (so in your loop you'll have tilex++; tiley++; or something).

You have to offset every second row, and this offset is actually calculated based on the fractal part of the tile co-ordinates of the upper-left corner of the screen. Mess about and you'll see what I mean.

Sorry this is confusingly written - it's actually all fairly simple stuff. I wrote a little C# app that renders a tilemap (in tile-space) and shows the screen (in tilespace - so it's a sort of big, distorted diamond) and messed about with my logic there until it was right, before putting it into the game engine to render normally. That helped heaps.


Yeah have everything working now...the mouse picking and tile rendering all works correctly, the only thing im missing is grabbing the screen rect out of my world array.


I have a 2d array...fairly standard....and i want to grab the screen rect out of the world space....

also normally you start drawing at 0,0....in this situation you cant do that...In my situation I have to start drawing directly north from the middle of my screen so that the edges of the diamond dont show up on the screen.

im sure i'm thinking about it wrong...and i just need to calculate where that tile would be in screen space given that formula....but im not quite there yet

as it stands i would never see the corners of my map...because i always draw my map as a 20x20 diamond and just switch out tiles based on location.
I feel... How you like to draw your ISO Map depends on How you like to represent the game(I method - Staggered or II Method - Diamond) .

For example in my

Isometric Engine
I use staggered Map. Since I want to make games like Jagged Allaince 2, I don't like to display empty blanks on the four sides of my Map.

But for my
Isometric Thief Game I have used Diamond (II Method) map, and it suits the type of setting for the game.

Which method is best?... Dunno... personally I prefer the 1st method :)
SamRock
anyone have an example of how to get a screenrect worth of tiles out of an array for a diamond tilemap?
Quote:Original post by nex7
anyone have an example of how to get a screenrect worth of tiles out of an array for a diamond tilemap?


This is a bit of a rough cut-n-paste from a C# project that I have here (my proper C++ code isn't here, I'm afraid). It's pretty messy, but maybe it will help. Basically what I do is:

1. Calculate the extents of the screen (stored in screenPoints), in tilespace.
2. Do some minor adjustments to the start tile (ie. the upper-left one) based on the screen's sub-tile location.
3. Draw the tiles, left to right, top to bottom, as you'd expect.

The obscurely-named bShiftX variable effectively determines whether, on moving to the next row of tiles, they are offset to the left (onscreen) or right of the row above (ie. in your first image up at the top there, at the end of the first row bShiftX would be false because going from tile 0 to tile 5 would - in my diamond tilemap - be an increment in the Y coordinate).

Confusing and poorly written I know, but maybe will help you a bit.

// Calculate the 'visible' tiles.double x1, y1;double x2, y2;double x3, y3;double x4, y4;// Transform screen corners into tilespace.x1 = screenPoints[0].X + adjustx;y1 = screenPoints[0].Y + adjusty;x2 = screenPoints[1].X + adjustx;y2 = screenPoints[1].Y + adjusty;x3 = screenPoints[2].X + adjustx;y3 = screenPoints[2].Y + adjusty;x4 = screenPoints[3].X + adjustx;y4 = screenPoints[3].Y + adjusty;double fracx1 = x1 - Math.Floor(x1);double fracy1 = y1 - Math.Floor(y1);double fracx2 = x2 - Math.Floor(x2);double fracy2 = y2 - Math.Floor(y2);// Height and width of screen, in tiles.int nScreenRowWidth = (int)x2 - (int)x1 + 1;int nScreenColHeight = ((int)x1 - (int)x4 + 1) * 2;// Based on sub-tile location of screen-rectangle, might have to// draw a very slightly different set of tiles.bool bShiftX = true;bool b1, b2;b1 = (fracx1 + fracy1) > 1.0;b2 = fracx1 > fracy1;if (!b1 && b2){	y1 -= 1.0;	bShiftX = false;}			if (b1 && !b2){	bShiftX = false;}if (b1 && b2){	x1 += 1.0;	bShiftX = true;}// Draw the tiles.for (int j = 0; j < nScreenColHeight; j++){	x = (int)Math.Floor(x1);	y = (int)Math.Floor(y1);	for (int i =0; i < nScreenRowWidth; i++)	{		/* DrawTile(x * tileWidth, y * tileHeight) */		x++;		y++;	} 	x1 -= bShiftX ? 1.0 : 0.0;	y1 += bShiftX ? 0.0 : 1.0;	bShiftX = !bShiftX;}	

This topic is closed to new replies.

Advertisement