Estou escrevendo um jogo 2D isométrico e estou tendo dificuldade em descobrir exatamente em qual bloco o cursor está. Aqui está um desenho:
onde xs e ys são coordenadas da tela (pixels), xt e yt são coordenadas do bloco, W e H são a largura e a altura do bloco em pixels, respectivamente. Minha notação para coordenadas é (y, x) que pode ser confusa, desculpe por isso.
O melhor que pude descobrir até agora é o seguinte:
int xtemp = xs / (W / 2);
int ytemp = ys / (H / 2);
int xt = (xs - ys) / 2;
int yt = ytemp + xt;
Isso parece quase correto, mas está me dando um resultado muito impreciso, dificultando a seleção de determinados ladrilhos, ou às vezes ele seleciona um ladrilho ao lado daquele em que estou tentando clicar. Não entendo o porquê e gostaria que alguém pudesse me ajudar a entender a lógica por trás disso.
Obrigado!
Eu tive esse mesmo problema em um jogo que estava escrevendo. Eu imagino que esse problema será diferente com base em como exatamente você implementou seu sistema isométrico, mas explicarei como resolvi o problema.
Comecei com minha função tile_to_screen. (Suponho que é assim que você coloca os ladrilhos no local certo em primeiro lugar.) Essa função tem uma equação para calcular screen_x e screen_y. O meu ficou assim (python):
Peguei essas duas equações e as transformei em um sistema de equações lineares. Resolva esse sistema de equações em qualquer método que você escolher. (Eu usei um método rref. Além disso, algumas calculadoras gráficas podem resolver esse problema.)
As equações finais eram assim:
Como você pode ver, não é simples como a equação inicial. Mas funciona muito bem para o jogo que criei. Graças a Deus pela álgebra linear!
Atualizar
Depois de escrever uma classe Point simples com vários operadores, simplifiquei esta resposta para o seguinte:
fonte
Você está usando um bom sistema de coordenadas. As coisas ficam muito mais complicadas se você usar colunas escalonadas.
Uma maneira de pensar sobre esse problema é que você tem uma função para transformar (xt, yt) em (xs, ys). Vou seguir a resposta de Thane e ligar
map_to_screen
.Você quer o inverso dessa função. Nós podemos chamá-lo
screen_to_map
. Inversos de funções têm estas propriedades:Essas duas coisas são boas para o teste de unidade depois que você tiver as duas funções escritas. Como você escreve o inverso? Nem todas as funções têm inversas, mas neste caso:
Certifique-se de testar se a função inversa + original retorna a resposta com a qual você começou. Thane passa nos dois testes, se você remover o
+ TILE_HEIGHT/2
deslocamento de renderização. Quando resolvi a álgebra, criei:que eu acredito que é o mesmo que Thane
screen_to_map
.A função transformará as coordenadas do mouse em flutuadores; use
floor
para convertê-los em coordenadas de bloco inteiro.fonte