Saut impulsif

12

Il y a une chose qui m'a intrigué, et c'est comment mettre en œuvre un saut «faux-impulsé» dans un jeu de plateforme. Si vous ne savez pas de quoi je parle, pensez aux sauts de Mario, Kirby et Citation de Cave Story. Qu'est-ce qu'ils ont en commun? Eh bien, la hauteur de votre saut est déterminée par la durée pendant laquelle vous maintenez le bouton de saut enfoncé.

Sachant que les `` impulsions '' de ces personnages ne sont pas construites avant leur saut, comme dans la physique réelle, mais plutôt dans les airs - c'est-à-dire que vous pouvez très bien lever votre doigt à mi-hauteur de la hauteur maximale et il s'arrêtera, même si avec désaccélération entre elle et le point final; c'est pourquoi vous pouvez simplement taper pour un saut et le maintenir pour un saut en longueur -, je suis fasciné par la façon dont ils conservent leurs trajectoires sous forme d'arcs.

Mon implémentation actuelle fonctionne comme suit:

entrez la description de l'image ici

Lorsque le bouton de saut est enfoncé, la gravité est désactivée et la coordonnée Y de l'avatar est décrémentée de la valeur constante de la gravité. Par exemple, si les choses tombent à Z unités par tick, cela augmentera Z unités par tick.

Une fois que le bouton est relâché ou que la limite est atteinte, l'avatar désaccélère dans une quantité qui le ferait couvrir X unités jusqu'à ce que sa vitesse atteigne 0; une fois qu'il le fait, il accélère jusqu'à ce que sa vitesse corresponde à la gravité - fidèle à l'exemple, je pourrais dire qu'il accélère de 0 à Z unités / tick tout en couvrant X unités.

Cette implémentation, cependant, rend les sauts trop diagonaux, et à moins que la vitesse de l'avatar ne soit plus rapide que la gravité, ce qui le rendrait beaucoup trop rapide dans mon projet actuel (il se déplace à environ 4 pixels par tick et la gravité est de 10 pixels par tick, à un framerate de 40FPS), il le rend également plus vertical qu'horizontal. Ceux qui connaissent les jeux de plateforme remarqueront que le saut en arc du personnage leur permet presque toujours de sauter plus loin même s'ils ne sont pas aussi rapides que la gravité du jeu, et quand il ne le fait pas, s'il n'est pas bien joué, il se révélera être très contre-intuitif. Je le sais car je pourrais attester que ma mise en œuvre est très ennuyeuse.

entrez la description de l'image ici

Quelqu'un a-t-il déjà essayé des mécanismes similaires et peut-être même réussi? J'aimerais savoir ce qui se cache derrière ce genre de saut de plateforme. Si vous n'avez jamais eu d'expérience avec cela auparavant et que vous voulez l'essayer, alors s'il vous plaît, n'essayez pas de corriger ou d'améliorer ma mise en œuvre expliquée, sauf si j'étais sur la bonne voie - essayez de composer votre solution à partir de rayure. Je me fiche que vous utilisiez la gravité, la physique ou autre, tant que cela montre comment fonctionnent ces pseudo-impulsions, il fait le travail.

De plus, j'aimerais que sa présentation évite un codage spécifique à la langue; comme, en nous partageant un exemple C ++, ou Delphi ... Autant j'utilise le framework XNA pour mon projet et cela ne me dérangerait pas des trucs C #, je n'ai pas beaucoup de patience pour lire le code des autres, et je suis certains développeurs de jeux d'autres langues seraient intéressés par ce que nous réalisons ici, alors ne vous occupez pas de vous en tenir au pseudo-code.

Merci d'avance.

Mutoh
la source
3
Avez-vous regardé la question suivante et ses réponses? gamedev.stackexchange.com/questions/29617/…
bummzack
@bummzack C'est également très clair.
Mutoh
1
doublon possible de la manipulation de Jump et de la gravité Bien qu'il n'ait pas de jolies images, c'est la même question.
MichaelHouse

Réponses:

8

Je pense que votre principal problème réside ici:

Lorsque le bouton de saut est enfoncé, la gravité est désactivée et la coordonnée Y de l'avatar est décrémentée de la valeur constante de la gravité. Par exemple, si les choses tombent à Z unités par tick, cela augmentera Z unités par tick.

La gravité ne fonctionne pas comme ça. Google a "accéléré uniformément le mouvement" pour les détails, mais en termes simples, comme l'a dit un autre collègue, la gravité est une accélération, pas une vitesse.

Pour le dire simplement, alors que la vitesse est le taux constant de changement de position dans le temps, l'accélération est le taux constant de changement de vitesse dans le temps.

Donc, votre premier ordre du jour serait de changer votre algorithme de chute pour inclure l'accélération, pas seulement la vitesse. Au lieu de:

