Altura variável saltando em scrollers laterais

10

Como posso fazer o jogador pular mais alto se a tecla de pular for mantida pressionada por mais tempo? Atualmente, estou apenas reduzindo a gravidade enquanto a tecla estiver pressionada e o jogador estiver pulando, mas isso parece estranho.

John Stimac
fonte
talvez apenas por alguma modificação no quanto você reduz a gravidade, obtenha uma ação de salto melhor.
Jun1
@ Gajet Isso é bastante desajeitado e parece uma maneira estranha de fazê-lo.
O pato comunista
Hummm, você está dizendo que reduzir a gravidade não implica que você esteja usando um mecanismo de física. É esse o caso? Você está usando impulsos para pular?
Jonathan Connell
Não há mecanismo de física, e eu não estou usando Impulsos
John Stimac
Nesse caso, como você cai no jogador? Você acabou de traduzir sua posição de acordo com um vetor de movimento * salto * gravidade?
Jonathan Connell

Respostas:

9

Primeiro, você precisa decidir como será o salto.

Na vida real, a altura do salto é decidida no momento em que você sai do chão. Você não pode continuar pulando mais alto enquanto já está no ar.

Portanto, se você pode controlar a altura do seu salto enquanto já está no ar, obterá algum tipo de efeito semelhante ao "jet-pack".

Parece que me lembro de um side-scroller que tinha duas alturas de salto diferentes, acho que foi um dos jogos do super mario. O salto mais alto ocorreu quando você segurou o botão de salto, e o salto foi na verdade um salto de duas partes, começando com o salto regular inicial, seguido de um segundo impulso que o levou mais alto.

Então, como você quer que seu salto seja? Que tipo de controle você quer que o jogador tenha sobre o salto?

O que eu começaria é o seguinte:

Deixe a gravidade em paz (ou seja, nunca mude). Quando um jogador pressiona o botão de salto, aplique a força de salto enquanto o jogador estiver pressionando o botão de salto (até um certo limite de tempo). Então, quando o jogador solta o botão de pular, ele não pode aplicar nenhuma força de pulo novamente (ou seja, ele não pode iniciar um pulo novamente) até que ele toque o chão primeiro, quando os saltos serão reativados.

Olhovsky
fonte
Eu tentei isso e recebo o efeito jetpack. Fiquei me perguntando se havia alguma maneira de evitar isso.
John Stimac
1
Talvez não seja o jogo que você tem em mente, mas em Super Mario 2 você saltou mais alto, esquivando-se um pouco antes de pular. (Que faz uma certa quantidade de sentido intuitivo, desde que você não saltar muito longe se você tentar fazê-lo directamente a partir de uma posição de pé.)
Darien
3
Jcubed: Em vez de adicionar força à velocidade, tente adicionar a força diretamente à posição. Então o jogador se moverá linearmente para cima, em vez de acelerar.
precisa saber é o seguinte
@Jcubed: ao jogar alguns jogos como super meat boy, que eu acho que tem o mesmo efeito de salto que você deseja, parece que, enquanto você pressiona o botão de salto, uma força é aplicada ao personagem, é oposta à gravidade e menor que ele. resto é como o que Alhovsky disse. se eu implementasse algo assim, começaria com algo entre 60% e 80% de gravidade como força de salto.
Jun1
1
Eu faço isso o tempo todo, apenas mantenha o tempo durante o qual você define a velocidade de salto para cima mantendo pressionado o botão por tempo suficiente para que não seja um efeito perceptível do jet pack - então será como Super Mario com muita facilidade, com um pouco de magia número de ajustes. Não diminua a "força", continue redefinindo a velocidade para a velocidade máxima até que o jumpHigherTime expire ou o jogador solte o botão ... além disso, sinto super garotos pulando de carne sendo imprecisos e irritantes, como qualquer plataforma saltando que só conta com um motor de física; p
Oskar Duveborn
7

Eu já vi algumas pessoas fazendo isso:

  1. Crie uma variável (eu chamo jumpTime) de número (double / float). Quando a tecla de salto é pressionada, defina jumpTimepara algum número (ou seja, 0.5este será o número de segundos que a pressão da tecla de salto terá efeito).

  2. Em seguida, para cada etapa, a velocidade definida para jumpTimemultiplicado por algum outro número, e diminuir jumpTimepor delta(a diferença de tempo entre cada passo).

  3. Repita isso até jumpTimechegar a zero ou abaixo, ou quando o jogador soltar a tecla de pular. Depois que isso acontecer, use a física normal (aplique uma aceleração negativa constante até que o jogador alcance o chão).

Pode ser necessário usar tentativa e erro (ou "suposição lógica") para encontrar valores adequados para esses "alguns números", a menos que você saiba como fazê-lo.


ATUALIZAÇÃO: Encontrei o truque que torna o salto um pouco mais realista (já que originalmente é lento, mas rápido). Mario infinito também usa a seguinte linha (versão 293 do Character.js da versão JavaScript) ... this.Ya *= 0.85;Isso é simplesmente como "arrastar o ar" e limita / diminui a velocidade do personagem quando está no ar. Assim, todo quadro, multiplique a velocidade y (velocidade vertical) por um número menor que um, para que diminua a velocidade ao cair novamente (e, portanto, tanto para cima quanto para baixo durante um salto será semelhante e mais realista). Eu sei, sou péssima em explicar ...

