tags:

views:

128

answers:

1

I'm writing an isometric game, but unfortunately I've got stuck writing with the algorithm used to map back to world coordinates from screen coordinates (or possibly vice versa). Anyway I can't figure out the implementations which are the inverse of my GetScreenX/Y methods. Here's some code. width and height represent the width/height of the viewport area in tiles.

With the correct implementation, this should run through without any trouble. You can run it in Linqpad.

void Main()
{
 for(int width = 1;width<15;width++)
 { 
  for(int height = 1;height<10;height++)
  {
   for(int x = -50;x<50;x++){   
    for(int y = -50;y<50;y++){
     var screenX = GetScreenX(x, y, width, height);
     var screenY = GetScreenY(x, y, width, height);
     var worldX = GetWorldX(screenX, screenY, width, height);
     var worldY = GetWorldY(screenX, screenY, width, height);
     if (worldX != x || worldY != y)
     {
      throw new Exception("Algorithm not right!"); 
     }
    } 
   }
  }
 }
}

protected int GetScreenX(int x, int y, int width, int height)
{
 return WrappingMod(x + y, width);
}

protected int GetWorldX(int x, int y, int width, int height)
{
 return 1; //needs correct implementation
}

protected int GetWorldY(int x, int y, int width, int height)
{
 return 1; //needs correct implementation
}

protected int GetScreenY(int x, int y, int width, int height)
{
 return WrappingMod((int) ((y - x)/2.0), height);
}

static int WrappingMod(int x, int m)
{
 return (x % m + m) % m;
}

Sorry to have to ask but I'm at my wits end!

A: 

I don't understand your WrappingMod function. You seem to calculate the screen coordinate, and then take it modulo viewport dimension (twice) just for the hell of it. That makes your world->screen mapping non-bijective, so it has no inverse.

Why are you drawing several tiles ontop of each other to begin with?

Instead of taking the modulus, you should be wanting to raise an exception when the world coordinate doesn't fit in the viewport.

Pete
Hmm. It is a bit screwy seeming, I admit. Actaully what I'm doing is making a client server app. The client sends the viewport bounds up to the server, the server then tries to figure out which tiles are visible to the client (using the methods that require implementation), and sends the data for those tiles back to the client. The client then uses the GetScreen methods to position the tiles on screen.
jokersarejokers
The reason it does the wrapping mod is to bring them back into position on the screen, so when y = 0 and width = 8, x positions -12, -4, 4, 8, 12 etc. all get set to position 4
jokersarejokers
Hmm maybe you're right. The question is messed up
jokersarejokers
You need a parameter to the server about which set of tiles are in the viewport. The final solution depends on how you handle viewport moving, and it looks like your current solution is "skip to next set".In that case, you simply have GetWorldX(int x, int y, int offsetX) {return x/2+y+offsetX;}
Pete