2
\$\begingroup\$

I'm putting together an isometric engine and need to cull the tiles that aren't in the camera's current view. My tile coordinates go from left to right on the X and top to bottom on the Y with (0,0) being the top left corner.

If I have access to say the top left, top right, bottom left and bottom right corner coordinates, is there a formula or something I could use to determine which tiles fall in range?

This is a screenshot of the layout of the tiles for reference. screenshot

If there isn't one, or there's a better way to determine which tiles are on screen and which to cull, I'm all ears and am grateful for any ideas. I've got a few other methods I may be able to try such as checking the position of the tile against a rectangle. I pretty much just need something quick. Thanks for giving this a read =)

\$\endgroup\$
3
  • \$\begingroup\$ When you say top/bottom left/right coordinates, how are your tiles' coordinates specified? Just by their row/column as indicated in your picture? \$\endgroup\$
    – user14497
    Mar 20, 2012 at 19:33
  • \$\begingroup\$ How are you drawing them now? \$\endgroup\$
    – House
    Mar 21, 2012 at 15:24
  • \$\begingroup\$ They are laid out as they are in the picture. X value from left to right and Y value from top to bottom. Currently, I'm just drawing everything with no culling at all. \$\endgroup\$
    – Steve
    Mar 21, 2012 at 16:12

2 Answers 2

2
\$\begingroup\$

X+Y is constant for all tiles in a column, and X-Y is constant for all tiles in a row. In your current screenshot, it seems like your screen is centered at (X=15,Y=15) or alternatively, at (X+Y=30,X-Y=0)

  • 20 <= X+Y < 40 (vertical axis)
  • -8 <= X-Y < 10 (horizontal axis)

Your loop should be based on X+Y, and X-Y, not precisely X and Y.

// current viewport is x+y=20to40 by x-y=-8to10 
for(a=20;a<40;a++) {
    for(b=-8;b<10;b++) { 
       if ((b&1) != (a&1)) continue;
       x = (a+b)/2;
       y = (a-b)/2;
       // do stuff with X and Y here
    }               
}​

Here's the demo

\$\endgroup\$
1
  • \$\begingroup\$ Beautiful. Thanks a bundle, this works perfectly. I've got all the various elements in my game sorted into lists currently and each object contains the gridNumber that it is currently occupying. Before the draw call, I go through the lists and check using if(minX <= gridNumber.X && gridNumber.X < maxX) { object.isCulled = false;} on every object. I'm gonna have to figure out a way to do this in a more efficient manner but the selection of which numbers are valid work perfectly. thanks again! =) \$\endgroup\$
    – Steve
    Mar 21, 2012 at 23:08
0
\$\begingroup\$

To get how many titles you can display on screen (with rounding taken into account):

numOfTitlesX = (int)((float)screenWidth / titleWidth + 0.5f);
numOfTitlesY = (int)((float)screenHeight / titleWidth + 0.5f); 

Now you can just make loop to draw your titles. An example loop could look like this (without boundary check!):

for(int y = 0; y < numOfTitlesY; y++){
   for(int x = 0; y < numOfTitlesX; x++){
       titles[startingTopLeftIndex + y][startingTopRight + x].draw(screenDeltaX, screenDeltay);
   }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .