Salto impulsivo

12

Há uma coisa que me intriga, e é como implementar um salto 'impulsivo' em um jogo de plataformas. Se você não sabe do que estou falando, pense nos saltos de Mario, Kirby e Quote from Cave Story. O que eles têm em comum? Bem, a altura do seu salto é determinada por quanto tempo você mantém o botão de salto pressionado.

Sabendo que os "impulsos" desses personagens são construídos não antes do salto, como na física real, mas no ar - ou seja, você pode muito bem levantar o dedo no meio da altura máxima e ele irá parar, mesmo que com desaceleração entre ele e o ponto final; é por isso que você pode simplesmente dar um pulo e segurá-lo por um longo salto -, estou impressionado com a forma como eles mantêm suas trajetórias como arcos.

Minha implementação atual funciona da seguinte maneira:

insira a descrição da imagem aqui

Enquanto o botão de salto é pressionado, a gravidade é desativada e a coordenada Y do avatar é diminuída pelo valor constante da gravidade. Por exemplo, se as coisas caírem em Z unidades por tick, aumentará Z unidades por tick.

Quando o botão é liberado ou o limite é atingido, o avatar desacelera em uma quantidade que o faria cobrir X unidades até que sua velocidade atinja 0; quando isso acontece, ele acelera até sua velocidade corresponder à gravidade - seguindo o exemplo, eu poderia dizer que acelera de 0 a Z unidades / tick enquanto ainda cobre X unidades.

Essa implementação, no entanto, faz saltos muito na diagonal e, a menos que a velocidade do avatar seja mais rápida que a gravidade, o que tornaria muito rápido no meu projeto atual (ele se move a cerca de 4 pixels por tick e a gravidade é de 10 pixels por tick, em uma taxa de quadros de 40FPS), também a torna mais vertical do que horizontal. Aqueles familiarizados com os jogadores de plataforma notariam que o arco do personagem quase sempre os permite pular mais, mesmo que não sejam tão rápidos quanto a gravidade do jogo, e quando isso não acontecer, se não for jogado corretamente, provará ser muito contra-intuitivo. Sei disso porque pude atestar que minha implementação é muito irritante.

insira a descrição da imagem aqui

Alguém já tentou mecânica semelhante e talvez até tenha conseguido? Eu gostaria de saber o que está por trás desse tipo de salto de plataforma. Se você nunca teve alguma experiência com isso anteriormente e quer experimentar, tente não corrigir ou aprimorar minha implementação explicada, a menos que eu esteja no caminho certo - tente criar sua solução a partir de coçar, arranhão. Não me importo se você usa a gravidade, a física ou outros enfeites, desde que mostre como esses pseudo-impulsos funcionam, ele faz o trabalho.

Além disso, gostaria que sua apresentação evitasse uma codificação específica de idioma; tipo, compartilhando um exemplo em C ++, ou Delphi ... Por mais que eu esteja usando a estrutura XNA para o meu projeto e não me importe com coisas em C #, não tenho muita paciência para ler o código de outros, e estou certos desenvolvedores de jogos de outros idiomas estariam interessados ​​no que alcançamos aqui, então não se importe em aderir ao pseudo-código.

Obrigado de antemão.

Mutoh
fonte
3
Você deu uma olhada na seguinte pergunta e em suas respostas? gamedev.stackexchange.com/questions/29617/…
bummzack
@bummzack Isso também é muito claro.
Mutoh
1
possível duplicação do manuseio e gravidade do salto Embora ele não tenha imagens bonitas, é a mesma pergunta.
MichaelHouse

Respostas:

8

Eu acho que seu principal problema está aqui:

Enquanto o botão de salto é pressionado, a gravidade é desativada e a coordenada Y do avatar é diminuída pelo valor constante da gravidade. Por exemplo, se as coisas caírem em Z unidades por tick, aumentará Z unidades por tick.

A gravidade não funciona assim. O Google "movimento uniformemente acelerado" para os detalhes, mas em termos simples, como outro colega disse, a gravidade é uma aceleração, não uma velocidade.

Simplificando, enquanto a velocidade é a taxa constante de mudança de posição ao longo do tempo, a aceleração é a taxa constante de mudança de velocidade ao longo do tempo.

Portanto, sua primeira ordem de negócios seria alterar seu algoritmo decrescente para incluir aceleração, não apenas velocidade. Ao invés de:

