2011-08-02 3 views
7

그래서이지도를 그릴 때 각 타일의 위치를 ​​계산하는 첫 번째 부분 (알고리즘)을 작성했습니다 (아래 참조). 그러나 마우스 위치에서 셀을 가져 오는 방법을 알아낼 수 없기 때문에 마우스 위치를 적절한 셀로 변환 할 수 있어야하고 머리카락을 거의 꺼내 왔습니다. 내 관심사는 꽤 높은 수학이나 무언가를 포함한다는 것입니다. 나는 눈치 채기가 쉽지 않습니다.
예를 들어, 마우스 위치가 112; 35 인 경우 어떻게 계산합니까? 셀이 2; 3이면 그 위치에 있습니까? 어쩌면 여기에 정말 도움이되는 수학을 생각하는 프로그래머가 있습니다. 누가 어떻게하는지 알고 있거나 정보를 줄 수있는 사람이 있습니까?아이소 메트릭 타일 맵에서 마우스 위치를 변환하는 방법은 무엇입니까?

enter image description here

var cord:Point = new Point(); 
cord.x = (x - 1) * 28 + (y - 1) * 28; 
cord.y = (y - 1) * 14 + (x - 1) * (- 14); 

지도, 각각의 셀 (투명 타일 56x28 픽셀) 말하기 이전 셀의 중앙에 위치 (또는 셀 1 제로 위치 1) 상기 셀을 위치로 변환하는 데 사용하는 코드입니다. 나는 위치와 셀에 많은 것들과 계산을 시도했지만 각각 실패했다.

편집 : 정보 많이 읽은 후 그것을 보인다 (색 타일에 매핑됩니다) 화면 색상 맵을 사용하는 것이 가장 빠르고 가장 효율적인 해결책이 있는지?

+0

을 그리는에 사용하는거야? OpenGL과 같은 많은 그래픽 프레임 워크는 마우스 - 투 - 월드 변환을 수행하는 도우미 메서드를 가지고 있습니다. – AShelly

+0

플래시 BitmapData입니다. – Rihards

+0

