Encontrei uma abordagem simples e alternativa que usa a mesma lógica que um tabuleiro de xadrez regular. Ele cria um efeito de encaixe na grade com pontos no centro de cada bloco e em todo vértice (criando uma grade mais apertada e ignorando pontos alternados).
Essa abordagem funciona bem para jogos como Catan, onde os jogadores interagem com blocos e vértices, mas não é adequada para jogos nos quais os jogadores interagem apenas com blocos, pois retorna qual ponto central ou vértice as coordenadas estão mais próximas, em vez de qual bloco hexagonal o coordenadas estão dentro.
A geometria
Se você colocar pontos em uma grade com colunas que têm um quarto da largura de um bloco e linhas com metade da altura de um bloco, você obtém este padrão:
Se você modificar o código para pular cada segundo ponto em um padrão quadriculado (pular if column % 2 + row % 2 == 1
), você terminará com este padrão:
Implementação
Com essa geometria em mente, você pode criar uma matriz 2D (como faria com uma grade quadrada), armazenando as x, y
coordenadas de cada ponto da grade (no primeiro diagrama) - algo como isto:
points = []
for x in numberOfColumns
points.push([])
for y in numberOfRows
points[x].push({x: x * widthOfColumn, y: y * heightOfRow})
Nota: Como normal, ao criar uma grade em torno dos pontos (em vez de colocar pontos nos próprios pontos), é necessário compensar a origem (subtraindo metade da largura de uma coluna x
e metade da altura de uma linha y
).
Agora que você points
inicializou sua matriz 2D ( ), pode encontrar o ponto mais próximo do mouse da mesma forma que faria em uma grade quadrada, apenas tendo que ignorar todos os outros pontos para produzir o padrão no segundo diagrama:
column, row = floor(mouse.x / columnWidth), floor(mouse.y / rowHeight)
point = null if column % 2 + row % 2 != 1 else points[column][row]
Isso funcionará, mas as coordenadas estão sendo arredondadas para o ponto mais próximo (ou nenhum ponto) com base no retângulo invisível em que o ponteiro está. Você realmente deseja uma zona circular em torno do ponto (para que o intervalo de snap seja igual em todas as direções). Agora que você sabe qual ponto verificar, pode facilmente encontrar a distância (usando o Teorema de Pitágoras). O círculo implícito ainda teria que caber dentro do retângulo delimitador original, limitando seu diâmetro máximo à largura de uma coluna (quarto da largura de um ladrilho), mas ainda é grande o suficiente para funcionar bem na prática.