Movimento de RPG de cima para baixo com correção?

27

Eu espero que todos nós tenhamos jogado Zelda: A Link to the Past, por favor, me corrija se eu estiver errado, mas quero imitar esse tipo de movimento de personagem 2D de cima para baixo com um toque de correção. Isso já foi feito em outros jogos, mas acho que essa referência seria a mais fácil de se relacionar. Mais especificamente, o tipo de movimento e correção de que estou falando é:

  • Movimento flutuante não restrito ao movimento baseado em ladrilhos, como Pokemon e outros jogos em que um toque no bloco de movimento move você um quadrado nessa direção cardinal. Esse movimento flutuante deve ser capaz de obter movimento diagonal.
  • Se você estiver caminhando para o oeste e chegar a um muro diagonal da maneira Nordeste / Sudoeste, você será corrigido para um movimento Sudoeste, mesmo se continuar segurando a esquerda (Oeste) no controlador. Isso deve funcionar para as duas diagonais, corrigindo nas duas direções.
  • Se você estiver a alguns pixels de caminhar diretamente para uma porta ou corredor, será corrigido para caminhar pelo corredor ou pelo corredor, ou seja, esbarrar no canto faz com que você seja empurrado para o corredor / porta.

Procurei maneiras eficientes de conseguir isso e não tive sorte. Para deixar claro, estou falando do movimento do personagem humano, não do movimento de um NPC. Seus recursos estão disponíveis nesse tipo de movimento? Equações ou algoritmos explicados em um wiki ou algo assim?

Estou usando o XNA Framework, existe algo para ajudar nisso?

Corey Ogburn
fonte

Respostas:

23

Bem, o primeiro ponto é fácil. Você simplesmente armazena e manipula a posição do personagem nas coordenadas do mundo ou do pixel, em vez das coordenadas baseadas em blocos. Se você estava tendo um problema com isso, pode ser devido a uma escolha confusa de representação para o seu mundo e espaço em mosaico; portanto, talvez você deva postar mais detalhes sobre isso / fazer uma pergunta específica e separada.

Para o segundo ponto, a abordagem mais direta seria pegar o vetor de movimento (normalizado) do jogador e adicioná-lo ao vetor normal da parede e depois renormalizar. O sinal dos componentes do vetor resultante indicará como a parede se relaciona com o movimento do jogador, enquanto o próprio vetor indica em qual direção o jogador pode agora se mover.

Quanto ao terceiro ponto, supondo que você tenha retângulos de colisão para a parede e o jogador, você poderá determinar quanto do retângulo de colisão do jogador entra em contato com o retângulo de colisão da parede. Se, por exemplo, o jogador está se movendo para a direita e bate em uma parede vertical, você compara as extensões do eixo Y dos retângulos de colisão - se a extensão do jogador exceder a extensão da parede em algum limite, digamos 75% da Y do jogador extensão do eixo, então você "engana" o jogador em direção à porta.

Fiz uma série de suposições aqui na aparência do seu modelo de objeto em seu código e em quais técnicas você escolheu - em grande parte devido à generalidade de sua pergunta. Tentei sugerir abordagens simples (embora talvez não ótimas) pelo mesmo motivo. Se você puder fornecer informações mais específicas, nesta pergunta ou em uma nova, posso tentar fornecer mais detalhes ou uma ideia melhor.

Josh
fonte
Sim, flutuar o personagem não foi um problema. Apenas garantir que as pessoas vissem que era um requisito. Você me deu a resposta principal: ladrilhos com vetores! Não acredito que não pensei nisso. Obrigado.
Corey Ogburn
No zelda , havia apenas um ângulo em que eles poderiam estar, portanto não havia necessidade de calcular vetores normais, era apenas um caso especial no código.
BlueRaja - Danny Pflughoeft
Não entendo como você atribui um vetor a um bloco. Como seria isso?
teste
Presumivelmente, um bloco já possui dados como seu gráfico, passíveis ou não de serem passados, etc. esse é apenas outro campo. Por exemplo: struct Tile {vector2 normal; ...} O valor do normal deve vir com os dados que definem o bloco
Josh
@JoshPetrie Revistando isso. Um bloco que pode ser colidido em várias direções não precisa ter vários vetores? Não sei se entendi como um bloco poderia ter um único vetor.
teste
4

Como resposta possível para o segundo ponto, é projetar o vetor de movimento do jogador ao longo do vetor da parede usando um produto pontual (ab * normalizado (b)). Você então recebe um vetor que diz a que distância mover o jogador na direção da parede e, se você mover o jogador por esse vetor, obtém um 'slide' ao longo da parede. Funcionou bem para mim em um projeto de jogo anterior.

James
fonte
3

Ótima resposta para Josh, mas vou adicionar algumas sugestões: - Para obter mais informações sobre deslizar contra paredes, confira minha pergunta - a partir desta resposta, consegui fazê-la funcionar muito bem. - Se não me engano, ao subir a tela, o Link facilitará o alinhamento com o quadrado da grade horizontal mais próximo. Dessa forma, quando você chega às portas, é mais provável que esteja alinhado corretamente (pode estar errado). - Para facilitar a passagem pelas portas, verifique se a caixa de colisão do seu personagem é bem menor que a largura da porta.

Iain
fonte
Ou a caixa de colisão talvez seja um círculo?
Oskar Duveborn
2

Para corrigir a entrada de portas, você pode tornar o objeto de colisão para a porta um pouco maior que a imagem da porta. Isso resultaria no mesmo efeito proposto por Josh, mas sem ter que calcular a proximidade com o retângulo de colisão da parede.

RavensKrag
fonte