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:
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.
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.
fonte
Respostas:
Eu acho que seu principal problema está aqui:
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:
você teria que fazer algo como
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_y
o valor desejado. Contanto que o sinalacceleration_y
e o desejadovelocity_y
sejam 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_y
for 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:
fonte
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.
fonte
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.
fonte