Comment puis-je facilement implémenter le swing dans un jeu de plateforme?

9

Je suis en train de développer un jeu dans lequel le joueur peut utiliser des cordes pour se balancer (tout comme ce que Spiderman ou Bionic Commando ont fait) et j'ai des problèmes pour implémenter ce comportement. Quelqu'un peut-il m'aider à faire cela, je veux dire des formules de physique et etc. Jusqu'à maintenant, j'ai trouvé 3 idées. L'un utilise le printemps, mais il consomme beaucoup de temps et parfois il est nerveux. Les deux autres tentent de calculer la prochaine étape (l'une via le calcul de l'énergie potentielle et l'autre via le calcul du couple) et les deux se bloquent presque chaque fois que l'acteur essaie de se balancer.

Voici le code que j'ai écrit pour calculer le couple:

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;
Ali1S232
la source
Pertinent (sur la fabrication d'une corde): Détection de collision de corde 2D
doppelgreener
@JonathanHobbs la réponse à cette question est exactement comment j'essaie de mettre en œuvre ma corde à une exception près, car la collision est indésirable dans mon cas, j'ai défini chaque partie de corde comme un capteur afin qu'elles puissent se déplacer librement sans se coincer les unes dans les autres.
Ali1S232
Qu'en est-il du simple pendule pour corde + quelques animations qui apparaissent cordes? Je ne crois pas que les vieux jeux comme Bionic Commando avaient autre chose que pendule.
user712092
@user cette idée de pendule devrait fonctionner correctement. mais dans mon cas, soit à cause du mouvement rapide du joueur ou de ma mauvaise mise en œuvre, cela n'a pas donné de bons résultats.
Ali1S232
@Gajet essaie de faire un dessin de débogage jusqu'à ce que vous compreniez bien? Cette ligne de pendule pourrait être réalisée sous la forme d'une boîte suffisamment mince dans Box2D pour obtenir des collisions (et peut-être l'exclure de la physique et se déplacer à la main?).
user712092

Réponses:

6

Si vous voulez un swing rigide, de sorte que la distance au point de rotation soit constante, il suffit de traiter le personnage comme un point sur un cercle centré au point de rotation. Donnez-lui une vitesse angulaire unidimensionnelle (le long du cercle). Pour chaque image, l'accélération angulaire doit être accelerationDueToGravity * cos(angleOfPlayerOnCircle)(avec 0 degrés pointant vers la droite).

Si vous voulez que la corde soit plus longue / plus courte, vous pouvez utiliser le schéma ci-dessus et varier simplement le rayon de chaque cadre.

BlueRaja - Danny Pflughoeft
la source
vous répondez était mon deuxième essai mais il se déplace avec beaucoup plus de vitesse que je devrais éditer ma question et ajouter mon code peut-être que vous pouvez repérer où est le problème.
Ali1S232
3

après de nombreuses tentatives, je suis allé avec box2d.

il y a généralement deux approches pour cette simulation ou du moins j'en ai trouvé 2:

  1. la première consiste à utiliser des formes de cercle et à les connecter à l'aide d'articulations distantes.
  2. et l'autre consiste à créer des rectangles pour la chaîne elle-même, puis à les attacher à l'aide de joints tournants

dans chaque senario, vous devez avoir un ancre (qui dans mon cas était une boîte statique). il vaut mieux que vous diminuiez le poids des pièces de corde (que vous utilisiez des formes de cercle ou des formes de rectangle), par exemple pour avoir une physique plus réaliste, je règle leur densité à 0,1 et pour la boîte connectée à l'extrémité de la corde, j'utilise la densité 10.

une autre chose que vous devez vous soucier de la façon dont votre segment de corde réagit les uns aux autres. Je voulais juste que ma corde bouge librement dans la scène, j'ai donc marqué tous les appareils de corde comme capteurs. vous pourriez avoir besoin d'une approche différente.

la prochaine chose dont vous devez vous soucier est le nombre d'itérations que vous passez à la mise à jour mondiale: pour un segment de corde bas (peut-être 8 au plus), il n'est pas nécessaire d'utiliser une valeur d'itération élevée, peut-être 10/10, ce que box2d lui-même a suggéré est suffisant, mais si vous augmentez le nombre de segments, par exemple, j'ai essayé 30 segments, avec un faible nombre d'itérations, votre corde semble augmenter sa longueur plus qu'elle ne devrait, donc vous avez peut-être besoin de 40 à 40 itérations pour résoudre ces situations.

après quelques tests, il semble que la boîte 2d est conçue pour les scènes avec des tailles d'objet de 0,1 m à 10 m et la taille maximale suggérée pour les grandes scènes est d'environ 50 mx 50 m. Donc, fondamentalement, vous devez réduire votre objet pour correspondre à ces paramètres. dans mon cas, j'ai d'abord essayé de passer les positions des pixels directement à box2d mais il semblait qu'il y avait des limites de vitesse empêchant le monde de bouger aussi vite qu'il le devrait, j'ai donc dû redimensionner ma scène environ 64 fois pour obtenir les meilleurs résultats. bien que je ne me sois pas testé, il y a des limites dans box2d qui vous empêchent d'utiliser des scènes plus grandes. par exemple, il existe une valeur définie dans le b2Setting.hfichier, #define b2_maxTranslation 2.0fvous pouvez modifier les paramètres de box2d mais cela ne semble pas recommandé.

Ali1S232
la source
pourquoi est-ce mal avec box2d pour me gagner un downvote ??
Ali1S232
Cela ne répond pas à la question. Écrivez au moins comment vous l' avez fait fonctionner avec Box2D.
bummzack
@bummzack: ok je vais ajouter ça à ma réponse
Ali1S232
Si vous acceptez cela comme votre réponse, votre question est viciée. La physique des cordes segmentées est très différente de ce que vous avez décrit.
AttackingHobo
@attackingHobo: la question était correcte à ce moment-là, mais quand j'ai transformé mon code en box2d, j'ai compris sans trop d'effort que je pouvais implémenter la physique des cordes segmentées. et ce n'est pas très différent, pensez à ma question comme un seul segment d'une corde segmentée. et presque toutes mes solutions étaient des moyens d'implémenter une corde de style cercle sans box2d.
Ali1S232
2

Avez-vous envisagé de ralentir la vitesse du mouvement de swing en fonction de la distance entre la corde et le fil à plomb (le centre)?

Randolf Richardson
la source
pour les 3 approches, la longueur de la corde est l'un des paramètres que j'ai utilisés pour calculer la vitesse de swing. Mais je ne peux pas garantir que je l'ai utilisé correctement. Je viens de faire des calculs physiques et d'appliquer leur version résolue au jeu.
Ali1S232
Plus vous vous éloignez du centre, plus le délai avant le prochain mouvement de la corde est long. Vous pouvez également multiplier la valeur ABSolute du retard par quelque chose comme 0,28 (vous devrez l'expérimenter).
Randolf Richardson
Je ne peux pas obtenir ce que vous essayez de dire, lorsque je calcule la prochaine étape, j'ai une valeur constante pour delta_time, et j'utilise tous les paramètres que j'ai (comme la vitesse précédente, la position précédente, la longueur de la corde, etc.) pour calculer nouvelle vitesse, puis ajoutez cette vitesse multipliée par delta_time à la dernière position pour générer une nouvelle position. si vous voulez dire autre chose, veuillez fournir tous les détails dans votre réponse.
Ali1S232
1

Lorsque le joueur est plus loin que la longueur de la corde, le joueur sera immédiatement repoussé avec une force égale à la distance qu'il a franchie. Cela devrait fonctionner sans se sentir élastique et devrait être intuitif pour le joueur. Vous devrez peut-être modifier votre physique pour obtenir les meilleurs résultats pour votre jeu.

Lorsque la corde est attachée. Enregistrez une maxLengthvaleur.

Chaque mise à jour, vérifiez distanceentre le playeret leattachPoint

Si le distanceest inférieur à la maxLengthmise à jour normalement, aucun effet de corde.

Si la distance est supérieure à la maxLength, trouvez le normaldu attachPointau au joueur. Obtenez la différence entre le distanceet le maxLength. Ajoutez à playerVelocity, normalmultiplié par la différence.

Pseudo code:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;
AttackingHobo
la source
le code que j'ai modifié dans votre réponse (désolé, mais je n'ai pas trouvé meilleur endroit pour l'ajouter) est-il celui que vous proposez?
Ali1S232
J'ai approuvé l'édition, et oui, je pense que ça devrait être ça. Bien que j'aie utilisé la physique de la corde avant et utilisé une manière beaucoup plus compliquée de faire la même chose, à cause de cela, je ne suis pas entièrement sûr que ce code fonctionnera correctement, mais je pense qu'il devrait, et même s'il ne le fait pas, il vous obtient 95 % du chemin.
AttackingHobo
après quelques essais, je suppose que je vais essayer box2d pour ce problème et par la façon dont vous devez changer ce code pour que vous ayez dx = player.x - attachpoint.xet dy = player.y - attachpoint.y.
Ali1S232
1

Si vous regardez http://www.cocos2d-iphone.org/archives/1112 il y a une implémentation d'une corde avec un corps rigide attaché à l'extrémité de la corde. Il utilise Box2D pour le moteur physique. Si vous regardez le code source, je suis sûr que vous pouvez l'implémenter dans n'importe quelle langue que vous aimez.

En outre, le lien ci-dessus vers la question de la corde est le mien et cette démo (lien fourni) ci-dessus a vraiment aidé.

Joey Green
la source