Quando o personagem pula usando o método que eu descrevi acima, ele "sobe" mais rápido do que "cai para baixo". O arrasto, no entanto, diminui a velocidade vertical. Como definimos a velocidade vertical como proporcional a jumpTimetodos os quadros, esse arrasto não afeta muito a primeira metade do salto. No entanto, na metade seguinte (voltando para baixo), a velocidade vertical não é definida em todos os quadros, mas simplesmente adicionada por outro número (nesse caso, é a constante gravitacional). Portanto, o arrasto entra em vigor na queda e, como diminui a velocidade (em qualquer direção), diminui a velocidade da queda, tornando-a semelhante à primeira metade.

Existem outras maneiras de resolver esse problema, como diminuir o efeito da gravidade no personagem quando ele cai. No entanto, precisamos descobrir quanto devemos reduzir a gravidade.


Estudo de caso: Mario infinito

Foi o que eu encontrei (da linha 206 do Mario.java de Markus Persson (Notch)):

    if (keys[KEY_JUMP] || (jumpTime < 0 && !onGround && !sliding))
    {
        if (jumpTime < 0)
        {
            xa = xJumpSpeed;
            ya = -jumpTime * yJumpSpeed;
            jumpTime++;
        }
        else if (onGround && mayJump)
        {
            world.sound.play(Art.samples[Art.SAMPLE_MARIO_JUMP], this, 1, 1, 1);
            xJumpSpeed = 0;
            yJumpSpeed = -1.9f;
            jumpTime = 7;
            ya = jumpTime * yJumpSpeed;
            onGround = false;
            sliding = false;
        }
        else if (sliding && mayJump)
        {
            world.sound.play(Art.samples[Art.SAMPLE_MARIO_JUMP], this, 1, 1, 1);
            xJumpSpeed = -facing * 6.0f;
            yJumpSpeed = -2.0f;
            jumpTime = -6;
            xa = xJumpSpeed;
            ya = -jumpTime * yJumpSpeed;
            onGround = false;
            sliding = false;

            facing = -facing;
        }
        else if (jumpTime > 0)
        {
            xa += xJumpSpeed;
            ya = jumpTime * yJumpSpeed;
            jumpTime--;
        }
    }
    else
    {
        jumpTime = 0;
    }

A versão javascript é basicamente a mesma https://github.com/robertkleffner/mariohtml5/blob/master/code/character.js

Isso é semelhante à sugestão de Olhovsky, mas neste caso a força será proporcional à quantidade de tempo decorrido após o jogador pressionar a tecla de pular.

Minha versão javascript:

    if ( onGround && jump && !jumped ) {
        jumpTime = maxJumpTime;
        onGround = false;
        jumped = true;
        this.vel.y = jumpTime * jumpConstant;
        A = true;
    } else if ( !onGround && jump && jumpTime > 0 && !released ) {
        jumpTime -= evt.delta;
        this.vel.y = jumpTime * jumpConstant;
        B = true;
    } else if ( !onGround && ( !jump || jumpTime <= 0 ) ) {
        this.vel.y -= gravityConstant * evt.delta;
        jumpTime = 0
        released = true;
    } if ( this.pos.y < 0 && !A && !B ) {
        onGround = true;
        released = false;
        this.pos.y = 0;
        this.vel.y = 0;
    }
    if ( !jump && onGround ) jumped = false;

No entanto, alguns valores para as constantes (por exemplo, "gravityConstant" e "jumpConstant") darão um salto irrealista. Mas às vezes os jogos não precisam ser realistas! ( atualização, consulte a seção de atualização acima)

Esta pergunta já tem mais de um ano, mas espero que ajude!

ErnWong
fonte
2

Como Olhovsky disse, a altura do salto é decidida no momento em que você sai do chão, não depois disso.

Se você realmente deseja evitar o efeito do jetpack, vejo apenas duas maneiras: uma combinação de teclas para pular mais alto ou alterar fundamentalmente a maneira como a tecla de pular funciona:

Em vez de fazer o jogador pular assim que a tecla for pressionada, adie o salto até que a tecla seja liberada . Então, basicamente, a duração do pressionamento de tecla controla quanta tensão de mola nas pernas do jogador é construída e liberada posteriormente.

Obviamente, isso altera fundamentalmente a mecânica do jogo e pode não ser familiar para o jogador. Mas o efeito pode ser bastante interessante e pode valer a pena o desconhecimento.

Konrad Rudolph
fonte
2
Acho que me lembro de jogar algum jogo de plataforma exatamente com esse mecânico - não saia do chão até que você "carregue" o salto. Com algumas animações bonitas (como nuvem de poeira crescendo aos pés do personagem), isso pode ser feito para parecer intuitivo.
Jari Komppa
2

Encontrei outra solução na resposta de David Gouveia à pergunta " Como fazer um personagem pular? "

Resumo:

Sua idéia era definir uma velocidade quando o jogador pressionasse o botão de pular. Em cada quadro, apenas calcula a gravidade. No entanto, quando o jogador solta o botão, ele define a velocidade para um valor menor se a velocidade for maior que ela. A velocidade é apenas decrementada em cada quadro pela gravidade.

Eu não devo roubar a resposta dele, então vá em frente e leia o post dele. Sua solução está na seção " Salto de altura variável ".

Então, na verdade, as pessoas criaram várias maneiras diferentes de resolver esse problema ...

ErnWong
fonte