Renderização isométrica e picking?

23

Estive procurando uma fórmula para plotar azulejos isométricos (mundo-> tela) e escolher mouse (mundo-> tela) em um mundo em forma de diamante. Os que eu tentei sempre parecem estar bem. Qual é a maneira usual / correta de fazer isso?

mpnk121
fonte
O método exato e a fórmula usados ​​dependem um pouco da forma dos seus ladrilhos e, provavelmente, um pouco da maneira como você desenha o mapa (é 0,0 na parte superior, inferior ou em um dos lados do mapa). sobre o seu problema ajudaria.
Thedaian
1
Os blocos são 2: 1 (mais especificamente, 64x32). O sistema de coordenadas não importa, pois estou escrevendo o editor. (No entanto 0,0 na parte superior ou esquerda parece sensato.)
mpnk121
Muito tarde para a pergunta e eu nem tenho uma resposta completa, mas houve um Google Tech Talk muito bom sobre esse assunto preciso. Sua configuração inclui escolher a parte não transparente de imagens arbitrárias (em javascript, nada menos). youtube.com/watch?v=_RRnyChxijA
Seth Battin

Respostas:

21

Com base no seu comentário, eis o código que estou usando para converter os valores x, y do bloco em coordenadas na tela. Agora, ele não leva em conta "blocos 3d", tudo é considerado como estando no mesmo plano; portanto, se você estiver escrevendo um jogo onde isso importa, esse código não funcionará.

//this converts a map x/y coordinate into screen coordinates
//public, static method, so can be called outside the Tile object
point Tile::convertToScreen(int x, int y, int offsetX, int offsetY)
{
        point screen;
        //calculate the screen coordinates
        //note: these will then be modified by the camera
        screen.x = offsetX - (y * TILE_WIDTH/2) + (x * TILE_WIDTH/2) - (TILE_WIDTH/2);
        screen.y = offsetY + (y * TILE_DEPTH/2) + (x * TILE_DEPTH/2);
        return screen;
 }

point é simplesmente uma estrutura contendo x e y ints, TILE_WIDTH seria 64 no seu caso, TILE_DEPTH é meio que mal nomeado (na verdade, é a altura dos gráficos do bloco), mas seria 32 no seu caso. As compensações são se você deseja que seu mapa de blocos "inicie" em um local x, y diferente (como se você deseja que os blocos estejam acima de outro conjunto de blocos). Normalmente, o deslocamento pode ser 0,0.

Isso irá gerar um mapa com 0,0 no topo, no meio, assim:

        0,0
    0,1     1,0
0,2     1,1     2,1

Quanto à localização do bloco x, y do cursor:

point selectedTile;
int x = mX - camera.x;
int y = mY - camera.y;
selectedTile.x = (y + x/2)/TILE_DEPTH;
selectedTile.y = (y - x/2)/TILE_DEPTH;

Nesse pedaço de código, mX e mY são as coordenadas da tela do mouse, que estamos combinando com os valores da câmera para descobrir onde estamos nas "coordenadas mundiais". Tudo o resto é igual ao exemplo de código anterior.

Mais uma vez, isso pressupõe um mapa de blocos 2D isométrico plano. Há algum trabalho adicional se você quiser usar uma visualização semi-3d do mapa, e tudo isso pressupõe que você esteja trabalhando em 2D de qualquer maneira.

thedaian
fonte
1
Obrigado! - isso funciona muito bem para mapas planos. Agora, você pode me contar um pouco mais sobre como eu poderia adicionar blocos de tamanho arbitrário (ou seja, com profundidade Z) que estão em outra camada? (Tal como suportes como um bem ou de um poste)
mpnk121
2
É quando você usa os valores offsetY e offsetX. Se sua iluminação da rua for 64x64, passar um valor negativo de 32 para o valor de offsetY deve aparecer no lugar certo. Espero que isso seja o suficiente para você começar.
Thedaian 17/05
6
A coordenada "2,1" no seu exemplo não deve ser "2,0"?
31512 Chris