pos_y = pos_y + (velocity_y * time_difference)

il faudrait faire quelque chose comme

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

De cette façon, tout tombera dans une parabole, qui est le mouvement physiquement correct.

Maintenant, pour implémenter un saut simple (nous arriverons à votre question exacte juste après cela), vous définissez simplement velocity_yla valeur souhaitée. Tant que le signe acceleration_yet votre désir velocity_ysont différents, votre objet sautera correctement (en d'autres termes, vous ne "désactivez pas la gravité". Vous le maintenez, et vous réglez simplement la vitesse de l'objet à une valeur prédéfinie).

Vous remarquerez que plus velocity_yvous commencez à sauter, plus le saut sera élevé. Donc, pour mettre en œuvre l'effet souhaité, vous ajoutez une sorte d'accélération au saut (en termes physiques, cela signifie ajouter une force. Pensez à ajouter une petite fusée à l'objet).

Pour ce faire, vous faites la même chose qu'avant, mais maintenant l'accélération et la vitesse doivent avoir le même signe. Vous faites cela pendant que le bouton est enfoncé:

pos_y = pos_y + (velocity_y * time_difference) + (force_y * (time_difference ^ 2) / 2)
velocity_y = velocity_y + (force_y * time_difference)
Pyjama Panda
la source
4

La solution n'est pas de retarder la décélération. Lorsque vous lancez une balle en l'air, elle ne se déplace pas à une vitesse constante jusqu'à ce qu'elle atteigne sa hauteur maximale, mais décélère à partir du moment de l'impulsion.

La gravité n'est pas une vitesse, mais une accélération. Donc, si un joueur a une vitesse ascendante de 20 unités et que la gravité est de -10 unités, au tick suivant, la vitesse ascendante serait de 10 unités, la suivante, 0 unité, etc.

La raison pour laquelle vos sauts semblent si diagonaux est que la vitesse de montée et de descente de votre joueur est constante. Donc, si vous tracez littéralement une ligne en suivant le chemin du joueur, vous verrez une ligne avec la pente, positive ou négative, de votre valeur de gravité sur le changement de la position x.

Pour que votre joueur contrôle la hauteur de votre saut, votre joueur doit recevoir une certaine vitesse initiale lors de l'impulsion, la gravité doit être désactivée et une valeur de gravité spéciale (inférieure à la gravité normale) doit être appliquée à la vitesse du joueur. Une fois que le bouton de saut est relâché ou que la vitesse du joueur atteint 0, la gravité normale doit être appliquée.

De cette façon, le joueur verra une belle courbe pendant son saut, qu'il décélère par gravité régulière ou non.

SAHornickel
la source
2

La petite histoire est: vous allez avoir quelque part une section non parabolique dans votre arc de saut.

J'ai essayé quelques approches lors de la mise en œuvre du saut:

  • Montée constante: Cela semble être, en fait, ce que vous essayiez: avoir la vitesse verticale positive fixée jusqu'à ce que le bouton soit relâché, point auquel la gravité normale entre en jeu. L'arc est diagonal à la montée, mais normal à l'automne - cela semble normalement OK, et (plus important encore) se sent bien, car il est assez facile de bien juger de la hauteur du saut.

  • Montée arrêtée: c'est là que vous commencez le personnage à monter à la parabole de hauteur maximale, en appliquant une impulsion initiale. Ensuite, lorsque le bouton est relâché, vous réglez la vitesse verticale sur zéro (ou une petite vitesse ascendante). Cela signifie que vos plus grands sauts sont une parabole garantie, et les petits sauts donnent plus l'impression que vous faites un grand saut puis ralentissez.

  • Impulsion initiale variable: c'est celle pour laquelle j'ai finalement opté: appuyer sur le saut appliquerait une impulsion initiale ascendante suffisante pour un saut, puis continuerait d'appliquer une accélération ascendante (beaucoup plus grande que la gravité) sur une courte période - la fenêtre de saut - jusqu'à ce que le bouton a été relâché. Une fois la fenêtre de saut fermée, le mouvement serait alors parabolique et la période d'impulsion initiale variable était suffisamment courte pour ne pas paraître étrange, mais assez longue pour donner à un joueur expérimenté suffisamment de latitude pour contrôler la hauteur de saut. L'inconvénient était qu'il n'était pas aussi facile de juger de la hauteur de saut, car la fenêtre était beaucoup plus petite et n'avait pas la correspondance du moment de déclenchement à la hauteur. Comme cela arrivait la plupart du temps, vous vouliez un tap ou un saut complet de toute façon, ce n'était donc pas un problème.

Essayez-les et voyez ce qui vous convient le mieux.

Tom Johnson
la source