Fonction de collision

Résolu
cs_harmonyk Messages postés 37 Date d'inscription samedi 16 septembre 2006 Statut Membre Dernière intervention 5 juillet 2012 - 18 sept. 2010 à 01:51
PetoleTeam Messages postés 3426 Date d'inscription lundi 26 décembre 2005 Statut Membre Dernière intervention 14 janvier 2011 - 19 sept. 2010 à 13:42
Bonsoir,
je tente depuis quelques heures de coder un petit script qui permettrait la collision entre 2 div.
Un petit dessin s'impose :


Donc quand je clicke sur "lancer" la div_2 monte avec un animate et elle est censée pousser la div_1 quand elle la touche, au moyen de ce script :
function lancer()
{
    var pisteH=$('#test_piste').height();

    setTimeout(function(){collision();},20);
    $('#div_2').animate({'margin-top':'-'+parseInt(pisteH)},3000);
}

function collision()
{
    var div1Pos=$('#div_2').findPos(),
        div2Pos=$('#div_1').findPos();

    if(div_1.y==div2.y)
    {
        $('#div_2').animate({'margin-top':'-30'});
    }
}


(la fonction findPos permet de connaitre la position absolue d'un élément)
Donc, dans l'ordre, au click du bouton, la div_2 commence à monter et la fonction collision() vérifie toutes les 20millisecondes si les coordonées y de chaque div sont égales, et si c'est le cas, la div_1 monte aussi.
Le script fonctionne, mais très mal.
En effet, la présence d'un peu de lag empêche parfois de vérifier la condition if(div1Pos.y==div_2Pos.y) et la div_2 passe donc à travers la div_1.
J'en appelle donc à vos connaissances pour m'aider à optimiser ce script.
Merci d'avance !!

9 réponses

cs_harmonyk Messages postés 37 Date d'inscription samedi 16 septembre 2006 Statut Membre Dernière intervention 5 juillet 2012
18 sept. 2010 à 14:57
re'
Oui j'utilise un maximum jQuery, et ta solution est parfaite...

...à condition que l'animation soit automatique.
Hors ici (bon j'ai oublié de préciser, mais ce script est pour un petit jeu de bowling full Js), la div_2 (celle qui monte) n'est pas toujours censée toucher la div_1 !!
J'ai réussi à coder tout ça en bricolant un peu, l'essentiel c'est que ca fonctionne.
J'ai modifié le if(div_1.y==div2.y) car la condition sur l'axe y est trop précise pour etre vérifiée avec le lag du setTimeout :
function lancer()
{
    var pisteH=$('#test_piste').height();

    setTimeout(function(){collision();},20);
    $('#div_2').animate({'margin-top':'-'+parseInt(pisteH)},3000);
}

function collision()
{
    var div1Pos=$('#div_2').findPos(),
        div2Pos=$('#div_1').findPos();

    if(div_1.y>=div2.y && div_1.x==div_2.x)
    {
        $('#div_2').animate({'margin-top':'-30'});
    }
    setTimeout(function(){collision()},20);
}


Merci quand même à toi pour ta réflexion, ça fait du bien de ne pas être le seul à se creuser =)
3
PetoleTeam Messages postés 3426 Date d'inscription lundi 26 décembre 2005 Statut Membre Dernière intervention 14 janvier 2011 17
18 sept. 2010 à 09:34
Bonjour,
...a présence d'un peu de lag empêche...
????
je pense que tout se passe dans ton test, j'aurais fait une approche de ce type...
RECUP POSITION

 Calcul Position à Atteindre
   Contact_Y = Div_1.PosY + Div_1.Hauteur

 Calcul Position Suivante
   New_Y Div_2.PosY + IncrementY

TEST de COLLISION
===============
 SI New_Y INFERIEUR à Contact_Y ALORS
   Place Div_2 en Contact_Y
   Appel Fonction Deplace Div_1
 SINON
   Place Div_2 en New_Y
   Relance la Fonction
 FIN SI
il va de soit que seul ton cas de figure est géré ici...
;O)
0
cs_harmonyk Messages postés 37 Date d'inscription samedi 16 septembre 2006 Statut Membre Dernière intervention 5 juillet 2012
18 sept. 2010 à 11:40
Bonjour,
merci pour la réponse !
par contre je viens de m'apercevoir d'une erreur de ma part, j'ai ublié une ligne dans le code plus haut !!
Le voici en entier :
function lancer()
{
    var pisteH=$('#test_piste').height();

    setTimeout(function(){collision();},20);
    $('#div_2').animate({'margin-top':'-'+parseInt(pisteH)},3000);
}

function collision()
{
    var div1Pos=$('#div_2').findPos(),
        div2Pos=$('#div_1').findPos();

    if(div_1.y==div2.y)
    {
        $('#div_2').animate({'margin-top':'-30'});
    }
    setTimeout(function(){collision()},20);
}

