Comment gérer la physique des plates-formes mobiles dans un jeu de plateforme?

8

Donc, après quelques heures de recherche sur Internet, je n'ai pas encore trouvé de réponse agréable sur la façon de gérer les plates-formes mobiles dans un jeu de plate-forme 2D. J'ai donc décidé de faire un prototype simple où vous interagissez avec 2 plates-formes différentes, une qui se déplace verticalement et une horizontalement. J'aimerais de l'aide pour disséquer et voir ce qui ne fonctionne pas et comment les corriger. J'ai soumis le fichier .fla + le fichier .as ci-dessous, accompagné d'un lien vers le .swf jouable.

Le but est de faire interagir le héros avec les plates-formes comme s'il s'agissait d'objets solides sur lesquels il pouvait se tenir debout, poussé à côté, sauter dessus / dessous, etc.

Les problèmes avec mon prototype sont les suivants:

  • Lorsque vous vous tenez sur la plate-forme se déplaçant horizontalement, sans bouger (sans toucher à aucune touche), le héros se déplace avec la plate-forme, mais avec un léger retard faisant reculer un peu le héros.

  • Lorsque vous vous tenez sur la plate-forme se déplaçant horizontalement et que vous sautez, vous vous déplacez avec la plate-forme en plein air (certains jeux préfèrent l'avoir comme ça, mais cela ne semble pas naturel et n'est pas souhaité ici). Ce qui pourrait être dû au fait que le héros conserve la vitesse sur l'axe X à partir de la plate-forme.

  • Lorsque vous sautez vers le bas sur la plate-forme se déplaçant verticalement, tandis que la plate-forme se déplace vers le bas, vous vous enfoncez à l'intérieur pendant une brève seconde. Le héros pénètre comme si la collision était inexistante pendant un moment.

  • Lorsque vous sautez sur une plate-forme se déplaçant verticalement, la vélocité sur l'axe Y est conservée, donc lorsque vous quittez la plate-forme, vous tombez à une vitesse plus élevée. Avec la vitesse de la vitesse retenue, + la gravité qui est ajoutée (c'est principalement parce que je ne peux pas trouver un moyen de réinitialiser la vitesse sur l'axe Y à 0 lorsque vous atterrissez sur la plate-forme, sans que le joueur ne gèle en plein air).

Je suis un programmeur débutant, donc je suis sûr qu'il existe de MEILLEURES façons de le faire, et j'aimerais tous les entendre. Toutes les idées sur la façon d'améliorer le code ou d'autres méthodes dans lesquelles vous pouvez implémenter des plates-formes mobiles dans un jeu basé sur Tile sont les bienvenues. En fin de compte, j'essaie de trouver un moyen solide de gérer les plates-formes mobiles dans les plates-formes 2D.

SWF jouable: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.html (Déplacer avec les touches fléchées, sauter avec la touche X, exécuter avec la touche Z)

Fichier AS de code source: http://dl.dropbox.com/u/28271061/Platformerhowto.as

Fichier sourceFLA: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.fla

Si vous préférez simplement lire le code via Pastie en ligne: http://pastie.org/2266764

Enfant
la source
Pertinent (doublon improbable): Comment gérer les plateformes mobiles dans un jeu de plateforme? .
doppelgreener
J'ai lu ce fil, mais comme je n'utilise aucun nœud, il me semble que cela n'a pas résolu le problème. Le jeu que je construis est basé sur des tuiles, mais les plates-formes mobiles seront implémentées comme ci-dessus (déplacement libre). L'utilisation de nœuds nécessiterait une réécriture de mon moteur dans son ensemble, sur laquelle j'ai déjà passé beaucoup de temps. Je suppose que j'espérais que quelqu'un examinerait le code et proposerait une solution similaire à ce qui est proposé, ou trouverait une amélioration du code.
Kid
Vous voulez être en utilisant des nœuds une fois que vous mettre en œuvre cette solution aux plates - formes mobiles, même si c'est le seul endroit où vous les utilisez. Cela résoudrait votre problème de glissement.
doppelgreener
2
"(certains jeux préfèrent l'avoir comme ça, mais cela ne semble pas naturel et n'est pas souhaité ici)" Comment ne "se sent-il pas naturel"? Google Inertia and Momentum ...
Riki
1
@Felheart, naturel en termes de jeu, pas un vrai monde physique. Si vous jouez à Super Mario Bros ou à l'un des jeux de plateforme classiques, vous remarquerez qu'ils ne conservent PAS l'élan tout en sautant sur des plateformes en mouvement. Il perturbe la sensation de se tenir debout et d'interagir avec une plate-forme mobile.
Kid

Réponses:

17

Séparons votre problème en ses problèmes distincts ...

Un mot sur la qualité du code

Votre code dispose actuellement de vos plates-formes contrôlant directement la vitesse de votre joueur et même la constante de gravité du monde . C'est hacky, et c'est procédural quand il devrait être orienté objet. Une fois que vous aurez commencé à étendre ce jeu, les choses vont mal tourner rapidement .

Vous devez refactoriser votre code. Implémentez une classe de joueur, une classe de plate-forme et une classe de plancher. Séparez leurs préoccupations: demandez au joueur d'interpréter les commandes du clavier et de contrôler comment il court et saute, et demandez aux plates-formes de modifier son élan si nécessaire (en ajoutant leur propre vitesse à la vitesse déjà déterminée du joueur, si nécessaire).

