Bonjour, bonsoir. Même après beaucoup de recherches et d'essais, je me retrouve confronté à un problème :
Je crée un jeu depuis 2 mois mais j'ai toujours des problèmes au niveau des collisions... J'ai utilisé la technique AABB mais je suis bloqué au bord voire à l'intérieur du modèle en touchant un bord.
collision.x sert à "prévoir" la collision. S'il n'était pas là, il y aura une collision, le joueur déjà dans l'objet, donc c'est un peu inutile . Ce calcul est pour l'axe X, mais j'en fait un similaire pour les autres axes.
Par contre, je n'arrive pas à sauter des lignes dans mon code...
Sans même parler du code, je pense que tu tombes dans le piège des collisions :
"Que fait on quand on est coincé dans un mur ?" -> on revoir son code.
Car en effet, on ne doit pas être coincé dans un mur, jamais !
L'idée quand tu te déplaces, ce n'est pas de te déplacer puis voir si tu touches.
C'est de déplacer une copie, de voir si la copie touche, et si elle ne touche pas alors on valide le déplacement de l'original, sinon on ne touche pas à l'original.
Ainsi, on n'est jamais dans le mur. C'est ça qu'il faut revoir.
* note que dans certains jeux comme Megaman 2 sur Nes, ils avaient fait des algos d'éjection à droite dans les cas improbable ou on serait quand même dans le mur, et les speedrunner s'en servent pour skipper des parties entières de niveaux.
C'est de déplacer une copie, de voir si la copie touche, et si elle ne touche pas alors on valide le déplacement de l'original, sinon on ne touche pas à l'original.
C'est ça, collision.
Raynobrak a écrit:
C'est quoi translation?
width et height c'est la taille de quoi ?
Translation, c'est la position du joueur.
Width et height, c'est la taille de l'objet qui va entrer en collision ou non.
Deedolith a écrit:
Basiquement, pour chaque entité, tu définit une boite englobante.
La détection de collision vérifie juste si 2 boites s'entrecroisent.
Quand à faire du prédictif, tu dois d'abord calculer la prochaine position des entités, et ensuite faire le test de collision.
Comme Fvirtman l'a dit, j'ai crée une copie de la position. Grâce à width, height etdepth, je fabrique une boîte englobante qui change de taille selon la taille de l'objet. Enfaite, mon problème est que en touchant le bord d'un modèle (un cube, par exemple), je me retrouve bloqué et impossible de bouger.
TexturedModel est une classe qui regroupe le modèle et la texture de l'entité. model.size est un vec3 (j'utilise glm) représentant la taille du modèle.
Ton code détecte bien un chevauchement entre ta "camera après déplacement" et ton entité, et si chevauchement, annuler le déplacement de "camera", donc forcément, ça fait ce que tu décris.
Donc, si tu ne veux pas faire une simulation "physique" (cf. l’enchaînement de tâches indiquées dans mon précédent post), tu veux quoi comme comportement ???
Là, tu as implémenté le comportement "je reste figé à la position de départ" donc, où est la divergence ???
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Finalement, j'ai enfin trouvé une solution. Je me suis souvenu d'un programme que j'avais fait sur lequel les collisions étaient parfaites. J'ai repris son code et le voici :
Je ne suis pas convaincu que la fonction membre collide() soit une bonne idée. Une fonction libre sera plus appropriée a mon avis (plus générique, donc plus souple)
Je me souvient d'un tetris, le principe etait extremement simple: 1) Instanciation temporaire d'une piece à sa futur position. 2) Comparaison de la position des carrés de la piece avec ceux de l'aire de jeux (detection de collision). 3) S'il n'y a pas de collision, on effectue le mouvement. 4) S'il y a collision, on ne fait rien.
J'ai l'impression que tu as effectué le mouvement d'abord (puisque tu veux annuler), c'est l'inverse qu'il faut faire.
Heu, à part la prise en compte de la 3ème dimension, c'est quoi la différence ?
Finalement, tu as raison. Le bug est toujours présent mais j'ai trouvé une autre technique pour le résoudre. Je n'ai plus aucun problème de collision (après trois mois, quand même ) !
C'était simple, il fallait faire :
for (auto &entity : entities)
{
if (entity == this || entity->noHitbox)
continue;
const auto &texturedModel = entity->texturedModel;
const auto &model = texturedModel.model;
const auto &width = model.size.x * entity->scale + this->texturedModel.model.size.x * scale;
const auto &height = model.size.y * entity->scale + this->texturedModel.model.size.y * scale;
const auto &depth = model.size.z * entity->scale + this->texturedModel.model.size.z * scale;
AABB playerAabb = {translation.x + velocity.x, translation.y, translation.z, width, height, depth};
AABB entityAabb = {entity->translation.x, entity->translation.y, entity->translation.z, width, height, depth};
if (playerAabb.collide(entityAabb))
{
velocity.x *= -1;
break;
}
}
J'avais fait une erreur que je ne suis pas prêt de refaire.
Velocity, c'est le nouveau nom de collision.
- Edité par Anonyme 12 juin 2021 à 10:54:37
AABB bloqué sur les coins
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html