Il manquait le setTimeout qui relance la boucle qui vérifie l'égalité des coordonées div_1.y==div_2.y, c'est lui qui provoque le léger lag et qui empêche parfois de vérifier la condition.
0
PetoleTeam Messages postés 3426 Date d'inscription lundi 26 décembre 2005 Statut Membre Dernière intervention 14 janvier 2011 17
18 sept. 2010 à 14:40
Bonjour,
après relecture de ton post, il s'avère que tu dois utiliser la bibliothèque jQuery. Si c'est le cas je pense que tu te complique la vie.
En effet la méthode animate se suffit à elle seule, pas besoin de tester la collision...
lu ici -> Perform a custom animation of a set of CSS properties
.animate( properties, [ duration ], [ easing ], [ callback ] )
properties A map of CSS properties that the animation will move toward.
duration A string or number determining how long the animation will run.
easing A string indicating which easing function to use for the transition.
callback A function to call once the animation is complete.

donc tu peux résumer tes fonctions avec
function lancer(){
  var pisteH = $('#test_piste').height();
  $('#div_2').animate({
              'margin-top':'-'+parseInt(pisteH)},
              3000,
              function(){ // ICI la fonction appelée en fin d'animate
                $('#div_2').animate({'margin-top':'-30'});
              });
}

un point that's all!

mais ce que Jean dit il le dit!!!
;O)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
PetoleTeam Messages postés 3426 Date d'inscription lundi 26 décembre 2005 Statut Membre Dernière intervention 14 janvier 2011 17
18 sept. 2010 à 15:07
plusieurs petites remarques et question pour mon info personnel
dans la fonction
function collision(){
    var div1Pos=$('#div_2').findPos(),
        div2Pos=$('#div_1').findPos();
ces 2 variables ne sont pas ulisées ????
if(div_1.y>=div2.y && div_1.x==div_2.x)
d'où sort div2.y

enfin pourquoi utiliser les margin-top et non pas les top directement
...c'est juste pour info !

;O)
0
cs_harmonyk Messages postés 37 Date d'inscription samedi 16 septembre 2006 Statut Membre Dernière intervention 5 juillet 2012
18 sept. 2010 à 15:40
Oups!!
Si elles sont utilisées, c'est juste que je les ai mal écrites ici, j'ai raccourci énormément le script car il y a 10 quilles sinon ^^

A la fonction
function collision(){
    var div1Pos=$('#div_2').findPos(),
        div2Pos=$('#div_1').findPos();

je me sers de ces variables en faisant
if(div1Pos.y>=div2Pos.y && div1Pos.x==div2Pos.x)

grace à la fonction findPos() que je te met ci-dessous si ca peux te servir :
/*
 *Fonction qui reourne les coordonnées d'un élément
 */
jQuery.fn.extend({
   findPos : function()
   {
       obj = jQuery(this).get(0);
       var curleft = obj.offsetLeft || 0;
       var curtop = obj.offsetTop || 0;
       while (obj = obj.offsetParent)
       {
            curleft += obj.offsetLeft
            curtop += obj.offsetTop
       }
       return {x:curleft,y:curtop};
   }
});

Sinon je n'utilise pas top car le plateau de jeu n'est pas en haut de la page, et cela provoquait des bugs css sur IE ('fin comme d'hab quoi)
0
PetoleTeam Messages postés 3426 Date d'inscription lundi 26 décembre 2005 Statut Membre Dernière intervention 14 janvier 2011 17
19 sept. 2010 à 11:26
Bonjour,
si l'action se passe dans une DIV déclarée explicitement en position:relative les DIVs se promenant à l'intérieure de celle ci n'auront aucun soucis même sous IE.

Quant à l'utilisation de jQuery pour cette application, visiblement un jeu de quilles donc, je ne pense pas qu'elle t'apporte bien, qui plus est l'utilisation d'un setTimeout en plus du setInterval qu'utilise surement la méthode animate me semble redondant...

M'enfin bonne Prog....

;O)
0
cs_harmonyk Messages postés 37 Date d'inscription samedi 16 septembre 2006 Statut Membre Dernière intervention 5 juillet 2012
19 sept. 2010 à 11:58
Bonjour,
effectivement cac olle mieux avec un parent en position:relative, j'ai un peu de mal avec les css.
En ce qui concerne ces fonctions, j'ai encore un petit peu avancé, mais j'utilise toujours le setTimeout en plus de l'animate, ne sachant pas vraiment comment faire autrement pour tester les positions des éléments à chaque mouvement de l'animate.
Peut être devrais-je coder ma propre fonction animate ?
Après je n'ai pas remarqué une hausse importante de la consommation des ressources durant ces tests, mais je n'ai pas testé sur un autre pc...
0
PetoleTeam Messages postés 3426 Date d'inscription lundi 26 décembre 2005 Statut Membre Dernière intervention 14 janvier 2011 17
19 sept. 2010 à 13:42
Peut être devrais-je coder ma propre fonction animate ?
je le pense, rien n'empêchant de s'inspirer des fonctions de jQuery.

La consommation des ressources est une façon de parler, lorsque tu vas avoir des boucles il sera intéressant de minimiser les calculs

;O)
0
Rejoignez-nous