Tout d'abord bonjour à tous.
Je programme actuellement un jeu de billard en pascal (Pascal Objet pour être exact, sous Lazarus) mais mon problème n'est pas spécifique à Pascal mais est plutôt d'ordre algorithmique.
Le problème que je rencontre se trouve au niveau de la détection des collisions entre boules et de leur gestion.
Je m'explique : lorsque l'utilisateur joue un coup, un composant appelé "Timer" est activé et se charge d'appeler une fonction toutes les X microsecondes.
C'est cette fonction qui se charge de calculer les nouvelles positions des boules, les nouvelles vitesses et également des collisions.
Pour cela elle dispose d'objets décrivant les boules par les coordonnées de leur centre et du vecteur vitesse de ce dernier dans un repère global lié au tapis.
Les boules sont ensuite dessinées sur le tapis, ce sont de simples cercles, comme sur une vue de haut du billard.
Du fait que les positions soient actualisées toutes les X microsecondes, le mouvement de la boule n'est pas "véritablement continu" : à l'œil nu le mouvement semble parfait, étant donné le faible décalage de pixel à chaque rafraichissement et la fréquence des rafraichissements, mais au niveau de l'ordinateur, la boule prend des positions successives, comme ceci :
Le problème est alors le suivant : lors de déplacements impliquant plusieurs boules, ils arrivent que celles ci se recouvrent, comme ceci :
Et cela pose problème pour gérer correctement la collision (je précise au passage que j'ai toutes les équations nécessaires pour le calcul des nouvelles vitesses, là n'est pas le problème). Voilà ce qui se passe précisément :
- Premier calcul : Les positions des boules sont actualisées et ces dernières sont détectées comme étant en collision.
Les vitesses sont alors recalculées avec les équations qui vont bien et le billard est redessiné.- Second calcul : X microsecondes plus tard la fonction de gestion des boules est appelée une seconde fois et met à jour les positions des boules en tenant compte cette fois ci des vitesses modifiées après choc. Puis, elle recommence le même travail que précedemment, à savoir la détection de collisions. Là est tout le problème : si les vitesses des boules sont assez faibles, il se peut qu'elles soient toujours en recouvrement malgré la mise a jour des positions, ainsi la fonction détècte une collision qui n'a pas lieu d'être, et assigne des vitesses qui sont fausses
Voici un schéma qui résume le tout :
Je cherche donc un moyen de fixer tout cela...
Pour le moment j'ai pensé à déclarer un flag pour chaque paire de boule pouvant entrer en collision, mettre à 1 ce flag lorsqu'il y a collision et le remettre à 0 lorsque les boules ne sont plus en recouvrement (que je peux détecter facilement). Il suffirait ensuite de ne prendre en compte la collision de ces deux boules (celles correspondant au flag) uniquement si le flag est à 0. Qu'en pensez vous, je ne suis qu'à moitié satisfait...
Si quelqu'un avait la gentillesse de m'aider je lui en serais grandement reconnaissant.
Merci d'avance.
++
NiklosKoda.
PS : j'ai oublié de préciser la manière dont je détecte les collisions : pour le moment c'est la manière la plus basique, sans algorithme complexe particulier. Je parcours simplement tous les couples de boules possibles, en évitant les redondances, et je teste si la distance entre les centres des deux boules est inférieure ou égale à la somme des deux rayons.
Partager