Como rolar telhas hexagonais?

7

Parece que não consigo encontrar uma resposta para essa pergunta. Eu tenho um mapa de blocos hexadecimais. Desejo implementar a rolagem.

Código atualmente:

drawTilemap = function() {
    actualX = Math.floor(viewportX / hexWidth);
    actualY = Math.floor(viewportY / hexHeight);
    offsetX = -(viewportX - (actualX * hexWidth));
    offsetY = -(viewportY - (actualY * hexHeight));

    for(i = 0; i < (10); i++)
    {
        for(j = 0; j < 10; j++)
        {
            if(i % 2 == 0) {
                x = (hexOffsetX * i) + offsetX;
                y = j * sourceHeight;
            } else {
                x = (hexOffsetX * i) + offsetX;
                y = hexOffsetY + (j * sourceHeight);
            }

            var tileselected = mapone[actualX + i][j];

            drawTile(x, y, tileselected);
        }
    }
}

O código que escrevi até agora apenas lida com o movimento X. Ainda não funciona como deveria. Se você olhar para o meu exemplo no jsfiddle.net abaixo, verá que ao mover para a direita, quando chegar ao próximo bloco hexagonal, há um problema com a posição X e os cálculos que ocorreram.

Parece que está faltando um pouco de matemática. Infelizmente, não consegui encontrar um exemplo que inclua rolagem ainda.

http://jsfiddle.net/hd87E/1/

Verifique se não há barra de rolagem horizontal e tente mover para a direita usando a seta -> direita no teclado. Você verá o problema ao chegar ao final do primeiro bloco.

Desculpas pelo código horrível, estou aprendendo!

Felicidades

Chris Evans
fonte
Eu consegui encontrar isso. xnaresources.com/default.asp?page=Tutorial:TileEngineSeries:3 Infelizmente, funciona corretamente a tela, mas usa coordenadas incorretas. Se você olhar a figura, não acho que isso funcione com a matemática hexadecimal.
22611 Chris Evans
Ajustei o código ainda mais e é mais limpo e fácil de entender no que interessa. Você pode encontrar um exemplo completo aqui: jsfiddle.net/wg45T/2/embedded/result e o código aqui: jsfiddle.net/wg45T/2 Você encontrará o scroll agora e recria o mapa etc ok. O problema agora é que ele não mantém a posição do bloco que vem quando o bloco antigo é removido. Tente rolar para a direita para ver.
Chris Evans
Encontrei a resposta, mas ainda não posso postar. Carregará quando o prazo terminar.
22611 Chris Evans

Respostas:

1

Seja hexadecimal ou não, sugiro manter suas variáveis ​​de localização (x, y) apontando para o mundo do jogo e converter para / das coordenadas da tela somente quando necessário. Ao converter da tela para o mundo, você adiciona (cameraX, cameraY) e depois divide por (tileStepX, tileStepY). Ao converter do mundo para a tela, você multiplica por (tileStepX, tileStepY) e subtrai (cameraX, cameraY). Observe que há uma pequena complicação com hexágonos, que você lida com columnOffset.

Aqui está uma versão mais simples do seu código, com x, y, firstX, firstY nas coordenadas mundiais:

drawTilemap = function() {
    // Convert top left of the screen (0, 0) to world coordinates
    firstX = Math.floor(cameraX / 45);
    firstY = Math.floor(cameraY / 50);

    for( x = firstX; x < firstX + 10; x++ )  // world coordinates
    {
        var columnOffset = oddRowOffset * (x % 2);

        for( y = firstY; y < firstY + 10; y++ )  // world coordinates
        {
            // Make sure this world coordinate is part of the map
            if ( 0 <= y && y < mapone.length && 0 <= x && x < mapone[y].length )
            {
                // Convert world coordinates to screen coordinates
                drawTile((x * tileStepX) - cameraX,
                         (y * tileStepY + columnOffset) - cameraY,
                         mapone[y][x]);
            }
        }
    }
}
amitp
fonte
Que simplificação excelente! Cheers :)
Chris Evans
0

Encontrei a resposta! Veja aqui: http://jsfiddle.net/ck6Vq/1/embedded/result/

Não tem certeza se alguém pode apresentar algo mais organizado do que o código abaixo?

drawTilemap = function() {
    firstX = Math.floor(cameraX / 45);
    offsetX = cameraX % 45;
    if(firstX > 0) {
        firstX = firstX - 1;
        offsetX = offsetX + 45;
    }

    console.log(offsetX);

    firstY = Math.floor(cameraY / 50);
    offsetY = cameraY % 50;

    for(x = 0; x < 10; x++)
    {
        var rowOffset = 0;
        var columnOffset = 0;

        if((firstX + x) % 2 == 1)
        {
            columnOffset = oddRowOffset;
        }

        for(y = 0; y < 10; y++)
        {
            drawTile((x * tileStepX) - offsetX,
                     (y * tileStepY) - offsetY + columnOffset,
                     mapone[y+firstY][x+firstX]);
        }
    }
}
Chris Evans
fonte