참조 : [click-detection-in-a-2d-isometric-grid] (http://stackoverflow.com/questions/5611982/click-detection-in-a-2d-isometric-grid) – AShelly

답변

6
(1) x` = 28x -28 + 28y -28 = 28x + 28y -56 
(2) y` = -14x +14 +14y -14 = -14x + 14y 

변환 테이블 :

[x] [28 28 -56 ] = [x`] 
[y] [-14 14 0 ] [y`] 
[1] [0 0 1 ] [1 ] 

[28 28 -56 ]^-1 
[-14 14 0 ] 
[0 0 1 ] 

계산 플로터로 (내가 좋아하는 wims) 것을

[1/56 -1/28 1 ] 
[1/56 1/28 1 ] 
[0  0 1 ] 

x = 1/56*x` - 1/28y` + 1 
y = 1/56*x` + 1/28y` + 1 
+0

줄 수 있습니까? 그것이하는 일과 어떻게 작동하는지에 대한 약간의 조명? – Rihards

+0

http://en.wikipedia.org/wiki/Transformation_matrix .. 변환의 한면을 알고 있다면 기본적으로 다른면을 얻는 것이 쉽습니다 .. 따라서 V * A = V'가됩니다. 곱하기 A (- 1) 양면에 V * 1 = V' * A (-1) –

+0

내가 변환 할 대상은 무엇입니까? 전체지도 이미지를 기반으로 사각형을 만든 다음 셀을 쉽게 계산할 수 있습니까? – Rihards

0

한 가지 방법 사각형 돌출부로 다시 회전하는 것입니다 :

먼저 y를 번역하면 t가됩니다. 그는 치수는 원점을 기준으로 다음과 같습니다

x0 = x_mouse; 
y0 = y_mouse-14 

이 그런 다음 타일 크기로 확장 :

x1 = x/28; //or maybe 56? 
y1 = y/28 

그런 다음 투사 각도

a = atan(2/1); 
x_tile = x1 * cos(a) - y1 * sin(a); 
y_tile = y1 * cos(a) + x1 * sin(a); 

나는 마이너스 기호를 누락 될 수 있습니다에 의해 회전, 그러나 그것은 일반적인 생각입니다.

+0

전체지도 이미지를 뒤로 회전 예? 그것을 사각형 기반으로 만드시겠습니까? – Rihards

+0

전체지도를 회전시키지 않아도됩니다. 회전을 마우스 위치에 적용하기 만하면지도가 회전 된 것과 같은 좌표가 좌표로 나타납니다. 그러나, 나는 @ yochai의 답변이 좀 더 실용적인 해결책이라고 생각한다. – AShelly

+0

@ yochai의 예에서도 마우스 위치에만 회전을 적용합니까? 안 그래요? 마우스 위치를 왜곡하거나 회전시킬 수있는 방법이 보이지 않기 때문에 (예 : 112,35). – Rihards

0

원래 질문에서 언급하지는 않았지만 의견에서 플래시로 프로그래밍한다고 말한 것 같습니다. 이 경우 Flash에는 행렬 변환 함수가 제공됩니다. (. 예를 들어, 등각 투영 좌표) :

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html

당신은 회전하고 회전 방식의 역의 행렬을 확장 할 것

및 확장 그래픽 좌표계 사이의 변환하는 가장 강력한 방법은 매트릭스 변환을 사용하고 있습니다 .

1

이 사이트에서 알고리즘을 찾았습니다. http://www.tonypa.pri.ee/tbw/tut18.html. 나는 그것을 제대로 작동시키지 못했지만 시행 착오로이 형식으로 바꾼다. 지금은 나를 위해 일한다.

int x = mouse.x + offset.x - tile[0;0].x; //tile[0;0].x is the value of x form witch map was drawn 
int y = mouse.y + offset.y; 
double _x =((2 * y + x)/2); 
double _y= ((2 * y - x)/2); 
double tileX = Math.round(_x/(tile.height - 1)) - 1; 
double tileY = Math.round(_y/(tile.height - 1)); 

이것은 내가 위와 같이 타일을 렌더링

for(int x=0;x<max_X;x++) 
for(int y=0;y<max_Y;y++) 
map.drawImage(image, ((max_X - 1) * tile.width/2) - ((tile.width - 1)/2 * (y - x)), ((tile.height - 1)/2) * (y + x)); 
2

enter image description here

내 맵 생성이다.

매우 간단합니다!

먼저 :

내 타일 폭과 높이 모두 = 32이다은 이는 그 사시도에서 폭 및 높이 = 32 = 16! 이 경우 Mapheight는 5 (최대 Y 값).

y_iso & x_iso == 0시 y_mouse = MapHeight/tilewidth/2 x_mouse =

0시 x_mouse + = 1, y_iso - = 1

그래서 우선 I의 "픽셀 별 변환"계산

tileY의

= ((y_mouse * 2) - ((MapHeight tilewidth *)/2) + x_mouse)/2;

TileX = x_mouse-TileY;

난 그냥 tilewidth

tileY의 = tileY의/(32)에 의해 모두으로 나눔 좌표 타일을 찾을 수 있습니다; TileX = TileX/32;

완료! 아무런 문제가 없었습니다!

5

나는 오래된 게시물 인 것을 알고 있지만, 일부 사람들은 내가 오늘 이전과 마찬가지로이 문제에 대한 답을 찾을 수도 있기 때문에 이것을 업데이트하고 싶습니다. 그러나, 나는 이것을 스스로 알아 냈다. 이 방법을 사용하면 타일을 겹치지 않게 렌더링 할 수 있습니다.

코드는 다음처럼 간단하다 :

mouse_grid_x = floor((mouse_y/tile_height) + (mouse_x/tile_width)); 
mouse_grid_y = floor((-mouse_x/tile_width) + (mouse_y/tile_height)); 

mouse_xmouse_y 마우스 화면 좌표입니다.

tile_heighttile_width은 이미지 자체가 아닌 실제 타일 크기입니다. 내 예제 그림에서 볼 수 있듯이 타일 아래에 흙을 추가했습니다. 이는 렌더링하기 쉽도록 실제 크기가 24 x 12입니다. 좌표는 결과 격자 x 및 y를 반올림하여 유지하기 위해 "바닥"처리됩니다.

또한이 타일을 y = 0 및 x = tile_with/2 (빨간색 점)에서 렌더링합니다. 이것은 내 0,0이 실제로는 타일의 상단 모서리 (기울어 진 부분)에서 시작하고 야외에서는 밖으로 나오지 않는다는 것을 의미합니다. 이 타일을 회전 된 사각형으로 보시고, 여전히 0,0 픽셀부터 시작하고 싶습니다.

타일은지도 크기에 Y = 0 및 X = 0으로 시작하여 렌더링됩니다. 첫 번째 행이 렌더링 된 후 몇 픽셀 아래로 건너 뛰고 왼쪽으로 건너 뜁니다. 이렇게하면 타일의 다음 줄이 첫 번째 줄과 겹치게되어 레이어를 서로 겹치게 유지할 수 있습니다. 타일을 렌더링 한 다음 그 타일에 무엇이든 다음 타일로 이동해야합니다.

나는 너무 렌더링 예를 추가 할 것입니다 :

for (yy = 0; yy < map_height; yy++) 
{ 
    for (xx = 0; xx < map_width; xx++) 
    { 
      draw tiles here with tile coordinates: 
      tile_x = (xx * 12) - (yy * 12) - (tile_width/2) 
      tile_y = (yy * 6) + (xx * 6) 

      also draw whatever is on this tile here before moving on 
    } 
} 

Isometric Image

관련 문제