Question

Comment les jeux avec gravité gèrent-ils la relation entre des objets en mouvement tels que des joueurs, des monstres ou des objets et le sol? Le joueur est-il constamment "tombé dans" le sol et être rebondi?

Deux façons de réagir aux collisions que j'ai découvertes sont de ramener le joueur à son emplacement précédent avant la collision et de tester la nouvelle position avant de passer à une éventualité de collision, mais je ne vois pas comment l’un ou l’autre pourrait traiter d’une plate-forme qui monte et qui doit pouvoir soulever le joueur. Je regarde cela du point de vue de la conception de jeux en 2D, mais j'imagine que le même problème se produit dans la conception de jeux en 3D. Des allusions? Toutes les références que je devrais vérifier? Merci.

Était-ce utile?

La solution

Vous pouvez consulter la la FAQ Gravity de GameDev.net pour certains informations de base.

Etant donné que vous créez un jeu et non un modélisateur physique extrêmement précis, nous pouvons nous en sortir Intégrations Euler . Si votre besoin de précision augmente, la méthode d'intégration la plus répandue et la plus utilisée est un Runge-Kutta (RK4 ) intégration . Vous n'en aurez probablement pas besoin pour un jeu simple, mais ils sont certainement utilisés dans la simulation physique plus avancée et les jeux 3D. L'inconvénient de l'utilisation de RK4 est une complexité légèrement accrue et un peu plus lente. C’est très précis, mais pour l’instant, restons fidèles à Euler.

J'ai posé une question similaire, Comment est-ce que j'applique la gravité à mon jeu de balle bondissante " et j'ai obtenu plusieurs bonnes réponses. La première chose à faire est de choisir une constante de gravité arbitraire pour votre jeu. Dans mon application de balle rebondissante, j'utilise une constante de gravité par défaut de 2000px / s. Vous voudrez jouer avec cette constante de gravité pour obtenir l’effet souhaité pour votre jeu en particulier.

Ensuite, vous voulez vous assurer que vous restaurez votre jeu et mettez à jour vos objets de jeu indépendamment. Cela empêche vos objets du jeu de se déplacer très rapidement sur des ordinateurs rapides et de ralentir sur des ordinateurs lents. Vous souhaitez que la physique et la vitesse de déplacement de vos objets soient indépendantes de la vitesse de l'ordinateur. Physique du jeu: corrigez votre retard! .

Alors, comment faisons-nous cela? Vous gardez une trace du temps écoulé depuis le dernier appel de votre méthode Update. J'ai créé 2 threads, bien que ce ne soit pas directement nécessaire. J'ai un fil de mise à jour du jeu et un fil de rendu. Le fil de mise à jour contrôle la mise à jour des positions des objets du jeu. Le fil de mise à jour sait à quel moment il a été appelé, l'heure actuelle et à partir de là, calcule le temps écoulé depuis l'appel de la méthode de mise à jour.

Pour appliquer la gravité, nous allons simplement ajouter à la vitesse Y de notre objet notre constante de gravité multipliée par le temps écoulé.

private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;

public void updateGame()
{
    currentTime = System.currentTimeMillis();
    float elapsedSeconds = (currentTime - previousTime) / 1000f; 

    foreach(GameObject gameObject in gameObjects)
    {
        // Apply gravity to velocity vector
        gameObject.velocity.y += (gravityConstant * elapsedSeconds); 

        // Move objects x/y position based off it's velocity vector
        gameObject.position.x += (gameObject.velocity.x * elapsedSeconds); 
        gameObject.position.y += (gameObject.velocity.y * elapsedSeconds);

    }

    checkCollisions();

    previousTime = currentTime;
}

Cela déplacera tous vos objets en fonction de leur vecteur vitesse et leur appliquera la gravité en fonction de votre constante de gravité. Mieux encore, il le fait indépendamment de la vitesse de l'ordinateur!

