je fais un petit jeu de plateforme en SDL, et j'en arrive aux collisions.
J'ai fait pas mal de recherche, et je me suis décidé à utiliser des boîtes de collisions pour gérer les collisions, mais dans tous les tutos et exemples que j'ai trouvé, on ne parle que d'une collision entre deux objets bien défini : c'est toujours "si cet objet entre entre en collision avec celui ci", et je voudrais plutôt "si cet objet entre en collision....tout court", puis faire des tests pour voir d'où vient la collision
Pourquoi ? Parce que dans un jeu de plateforme, il n'y aura pas juste une plateforme, mais plusieurs.
J'ai pensé à créer un tableau à deux dimensions qui serait comme ça :
la fonction qui gère les collisions de mon personnage parcourrait ce tableau, mais parcourir tout le niveau à chaque instant, ça m'a l'air un peu neuneu comme solution (je vais néanmoins faire comme ça pour commencer et je modifierai une autre fois si quelqu'un me donne une solution plus judicieuse)
Je me suis mal exprimé, mon problème, plus clairement, c'est que je ne vois pas comment faire pour ne pas avoir à faire des tests de collision avec le personnage et tous les éléments du décor à chaque instant. C'est quand même pas possible qu'on soit obligé de vérifier s'il y collision avec un ennemi qui n'est même pas dans la fenêtre actuelle ?
1) A chaque temps, chaque objet vérifie qu'il est pas en collision avec chaque autre objet. C'est facile à implémenter mais peu efficace si le nombre d'objets devient grand (>100).
2) La position de chaque objet est stockée dans une std::map avec comme clé la position de l'objet. A chaque déplacement, on vérifie que la clé de la map n'existe pas avant d'effectuer le déplacement. Le cas échéant, on gère la collision. Plus difficile à coder, mais plus efficace.
Il existe encore d'autres méthode si jamais ça ne te suffit pas.
Salut,
Effectivement, il y'a une solution qui correspond à ce que tu cheche
Il te suffit de faire une class BoundingBox, à chaque objet bounding box, tu attache uns surface SDS, et dès que tu détecte une collision entre deux bounding box, tu traite la collision sans te soucier de l'objet mais, tu dois classifer tes élément en plusieurs catégories (généralement 2 ou 3 : ennemies, wall, items), puis selon le cas, tu fais ce que t'as à faire
Voila, en espérant t'avoir été utile.
La maîtrise des fondamentaux est le fondamental de la Maîtrise.
Il te suffit de faire une class BoundingBox, à chaque objet bounding box, tu attache uns surface SDS, et dès que tu détecte une collision entre deux bounding box, tu traite la collision sans te soucier de l'objet
C'est là le problème, tout trier dans des classes, je pense pouvoir le faire (y'a intérêt..), mais c'est le "dès que tu détectes une collision" qui pose problème, comment, sans faire ce que m'a proposé Nanoc en 1, détecter une collision ?
Citation
1) A chaque temps, chaque objet vérifie qu'il est pas en collision avec chaque autre objet. C'est facile à implémenter mais peu efficace si le nombre d'objets devient grand (>100).
Et au passage, c'est quoi une surface SDS , google a pas l'air de connaître
Nanoc, en 2 tu me proposes une solution qui correspond surement exactement à ce que je veux, mais après quelques recherches je crois que std::map c'est un "template", et que pour m'en servir il faut que je lise des tutos en anglais ( , mais j'le ferai), qui parlent d'itérateurs et de je ne sais quoi. Tu dis qu'il existe d'autres méthodes, s'il y en a une que je peux exploiter plus facilement je veux bien.
Je suis tombé sur la discussion vraiment par hasard, alors que je cherchais comment gérer le mieux possible une collision sur une trajectoire de sprite.
Je suis vraiment intéressé par la seconde solution de Nanoc :
Citation : Nanoc
2) La position de chaque objet est stockée dans une std::map avec comme clé la position de l'objet. A chaque déplacement, on vérifie que la clé de la map n'existe pas avant d'effectuer le déplacement. Le cas échéant, on gère la collision. Plus difficile à coder, mais plus efficace.
Stocker la position du sprite dans la std::map me paraît une très bonne idée, mais si les sprites ne sont pas ponctuels... chacun de ses pixels occupe une position bien précise, non ?
Dans ce cas, la vérification ne s'effectuerait que pour un seul des pixels du sprite (celui de la position) ?
On ne va quand même pas associer une clé à chacun des pixels "collisionnables" ? Cela me semble très coûteux...
Dans le cas de boîtes de collision, on pourrait peut-être stocker seulement 2 pixels : inférieur gauche et supérieur droit, et puis comparer, mais comment ??
Je suis vraiment perdu et je comprends le mal de Tjukoz
Une surface SDL et pas SDS ( faute de frappe )
Pour ce qui est des optimisations, y'en a une que j'ai développé moi même, tu peux tester les collisions uniquement pour les objets mobiles, c'est vrai, un objet qui bouge peut heurter qelque chose, par contre un objet qui est en arrêt ou fixe n'a nul besoin de tester s'il va entrer en collision, un exemple:
class personnage
{
public:
personnage();
~personnage();
bool isInCollision(personnage* unAutPerso);
bool isMoving();
//et plein d'autres fonctions.
//Attributs:
double _speed; //vitesse de déplacement.
double _direction; //Angle d'orientation du sprite.
if((unAutPerso->X == (cos(_direction) * _speed) + X) && (unAutPerso->Y == (sin(_direction) * _speed) + Y))//Un peu de trigo, ça ne tue personne
returntrue;
else
returnfalse;
}
returnfalse;
}
};
Et voiala , optimisé, et tu n'as plus à te soucier des direction (marche pour 360° ), si elle n'est pas belle la vie
Voila.
EDIT:
Tu peux généraliser la class, au lieu de faire cela uniquement pour les persos, tu peux faire une class Object, qui représentra toutes les entités de ton jeu (items, personnages, munitions ...) comme ça, t'aura un classe qui gère tout
Bonne chance.
La maîtrise des fondamentaux est le fondamental de la Maîtrise.
Ouai j'aime bien ce que fait fissal_houate , moi je vais plus loin en supprimant sa methode isMoving() et en la remplaçant par isMovingLeft(), isMovingRight(), isMovingUp() et isMovingDown().
Ba ouai parce que ça sert a rien de tester une collision a droite si ton personnage tombe a gauche...
Alors apres c'est sur que tu va éliminer enormément de cas si tu testes uniquement avec les objets a droite de ton perso et dans l'angle de camera ( l'ecran de jeu ).
Il y a meme quelque articles qui vont plus loin en découpant ton ecran en plusieurs zones , tu vois genre 9 zones et on teste uniquement avec les objets a droite, qui se trouvent la meme zone ( donc implicitement dans l'angle de caméra ) mais bon c'est inutile la selon moi parce que j'ai rarement vu 200 objets affichés dans la partie droite de l'ecran dans un jeu de plateforme
Juste une question parce qu'on parle de map , de vector , t'as découpé ton espace en tuiles nan ?
Un cerveau (c'est pas méchant, hein), de la géométrie, et math.h
[SDL] Gérer les collisions avec plusieurs objets
× 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.
La maîtrise des fondamentaux est le fondamental de la Maîtrise.
La maîtrise des fondamentaux est le fondamental de la Maîtrise.
La maîtrise des fondamentaux est le fondamental de la Maîtrise.