Fonction de collision [Résolu]

Messages postés
37
Date d'inscription
samedi 16 septembre 2006
Dernière intervention
5 juillet 2012
- - Dernière réponse : PetoleTeam
Messages postés
3435
Date d'inscription
lundi 26 décembre 2005
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 !!
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
Messages postés
37
Date d'inscription
samedi 16 septembre 2006
Dernière intervention
5 juillet 2012
3
Merci
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 =)

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 106 internautes ce mois-ci

Commenter la réponse de cs_harmonyk
Messages postés
3435
Date d'inscription
lundi 26 décembre 2005
Dernière intervention
14 janvier 2011
0
Merci
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)
Commenter la réponse de PetoleTeam
Messages postés
37
Date d'inscription
samedi 16 septembre 2006
Dernière intervention
5 juillet 2012
0
Merci
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.
Commenter la réponse de cs_harmonyk
Messages postés
3435
Date d'inscription
lundi 26 décembre 2005
Dernière intervention
14 janvier 2011
0
Merci
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)
Commenter la réponse de PetoleTeam
Messages postés
3435
Date d'inscription
lundi 26 décembre 2005
Dernière intervention
14 janvier 2011
0
Merci
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)
Commenter la réponse de PetoleTeam
Messages postés
37
Date d'inscription
samedi 16 septembre 2006
Dernière intervention
5 juillet 2012
0
Merci
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)
Commenter la réponse de cs_harmonyk
Messages postés
3435
Date d'inscription
lundi 26 décembre 2005
Dernière intervention
14 janvier 2011
0
Merci
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)
Commenter la réponse de PetoleTeam
Messages postés
37
Date d'inscription
samedi 16 septembre 2006
Dernière intervention
5 juillet 2012
0
Merci
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...
Commenter la réponse de cs_harmonyk
Messages postés
3435
Date d'inscription
lundi 26 décembre 2005
Dernière intervention
14 janvier 2011
0
Merci
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)
Commenter la réponse de PetoleTeam

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.