Pour répondre à votre autre question, oui, les objets auront en permanence la " force " de la gravité sur leur vecteur y. Donc, il sera constamment en collision avec le sol. Cependant, une chose que vous voulez faire est d’utiliser un valeur Epsilon pour éventuellement ramener la vitesse de votre gameObject à zéro. Ensuite, lors de la détection des collisions dans le cadre de votre processus d’élagage, vous pouvez généralement ignorer la vérification de la collision entre un objet immobile (et non l'inverse!).

Ce que j'aime faire avec les collisions, c’est que dès que je trouve des objets qui s’entrechoquent (se pénètrent les uns dans les autres), je les écarte de leur distance de translation minimale (MTD) qui les sépare. Cette étape est essentielle sinon vous obtiendrez le bogue fréquemment rencontré dans les jeux d’objets "bloqué". ensemble se déplaçant avec agitation. Une fois qu'ils sont séparés, je calcule ma réponse à la collision.

En utilisant cette méthode, cela fonctionnera correctement dans le scénario décrit pour une plate-forme montante. La plate-forme continuera à monter, le gameObject se séparera en utilisant le MTD entre lui-même et la plate-forme et il augmentera naturellement avec i

Autres conseils

Une approche utilisée dans certains jeux consiste à tricher: vous devez avoir un état séparé pour marcher vs dans les airs. En marchant, le moteur de jeu peut déterminer l’inclinaison de la surface et, s’il n’est pas trop raide, déplacer le personnage dans la direction de la surface et lui donner le placement vertical approprié par rapport à la surface.

Pour ce qui est de la physique, je deviens un partisan de l'intégration de verlet, comme décrit dans Gamasutra. : Physique avancée des personnages . Cela simplifie les équations de mise à jour de la physique (vous n'avez pas à suivre la vitesse!) Et les collisions (vous n'avez pas à ajuster la vitesse!). Cela dit, il vous reste quelques nuances si vous avez besoin de précision.

L'un des manuels les plus complets sur ce sujet est Détection de collisions en temps réel par Christer Ericson . Il dispose également d'un blog compagnon . Mathématiques pour la programmation de jeux 3D et l'infographie de Eric Lengyel > est utile aussi.

Je ne suis pas spécifiquement un programmeur de jeux, mais voici ce que je comprends:

  • dans un monde idéal avec une "cadence infinie", vous détecteriez la collision exactement au moment où elle se produirait et utiliseriez un peu de physique standard pour modéliser les nouvelles vitesses et accélérations des corps à la suite de la collision ( consultez un manuel de mécanicien de lycée standard ou plusieurs ouvrages intitulés "Physics for Games Programers")
  • En réalité, comme vous avez une fréquence d'images fixe et que, par conséquent, les corps ne se déplacent qu'avec une certaine granularité, vous devez généralement ajouter une astuce supplémentaire, telle que calculer à l'avance le chemin relatif que les corps vont parcourir sur la prochaine image et voir. si l'un des chemins se croise
  • s’ils se croisent, le point d’intersection sera en réalité une estimation , mais légèrement inexacte, du point où les corps se seraient vraiment heurtés; vous avez alors le choix de ne pas vous intéresser et de prendre cette estimation comme point d'intersection et d'interpoler linéairement pour obtenir les vitesses au point de collision, ou d'effectuer un calcul plus précis maintenant que vous avez découvert qu'ils vont se croiser, pour obtenir le point / heure / vitesse de collision réels

Outre la modélisation des collisions, une bonne approche consiste également à modéliser les transferts d'énergie continus (ou de la quantité de mouvement, ou simplement de la vitesse, en fonction de la complexité de votre simulation). Lorsque votre joueur se trouve sur une plate-forme, stockez ces informations dans l'objet représentant la plate-forme et, chaque fois que la vélocité de l'objet est ajustée, vous pouvez directement appliquer cette modification au joueur ainsi lié ou à d'autres objets.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top