Demandez à votre joueur de déterminer où il se trouve par rapport à un objet de type sol (les plates-formes et les sols auraient tous deux un BodyType = BodyTypes.Floor, ou quelque chose) et de déterminer par lui-même où il se trouve par rapport à l'objet, comment il devrait réagir et s'il tombe ou par terre.

Cela peut mériter un sujet distinct car c'est un problème tout à fait distinct de tout ce que vous avez évoqué. Cependant, vous allez devoir le faire à un moment donné.

Inertie horizontale / verticale à la sortie d'une plateforme

Pour résoudre vos problèmes de vitesse verticale et horizontale, notez deux choses:

  • Concernant la vitesse horizontale: Votre code ne met la vitesse horizontale à 0 que lorsque le joueur touche le sol (sur la ligne Pastie 200) ou une plateforme.
  • Concernant la vitesse verticale: Votre joueur a une accélération de chute constante. Lorsqu'il quitte la plate-forme verticale, cette accélération en baisse ne fait que s'ajouter à son mouvement déjà descendant.

Votre joueur souffre simplement d' inertie : son élan est maintenu jusqu'à ce que quelque chose l'arrête.

Solution: Les deux problèmes seraient résolus par la solution de jSepia à Comment gérer les plateformes mobiles dans un jeu de plateforme? car cela séparerait complètement le processus de mouvement du joueur de la façon dont les plates-formes le déplacent. Vous ne tomberiez tout simplement pas plus vite en marchant sur une plate-forme verticale et ne conserveriez pas votre élan horizontal en sautant sur une plate-forme horizontale, car les plates-formes n'affecteront plus les vx et vy de votre joueur .

Remarque: Vous pouvez avoir des difficultés à implémenter la solution de jSepia avant que votre code soit refactorisé.

Glissement latéral sur la plate-forme horizontale

Votre joueur n'est pas déplacé horizontalement aussi rapidement que la plate-forme se déplace. Ce n'est pas évident pour moi pourquoi. Ce problème serait également probablement résolu en implémentant la solution de jSepia et en refactorisant correctement votre code (ce dernier rendrait simplement la cause évidente).

Détection de collision: chevauchement avec la plate-forme verticale

Voir Pastie ligne 381: à chaque étape, il remet le vy du joueur à 0 tant que le joueur entre en collision avec le dessous de la plate-forme verticale. Dans l'étape suivante, vy est augmenté par l'accélération de la gravité, puis le joueur est déplacé (puis il est remis à 0).

Cela signifie que tant que votre joueur entre en collision avec le bas de la plate-forme, il descend à une vitesse constante (la constante de gravité). La plate-forme verticale est plus rapide que ça donc elle le chevauche. Si la plate-forme verticale se déplaçait sur une plus longue distance, elle glisserait à travers lui jusqu'à ce que le joueur soit enregistré comme se tenant sur la plate-forme.

Solution: ne remettez pas le vy du joueur à 0. Réglez simplement le vy du joueur sur la vitesse verticale de la plateforme ( si la plateforme se déplace vers le bas ). Votre joueur s'éloignera alors de la plate-forme verticale au moins aussi vite que la plate-forme et accélérera loin de celle-ci.

doppelgreener
la source
Excellent! Tout d'abord merci pour la solution au saut et à la pénétration de la plateforme verticale (ça marche!). Et deuxièmement, vous avez raison, le code est terrible dans cet état. Bien que ce ne soit pas le jeu en soi, il s'agit d'un prototype rapide conçu pour expérimenter et mieux comprendre les plates-formes mobiles. Néanmoins, si je veux traduire cela dans le code des jeux, je devrais garder un code plus structuré et orienté objet. Cela facilitera le transfert. Maintenant, en ce qui concerne la solution jSpeias, je pense avoir le concept d'arborescence de nœuds, c'est juste que je ne sais pas comment l'implémenter correctement.
Kid
Ma première pensée est de créer des valeurs booléennes qui décriraient l'état des joueurs, telles que: "onFloor", "onPlatform", "onGround", "tomber", "sauter", etc. Et puis exécuter une instruction if dans le événement enterFrame qui vérifie l'état actuel et modifie les propriétés des joueurs en conséquence (?) Par exemple: if (Hero.onPlatform == true) {Player.x = platform.x (par rapport aux joueurs global x);}. Quelque chose de cette manière.
Kid
J'y travaille pendant que nous parlons, mais en même temps, je sépare le code en différentes classes comme vous l'avez suggéré, ce qui est également un peu déroutant (communiquer entre les classes de plate-forme / collision / joueur est époustouflant).
Kid
@Kid: Playerpossède une méthode GetPositionet des variables internes parent(pour son nœud parent) et position(pour sa position par rapport à son parent). Player.GetPosition()retourne position + parent.GetPosition(). Son parent fait la même chose jusqu'à ce que vous atteigniez la racine de l'arbre - le nœud mondial. Lorsque votre joueur se déplace, vous ne traitez qu'avec la positionvariable privée . Votre joueur est dessiné sur l'écran de jeu selon GetPosition()la valeur de. Je vais vous laisser comprendre comment la transition entre les nœuds. ;)
doppelgreener
Bien sûr, avoir une classe de joueurs sachant comment modifier sa propre vitesse ne confirme pas la séparation des préoccupations
Andy Ray