Saut de hauteur variable dans les scrollers latéraux

10

Comment puis-je faire sauter le joueur plus haut si la touche de saut est maintenue enfoncée plus longtemps? Je suis actuellement en train de réduire la gravité tant que la touche est maintenue et que le joueur saute, mais cela semble étrange.

John Stimac
la source
peut-être juste par une certaine modification de la réduction de la gravité, vous obtenez une meilleure action de saut.
Ali1S232
@Gajet C'est plutôt maladroit et cela semble une façon étrange de le faire.
The Communist Duck
Hmm vous dites que la réduction de la gravité ne signifie pas que vous utilisez un moteur physique. Est-ce le cas? Utilisez-vous des impulsions pour sauter?
Jonathan Connell
Il n'y a pas de moteur physique, et je n'utilise pas d'impulsions
John Stimac
Dans ce cas, comment tombez-vous joueur? Traduisez-vous simplement sa position selon un mouvement * saut * vecteur de gravité?
Jonathan Connell

Réponses:

9

Vous devez d'abord décider à quoi vous voulez que le saut ressemble.

Dans la vraie vie, la hauteur de saut est décidée au moment où vous quittez le sol. Vous ne pouvez pas continuer à sauter plus haut pendant que vous êtes déjà dans les airs.

Donc, si vous pouvez contrôler votre hauteur de saut pendant que vous êtes déjà dans les airs, vous obtiendrez une sorte d'effet de type "jet-pack".

Je crois me souvenir d'un sidecroller qui avait deux hauteurs de saut différentes, je pense que c'était l'un des jeux de super mario. Le saut le plus élevé s'est produit lorsque vous avez maintenu le bouton de saut enfoncé, et le saut était alors en fait un saut en deux parties, commençant par le saut régulier initial, suivi d'une seconde impulsion qui vous a amené plus haut.

Alors, à quoi voulez-vous que votre saut ressemble? Quel type de contrôle voulez-vous que le joueur ait sur le saut?

Je commencerais par ceci:

