2010-11-30 6 views
0

현재 XNA 게임 프로토 타입을 작업 중입니다. 게임 세계의 등각 투영 뷰를 얻으려고합니다 (또는이 투영에 적합한 용어가 무엇인지 확실하지 않습니다 - 그림 참조). 세계는 큐브 타일로 이루어진 타일 기반 세계 (예 : Minecraft의 세계와 유사)가 있어야하며 스프라이트를 사용하여 2D로 렌더링하려고합니다.XNA 아이소 메트릭 타일 렌더링 문제

그래서 큐브의 앞면과 앞면 및 측면 (보이는면)이있는 스프라이트 시트가 있습니다. 3 개의 draw (Draw, Draw, Sprite) 호출을 사용하여 타일을 그립니다. 하나는 위쪽, 다른 하나는 앞면, 하나는 소스 사각형을 사용하여 그려야하는면을, 다른 하나는 대상 사각형을 사용하여 화면상의 위치를 ​​설정합니다. 3D 세계 좌표를 등각 투영법 (orthographic?)으로 변환하는 수식입니다.

(샘플 스프라이트 : Sprite)이 좋은만큼 내가 얼굴을 그려,하지만 난 (타일 그리드에 따라) 각 블록의 미세 가장자리를 그릴하려고하면 내가 얻을 것을 볼 수 있습니다로 작동

일부 선은면 자체에 겹쳐 쓰여지고 일부는 그렇지 않은 임의의 렌더링 패턴입니다.

내 세계를 표현하기 위해 X가 왼쪽에서 오른쪽이고 Y가 화면 외부에 있으며 Z가 아래입니다.

이 예제에서는 맨 얼굴 가장자리로만 작업하고 있습니다. 여기에 내가 (사진을) 무엇을 얻을 : 라인의 일부가 표시 일부는하지 왜 이해가 안

alt text

. I 사용 렌더링 코드는 (주이 예에서는 각 차원의 최상부 층을 드로잉하고있어)

/// <summary> 
/// Draws the world 
/// </summary> 
/// <param name="spriteBatch"></param> 
public void draw(SpriteBatch spriteBatch) 
{ 
    Texture2D tex = null; 

    // DRAW TILES 
    for (int z = numBlocks - 1; z >= 0; z--) 
    { 
     for (int y = 0; y < numBlocks; y++) 
     { 
      for (int x = numBlocks - 1; x >=0 ; x--) 
      { 

       myTextures.TryGetValue(myBlockManager.getBlockAt(x, y, z), out tex); 
       if (tex != null) 
       { 
        // TOP FACE 
        if (z == 0) 
        { 
         drawTop(spriteBatch, x, y, z, tex); 
         drawTop(spriteBatch, x, y, z, outlineTexture); 
        } 

        // FRONT FACE 
        if(y == numBlocks -1) 
         drawFront(spriteBatch, x, y, z, tex); 

        // SIDE FACE 
        if(x == 0) 
         drawSide(spriteBatch, x, y, z, tex); 

       } 
      } 
     } 
    } 
} 


private void drawTop(SpriteBatch spriteBatch, int x, int y, int z, Texture2D tex) 
     { 
      int pX = OffsetX + (int)(x * TEXTURE_TOP_X_OFFRIGHT + y * TEXTURE_SIDE_X); 
      int pY = OffsetY + (int)(y * TEXTURE_TOP_Y + z * TEXTURE_FRONT_Y); 
      topDestRect.X = pX; 
      topDestRect.Y = pY; 
      spriteBatch.Draw(tex, topDestRect, TEXTURE_TOP_RECT, Color.White); 
     } 
난 후 루프 중첩 된 제 3 계층을 생성하는 다른 방법을 사용하여 시도

첫 번째, 그래서 첫 번째 루프에서 드로잉 윗면을 유지하고 두 번째 루프의 가장자리를 강조 표시합니다. (저는 이것이 비효율적입니다. 그리기 위해 각 타일에 대한 메서드 호출을 피하는 것이 좋습니다. 그냥 지금 당장 작동시키려는 것).

결과는 어떻게 든 더 나은하지만 여전히 기대, 상단 행으로 작동하지 않는 것은 누락, 그림 참조 :

alt text

왜이 문제에 봉착했습니다의 어떤 생각? 첫 번째 접근법에서는 일종의 z-fighting 일 수도 있지만 스프라이트를 정확한 순서로 그리기 때문에 이미 존재하는 것을 덮어 쓰지 않아야합니까? 1 개 또는 2 픽셀 소스 및 대상 사각형의 크기를 조정

모두에게 감사

+0

크기 조정 중입니까? –

답변

1

와우, 미안 나는 바보 야. :) SpriteBatch.begin (SpriteSortMode.BackToFront)을 사용하여 배치를 시작했지만 그릴 때 z 값을 사용하지 않았다. SpriteSortMode.Deferred를 사용해야합니다! 이제는 잘 작동합니다. 모두에게 감사드립니다!

0

보십시오. 저는이 직사각형이 렌더링 될 영역의 일종의 외곽선과 일종의 비대칭적인 문제로 처리되는 방식과 관련이 있다는 몰래 의심합니다. 이것은 전문가 조언이 아니라 동료 코더의 직감입니다.

0

서브 픽셀 정밀도 또는 스케일링 문제처럼 보입니다. 또한 텍스처/타일 너비/높이가 2의 제곱수 (32, 64, 128 등)인지 확인하여 효과를 나쁘게 만들 수 있습니다. 그 그림들에서 말하기는 정말로 어렵습니다.

모든 것을 확장하는 방법/방법을 모르겠지만 (특히 drawTop() 메서드 내에서) 가능한 한 반올림하지 않도록해야합니다.매번 위치를 반올림/좌표 기회가 좋으면 오류/임의 오프셋을 늘릴 수 있습니다. 정수 대신 double (또는 better : float) 좌표를 사용하십시오.

+0

지금은 1 : 1 눈금을 사용하고 있는데, 눈금을 변경하면 특정 눈금 (예 : 주어진 눈금의 픽셀을 "놓친다")에서 일부 인공물을 실행하지만 그 밖의 것은 괜찮습니다. 또한 사각형 원점은 int 값으로 만 설정할 수 있습니까? – Marco83

+0

절대 사용하지 마십시오 (주로 DirectX 및 OpenGL에 집중). 화면 좌표/픽셀을 사용하면 정수도됩니다. 그것들을 계산하는 동안 라운드하지 마십시오 (통과하기 전에). – Mario

관련 문제