calculating the onscreen

Started by
3 comments, last by rebis 23 years, 3 months ago
Isometrists, I can draw tiles in their correct isometric positions no problem. I use a "diagonal map" that looks like: 1 4 2 7 5 3 8 6 9 My map is larger than what would fit onscreen so I need to either: 1. Draw the entire map in a very large offscreen buffer, then pull out the current rect that is being viewed or 2. Calculate what is being viewed and draw those tiles only, saving lots of memory. How can one calculate what is supposed to be shown? I asked this question in August, and got a response that was specific for a staggered map that looked like: 1 2 3 4 5 6 7 8 9 I need to know how to calculate this for the diagonal map. Any help greatly appreciated. -Ashley
Advertisement
(I haven''t implented one of these in a while... not since my Amiga days.)

Basically:

(1)Create an offscreen buffer that is 2x the width and 2x the height.

(2)Use a viewport that accesses this buffer.

(3)As the viewport moves, draw tiles around the viewport onto the offscreen buffer.

(4)When the viewport moves off of the offscreen buffer, cycle it around to the opposite side. (And if you copied the tiles correctly, the result is seamless scrolling, and quick at that.)

I hope this helps.

.Travois. (who misses the Amiga days...)
Still not 100% sure about what you mean here. I would draw a bigger offscreen than the viewport, but not necessarily the entire map. Ok, this would save memory if my map was large. However, I would still have to calculate which map cells need to be drawn when the offscreen map gets scrolled. This is what I still do not understand how to do. For the "staggered" isometric map such as,

1.2.3.
.4.5.6
7.8.9.

this is easy because you just keep track of what map cell is in the corners of the viewport and draw everything in between. In this case, if the viewport was big enough to see the whole map I would just tell the drawing function to draw from 1 to 9. For a "diagonal" isometric map such as,

..1...
.4.2..
7.5.3.
.8.6..
..9...

it is not obvious to me how one keeps up with what map cells are in the corners of the viewport or how to feed that data to the drawing function. For example, if the map cells on the corners of the viewport are 4,2,6,8...how in the heck can that be feed into the drawing loop? Is this gibberish understandable to anyone?

Ashley

quote:Original post by TV

(I haven''t implented one of these in a while... not since my Amiga days.)

Basically:

(1)Create an offscreen buffer that is 2x the width and 2x the height.

(2)Use a viewport that accesses this buffer.

(3)As the viewport moves, draw tiles around the viewport onto the offscreen buffer.

(4)When the viewport moves off of the offscreen buffer, cycle it around to the opposite side. (And if you copied the tiles correctly, the result is seamless scrolling, and quick at that.)

I hope this helps.

.Travois. (who misses the Amiga days...)


I am sorry for this inconvience, but to describe this I will have to use this convention:

      (3,0)     (2,0)(3,1)    (1,0)(2,1)(3,2)   (0,0)(1,1)(2,2)(3,3)       (0,1)(1,2)(2,3)           (0,2)(1,3)               (0,3) 


As you see, the map is a 2d array, with the first index (0,0) beginning on the left-most tile. As X increases, the indexed tile rises up-right. As Y increases, tiles go down-right. (This can be pictured as a square tiles and buffer rotated 45 degrees counter-clockwise)

Problem 1: Determining border.

As you see, to draw tiles in a horizontal line (across top and bottom of viewport, into offscreen buffer) it follows a pattern of (x,y)(x+1,y+1)(y+2,y+2)... and so on.

However, there is one note. Since the tiles are diamond shaped, the tiles need to draw those in between, otherwise there would be a gap. So, the new horizontal methods are:

Copying top of buffer: (in-between tiles are bold)
(x,y)(x+1,y)(x+1,y+1)(x+2,y+1)(x+2,y+2)... and so on.

Copying bottom of buffer: (in-between tiles are bold)
(x,y)(x,y+1)(x+1,y+1)(x+1,y+2)(x+2,y+2)... and so on.

[ (x,y) represents the tile to start copying ]
The algorithm changes from top and bottom because the top-copy must account for adjacent tiles above the tiles, and vice-versa with the bottom.

The vertical copying is very similar to the above, with the appropriate modifications.

Copying left of buffer:
(x,y)(x-1,y)(x-1,y+1)(x-2,y+1)(x-2,y+2)

Copying right of buffer:
(x,y)(x,y+1)(x-1,y+1)(x-1,y+2)(x-2,y+2)

[ The diagram above confusingly shows that there is a vertical alignment among (x,y) and (x-1,y+1) values; ex: (3,0) and (2,1) are aligned.)

This works well, assuming you have some form of checking of tiles out-of-bounds. In these cases, simply draw a blank tile (black diamond, in most cases).

If you have more questions, feel free to email me. (address in my profile.)

.Travois.
Aw shucks...

I should also describe how to fill in the screen will the tiles that are only on the screen... if you decide to use the offscreen buffer method or draw only the tiles in viewport directly to a backbuffer this is useful.

This will use the same convention as the last example used. (x,y) will represent the tile at the top-left of screen.


Algo:

You copy the first tile (x,y)
Then copy from (x-1,y+1) to (x+1,y+1)
Then copy from (x-2,y+2) to (x+2,y+2)
and so on...

As you see, the length gets longer each time, and each line copied starts on the left of the screen and goes up right until it reaches the top of the screen. (start-x decreases, end-x increases) As a performance note, you can safely assume that only the first and last tile copied need clipped at all, since they are the only ones at the edge of the screen. In between nodes can be copied without any checking. (Unless of course, tiles can be larger shapes than their diamond bases.)

This copying process gets continued until it reaches the bottom of the screen. You can monitor this by stopping once the tiles copied equals tiles_per_screen_height.

This can be thought of as:
for (y=0; y < tiles_per_screen_height; ++y) for (x=-y; x < y; ++x)  copy_tile(Xbase+x,Ybase+y)  


And yes, copy_tile is the function that places the tile in the right place...

Once those have been copied, the 2nd process copies tiles in a similar fashion; this time from bottom of screen to right of screen. Now, the start-x increases as the end-x decreases.

Algo:
[ '8' is just an arbitrary # representin'. ]

First line of tiles from (x-8,y+8) to (x+8,y+8)
Next line of tile from (x-7,x+9) to (x+6,x+9)
down to...
(x-0,y+16) to (x+0, y+16) or simply, (x, y+16), the last tile on bottom right of screen.


Hope this enlightens you to some extent...

.travois.

Edited by - tv on January 18, 2001 4:36:48 AM

This topic is closed to new replies.

Advertisement