Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Game Development

Criando um jogo 2D isométrico e hexagonal no estilo 'Sokoban' com Unity

by
Difficulty:IntermediateLength:MediumLanguages:

Portuguese (Português) translation by Jonathan Ramos (you can also view the original English article)

Final product image
What You'll Be Creating

Neste tutorial, iremos converter um convencional jogo 2D de Sokoban para perspectivas isométricas e hexagonais. Se você é novo em jogos isométricos ou hexagonais, pode ser esmagador tentar cumprir os dois ao mesmo tempo. Nesse caso, eu recomendo fazer o isométrico primeiro e depois voltar numa fase posterior para a versão hexagonal.

Nós construiremos em cima do tutorial anterior de Unity: Jogo "Sokoban" 2D baseado em tilesets com Unity Por favor faça o primeiro tutorial, já que a maioria do código permanecerá intacta e todos os conceitos fundamentais permanecem os mesmos. Eu também vou interligar outros tutoriais explicando alguns dos conceitos subjacentes.

O aspecto mais importante na criação de versões isométricas ou hexagonais de uma versão 2D é descobrir o posicionamento dos elementos. Nós usaremos os métodos de conversão baseados em equações para converter entre os diferentes sistemas de coordenadas.

Este tutorial tem duas seções, uma para a versão isométrica e outra para a versão hexagonal.

1. Sokoban isométrico

Vamos mergulhar mesmo na versão isométrica, uma vez que você tenha passado pelo tutorial original. A imagem abaixo mostra como a versão isométrica ficaria, desde que usemos as mesmas informações de nível usadas no tutorial original.

the isometric version of the sokoban level

Perspectiva isométrica

Teoria isométrica, equação de conversão e implementação são explicados em vários tutoriais no Envato Tuts+. Uma explicação antiga baseada em Flash pode ser encontrada neste tutorial detalhado. Eu recomendaria este tutorial baseado em Phaser por ser mais recente.

Embora as linguagens de script usadas nesses tutoriais são  ActionScript 3 e JavaScript, respectivamente, a teoria é aplicável em todas as plataformas, independente das linguagens de programação. Basicamente resume-se a estas equações de conversão usadas para converter coordenadas cartesianas 2D para coordenadas isométricas ou vice-versa.

Usaremos a seguinte função da Unity para a conversão de coordenadas isométricas.

Alterações na arte

Usaremos as mesmas informações de nível para criar nossa matriz 2D, levelData, que responsável pela representação isométrica. A maioria do código também permanecerá o mesmo, exceto a parte relacionada a perspectiva isométrica.

A arte, no entanto, precisa de algumas mudanças no que diz respeito as pontos de pivô. Consulte a imagem abaixo e a explicação que segue.

isometric sprites and their offsets

O script IsometricSokoban usa sprites como heroSprite, ballSprite e blockSprite. A imagem mostra os novos pontos de pivô usados para estes sprites. Esta mudança dá a aparência de um jogo pseudo 3D que é o que almejamos com a perspectiva isométrica. O blockSprite é um novo sprite que adicionamos quando encontramos um invalidTile.

Isso vai me ajudar a explicar o aspecto mais importante dos jogos isométricos: a classificação de profundidade. Embora o sprite seja apenas um hexágono, estamos considerando isso como um cubo 3D, onde o pivô situa-se no meio da face inferior do cubo.

Alterações no código

Faça o download do código compartilhado através do repositório git antes de prosseguir. O método CreateLevel tem algumas alterações que lidam com a escala e o posicionamento das telhas e a adição do blockTile. A escala da tileSprite, é apenas uma imagem em forma de diamante que representa o nosso chão, que precisa ser alterado conforme está abaixo.

Isto reflete o fato de que uma tileset isométrica terá uma altura correspondente a metade da sua largura. O heroSprite e o ballSprite têm um tamanho de tileSize/2.

Para cada invalidTile encontrado, nós adicionamos um blockTile usando o código a seguir.

O hexágono precisa ser dimensionado de forma diferente para obter a aparência isométrica. Isto não é um problema quando a arte é tratada por artistas. Nós estamos aplicando um valor ligeiramente inferior de alfa para o blockSprite para que possamos ver através dele, o que nos permite ver a profundidade corretamente. Observe que adicionamos estas tilesets no dicionário occupants também, que serão usadas posteriormente para a classificação de profundidade.

O posicionamento das tilesets é feito usando o método GetScreenPointFromLevelIndices, que por sua vez, usa o método de conversão CartesianToIsometric explicado anteriormente. Os pontos do eixo Y aponta a  direção oposta para na Unity, o que precisa ser considerado ao posicionar o middleOffset no meio da tela.

No final do método CreateLevel, bem como no final do método TryMoveHero, chamamos o método DepthSort. Sortear a profundidade é o aspecto mais importante de uma implementação isométrica. Essencialmente, nós determinamos quais tilesets estão na frente de outros no nível. O método DepthSort é como mostrado abaixo.