pos_y = pos_y + (velocity_y * time_difference)

você teria que fazer algo como

pos_y = pos_y + (velocity_y * time_difference) + (gravity_y * (time_difference ^ 2) / 2)
velocity_y = velocity_y + (acceleration_y * time_difference)

Dessa forma, tudo cairá em uma parábola, que é o movimento fisicamente correto.

Agora, para implementar o salto simples (chegaremos à sua pergunta exata logo após isso), basta definir velocity_yo valor desejado. Contanto que o sinal acceleration_ye o desejado velocity_ysejam diferentes, seu objeto saltará corretamente (em outros termos, você não "desativa a gravidade". Você o mantém ligado e simplesmente define a velocidade do objeto para algum valor predefinido).

Você notará que quanto maior velocity_yfor quando você começar a pular, maior será o salto. Portanto, para implementar o efeito desejado, você adiciona algum tipo de aceleração ao salto (em termos físicos, isso significa adicionar uma força. Pense em adicionar um pequeno foguete ao objeto).

Para fazer isso, você faz o mesmo que antes, mas agora a aceleração e a velocidade devem ter o mesmo sinal. Você faz isso enquanto o botão é pressionado:

pos_y = pos_y + (velocity_y * time_difference) + (force_y * (time_difference ^ 2) / 2)
velocity_y = velocity_y + (force_y * time_difference)
Panda Pajama
fonte
4

A solução é não atrasar a desaceleração. Quando você joga uma bola no ar, ela não se move a uma velocidade constante até atingir sua altura máxima, mas desacelera a partir do momento do impulso.

Gravidade não é uma velocidade, mas uma aceleração. Portanto, se um jogador tiver uma velocidade acima de 20 unidades e a gravidade for -10 unidades, no próximo tick, a velocidade acima será de 10 unidades, no próximo, 0 unidades, etc.

A razão pela qual seus saltos parecem tão diagonais é porque a velocidade do seu jogador para cima e para baixo é constante. Portanto, se você literalmente desenhar uma linha seguindo o caminho do jogador, verá uma linha com a inclinação, positiva ou negativa, do seu valor de gravidade sobre a mudança na posição x.

Para o seu jogador controlar a altura do seu salto, ele deve receber uma velocidade inicial por impulso, a gravidade deve ser desligada e um valor especial de gravidade (menor que a gravidade regular) deve ser aplicado à velocidade do jogador. Quando o botão de salto for solto ou a velocidade do jogador atingir 0, a gravidade normal deve ser aplicada.

Dessa forma, o jogador verá uma boa curva durante o salto, desacelerando pela gravidade regular ou não.

SAHornickel
fonte
2

O conto é: você terá uma seção não parabólica em seu arco de salto em algum lugar.

Eu tentei algumas abordagens ao implementar o salto:

  • Escalada constante: isso parece ser o que você estava tentando: manter a velocidade vertical positiva fixa até o botão ser liberado, momento em que a gravidade normal entra em ação. O arco é diagonal na subida, mas normal na queda - isso normalmente parece bom e (mais importante) parece bom, pois é muito fácil julgar bem a altura do salto.

  • Subida presa: é aqui que você inicia o personagem subindo na parábola da altura máxima, aplicando um impulso inicial. Então, quando o botão é solto, você define a velocidade vertical para zero (ou uma pequena velocidade para cima). Isso significa que seus maiores saltos são uma parábola garantida, e saltos menores parecem mais como se você estivesse fazendo um grande salto e depois diminuindo a velocidade.

  • Impulso inicial variável: Esse foi o motivo pelo qual acabei optando: pressionar o salto aplicaria um impulso inicial ascendente suficiente para um salto e continuaria aplicando a aceleração ascendente (muito maior que a gravidade) por um curto período - a janela de salto - até o botão foi liberado. Uma vez fechada a janela do salto, o movimento seria parabólico e o período de impulso inicial variável era curto o suficiente para não parecer estranho, mas era longo o suficiente para dar a um jogador experiente espaço suficiente para controlar a altura do salto. A desvantagem foi que não foi tão fácil julgar a altura do salto, pois a janela era muito menor e não tinha a correspondência entre o momento do lançamento e a altura. Como aconteceu na maioria das vezes, você queria uma torneira ou um salto total, de modo que não era esse o problema.

Experimente e veja qual é a melhor.

Tom Johnson
fonte