Laissez la gravité tranquille (c'est-à-dire ne la changez jamais). Lorsqu'un joueur appuie sur le bouton de saut, appliquez la force de saut tant que le joueur appuie sur le bouton de saut (jusqu'à une certaine limite de temps). Ensuite, lorsque le joueur relâche le bouton de saut, il ne peut plus appliquer de force de saut (c'est-à-dire qu'il ne peut pas recommencer un saut) jusqu'à ce qu'il touche le sol en premier, moment auquel les sauts sont réactivés.

Olhovsky
la source
J'ai essayé ça, et j'obtiens l'effet jetpack. Je me demandais s'il y avait un moyen d'éviter cela.
John Stimac
1
Peut-être pas le jeu que vous avez en tête, mais dans Super Mario 2, vous avez sauté plus haut en esquivant un peu avant de sauter. (Ce qui a un certain sens intuitif, puisque vous ne sautez pas très loin si vous essayez de le faire directement en position debout.)
Darien
3
Jcubed: Au lieu d'ajouter de la force à la vitesse, essayez d'ajouter la force directement à la position. Ensuite, le joueur se déplacera linéairement vers le haut, au lieu d'accélérer.
Olhovsky
@Jcubed: lorsque vous jouez à des jeux comme super meat boy, qui, je pense, ont le même effet de saut que vous le souhaitez, il semble que tant que vous maintenez le bouton de saut enfoncé, une force est appliquée au personnage, elle est opposée à la gravité et plus petite que celle-ci, et la le repos est comme ce qu'a dit alhovsky. si je devais implémenter quelque chose comme ça, je commencerais avec quelque chose comme 60% -80% de gravité comme force de saut.
Ali1S232
1
Je le fais tout le temps, gardez juste le temps pendant lequel vous réglez la vitesse de saut vers le haut en maintenant le bouton assez court pour que ce ne soit pas un effet de jet pack notable - alors ce sera comme Super Mario assez facilement, avec un peu de magie réglages de nombre. Ne réduisez pas la "force", continuez simplement à réinitialiser la vitesse à la vitesse de saut maximale jusqu'à ce que le jumpHigherTime expire ou que le joueur relâche le bouton ... aussi, je sens que les super-garçons de viande sautent pour être imprécis et ennuyeux, comme n'importe quelle plate-forme sautant qui ne repose que sur un moteur physique; p
Oskar Duveborn
7

J'ai vu des gens faire ça:

  1. Créez une variable (je l'appellerai jumpTime) (nombre / double / flottant). Lorsque la touche de saut est enfoncée, définissez-la jumpTimesur un certain nombre (c'est-à-dire que 0.5ce sera le nombre de secondes que le maintien de la touche de saut aura affectée).

  2. Ensuite, pour chaque étape, réglez la vitesse sur jumpTimemultipliée par un autre nombre et diminuez jumpTimede delta(la différence de temps entre chaque étape).

  3. Répétez cela jusqu'à ce qu'il jumpTimeatteigne zéro ou en dessous, ou lorsque le joueur relâche la touche de saut. Après cela, utilisez la physique normale (appliquez une accélération négative constante jusqu'à ce que le joueur atteigne le sol).

Vous devrez peut-être utiliser des essais et erreurs (ou «devinettes logiques») pour trouver des valeurs appropriées pour ces «certains nombres», sauf si vous savez comment le faire.


MISE À JOUR: J'ai trouvé l'astuce qui rend le saut un peu plus réaliste (car il est à l'origine lent à monter mais ensuite à descendre rapidement). Infinite Mario utilise également la ligne suivante (293 de Character.js de la version JavaScript) ... this.Ya *= 0.85;C'est tout simplement comme un "air drag", et limite / ralentit la vitesse du personnage en plein vol. Donc, à chaque image, multipliez la vitesse y (vitesse verticale) par un nombre inférieur à un afin qu'elle ralentisse en retombant (et donc que monter et descendre pendant un saut sera similaire et plus réaliste). Je sais, je suis mal à expliquer ...

Lorsque le personnage saute en utilisant la méthode que j'ai décrite à l'origine ci-dessus, il "monte" plus vite puis "retombe vers le bas". La traînée, cependant, ralentit la vitesse verticale. Puisque nous avons réglé la vitesse verticale pour qu'elle soit proportionnelle à jumpTimechaque image, cette traînée n'a pas beaucoup d'effet sur la première moitié du saut. Cependant, dans la moitié suivante (retombant vers le bas), la vitesse verticale n'est pas définie à chaque image, mais simplement ajoutée par un autre nombre (dans ce cas, c'est la constante gravitationnelle). Par conséquent, la traînée prend effet dans la chute, et comme elle diminue la vitesse (dans n'importe quelle direction), elle ralentit la chute, la rendant similaire à la première moitié.

Il existe cependant d'autres moyens de résoudre ce problème, comme diminuer l'effet de la gravité sur le personnage à mesure qu'il tombe. Cependant, nous devons trouver combien nous devons réduire la gravité.


Étude de cas: Infinite Mario

Voici ce que j'ai trouvé (à partir de la ligne 206 de Mario.java par 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;
    }

La version javascript est essentiellement la même https://github.com/robertkleffner/mariohtml5/blob/master/code/character.js

Ceci est similaire à la suggestion d'Olhovsky, mais dans ce cas, la force sera proportionnelle au temps écoulé après que le joueur a appuyé sur la touche de saut.

Ma version 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;

Cependant, certaines valeurs pour les constantes (par exemple "gravityConstant" et "jumpConstant") donneront cependant un saut irréaliste. Mais parfois, les jeux ne doivent pas être réalistes! ( mise à jour voir la section mise à jour ci-dessus)

Cette question a déjà plus d'un an, mais j'espère que cela vous aidera!

ErnWong
la source
2

Comme l'a dit Olhovsky, la hauteur de saut est décidée au moment où vous quittez le sol, pas après.

Si vous voulez vraiment éviter l'effet jetpack, je ne vois que deux façons: une combinaison de touches pour sauter plus haut, ou changer fondamentalement le fonctionnement de la touche de saut:

Au lieu de faire sauter le joueur dès que la touche est enfoncée, retardez le saut jusqu'à ce que la touche soit relâchée . Donc, fondamentalement, la durée de la pression sur la touche contrôle la quantité de tension du ressort dans les jambes du joueur, puis relâchée.

Bien sûr, cela modifie fondamentalement les mécanismes de jeu et peut ne pas être familier au joueur. Mais l'effet pourrait être très intéressant et pourrait bien valoir la méconnaissance.

Konrad Rudolph
la source
2
Je pense que je me souviens avoir joué à un jeu de plateforme avec exactement ce mécanisme - ne quittez pas le sol avant d'avoir "chargé" le saut. Avec de jolies animations (comme des nuages ​​de poussière qui poussent aux pieds du personnage), cela peut être fait pour être intuitif.
Jari Komppa
2

J'ai trouvé une autre solution dans la réponse de David Gouveia à la question " Comment faire sauter un personnage? "

Résumé:

Son idée était de définir une vitesse lorsque le joueur appuie sur le bouton de saut. Dans chaque image, il calcule uniquement la gravité. Cependant, lorsque le joueur relâche le bouton, il définit la vitesse sur une valeur plus petite si la vitesse est supérieure à celle-ci. La vitesse est seulement décrémentée à chaque image par la gravité.

Je ne devrais pas voler sa réponse, alors allez-y et lisez son message. Sa solution se trouve dans la section " Saut de hauteur variable ".

Donc, vraiment, les gens ont trouvé de nombreuses façons de résoudre ce problème ...

ErnWong
la source