A beleza de uma implementação baseada em matriz 2D é a classificação de profundidade correta, só precisamos atribuir sequencialmente maior profundidade enquanto classificamos a ordem da fase, usando sequenciais nos loops. Isso funciona para o nosso nível simples com apenas uma única camada de solo. Se tivéssemos vários níveis de solo em diferentes alturas, então a classificação de profundidade seria mais complicada.

Todo o resto permanece igual a implementação 2D explicada no tutorial anterior.

Nível completo

Você pode usar os mesmos controles de teclado para jogar. A única diferença é que o herói não se moverá verticalmente ou horizontalmente mas de forma isométrica. O nível terminado ficaria como na imagem abaixo.

Isometric version finished level

Confira como a classificação de profundidade é claramente visível com o nosso novo blockTiles.

Não foi difícil, não é? Eu convido você a mudar os dados no arquivo de texto para experimentar novos níveis. O próximo é a versão hexagonal, que é um pouco mais complicada, e eu aconselho a fazer uma pausa para jogar a versão isométrica antes de prosseguir.

2. Sokoban hexagonal

A versão hexagonal do Sokoban ficaria como na imagem abaixo.

hexagonal sokoban level

Perspectiva hexagonal

Estamos usando o alinhamento horizontal para a grade hexagonal para este tutorial. A teoria por trás da implementação hexagonal requer muita leitura adicional. Por favor veja esta série de tutoriais para uma compreensão básica. A teoria é implementada na classe auxiliar HexHelperHorizontal, que pode ser encontrado na pasta utils.

Conversão de coordenadas hexagonal

O script  HexagonalSokoban usa métodos convencionais da classe auxiliar para converter as coordenadas e outros recursos hexagonais. A classe auxiliar HexHelperHorizontal só funcionará com uma grade hexagonal alinhada horizontalmente. Ela inclui métodos para converter coordenadas entre sistemas cúbicos, deslocamento, e axial.

A coordenada de deslocamento é a mesma coordenada cartesiana 2D. Ele também inclui um método getNeighbors, que leva em uma coordenada axial e retorna um List<Vector2> com a coordenada todos os seis vizinhos da célula. A ordem da lista é no sentido horário, começando com a coordenada da célula que fica ao nordeste.

Alterações nos controles

Com uma grade hexagonal, temos seis direções de movimento ao invés de quatro, já que o hexágono possui seis lados, enquanto que um quadrado tem quatro. Então temos seis teclas no teclado para controlar o movimento do nosso herói, como mostrado na imagem abaixo.

Hexagonal keyboard control keys

As teclas são organizadas no mesmo layout como uma grade hexagonal, se você considerar a tecla S como a célula do meio, com todas as teclas vizinhas. Isso ajuda a reduzir a confusão dos controles. Com as alterações o código ficou como está abaixo.

Não há alteração na arte, e não há nenhuma mudança necessária no pivô.

Outras mudanças no código

Vou explicar as alterações de código no que diz respeito ao tutorial de Sokoban 2D original e não a versão isométrica acima. Por favor, consulte o código fonte para este tutorial. O fato mais interessante é que quase todo o código permanece o mesmo. O método CreateLevel tem apenas uma mudança, que é o cálculo do middleOffset.

Uma mudança importante é, obviamente, a maneira que as coordenadas da tela encontram-se no método GetScreenPointFromLevelIndices.

Aqui usamos a classe auxiliar para primeiro converter a coordenada axial e encontrar a coordenada de tela correspondente. Por favor, dê uma olhada no uso da variável sideLength para a segunda conversão. O valor do comprimento de um lado do tileset do hexágono, que novamente é igual a metade da distância entre as duas extremidades do hexágono. Por isso:

Outra mudança é o método GetNextPositionAlong, que é usado pelo método TryMoveHero para localizar a próxima célula em uma determinada direção. Este método é completamente alterado para acomodar o layout totalmente novo da nossa grade.

Usando a classe auxiliar, podemos facilmente voltar as coordenadas do vizinho na direção determinada.

Todo o resto permanece igual a implementação original 2D. Não foi difícil, não é? Porém, compreender como chegamos às equações de conversão, seguindo o tutorial hexagonal, que é o cerne de todo o processo, não é fácil. Se você jogar e completar o nível, você obterá o resultado abaixo.

hexagonal sokoban finished level

Conclusão

O elemento principal em ambas as conversões foi a conversões de coordenadas. A versão isométrica envolve alterações adicionais na arte com seu ponto de pivô, bem como a necessidade de classificação e profundidade.

Acredito que você já se deu conta de como é fácil criar jogos baseados em grade usando apenas matrizes bidimensionais e uma abordagem baseada em tilesets. Existem possibilidades ilimitadas e jogos que você pode criar com esta nova compreensão.

Se você entendeu todos os conceitos que discutimos até agora, convido você a mudar o método de controle para touch e adicionar alguns algoritmos para encontrar o caminho correto. Boa sorte.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.