Un setTimer qui s'emballe :'(

Le
eVlisse
Bonjour,

J'essai de faire une petite animation avec une image qui se déplace de
droite à gauche, et qui se met à rebondir lorsque l'on touche l'image
avec le curseur de la souris
Mon soucis c'est que dès que l'on lui fait plusieurs fois des rebond,
lorsqu'i reprend sont glissage de droite à gauche il est à fond les
ballon mon père noel

Ici, pour voir en réel http://mininux.no-ip.org/Pere_noel/

Le code :
=
<html>

<head>
<title>Pere noel qui rebondit</title>

<style>
DIV.movable { position:absolute; }
</style>

<script language="javascript">
var x = 5; //Starting Location - left
var y = 5; //Starting Location - top
var ItterationFuite = 700;
var Increment = 2; //Move 10px every initialization
var IncrementR2L = 1; //Move 10px every initialization
var NbBounceMax = 356353;
var SpeedX, SpeedY;
var X_Origine=0;
var Y_Origine=0;
var X_Middle;
var Y_Middle;
var Largeur=0;
var Hauteur=0;
var SensX=0, SensY=0;
var N=0
var ecranX,ecranY;

var Mouse_X; // Variable globale Position X de la Mouse
var Mouse_Y; // Variable globale Position Y de la Mouse

//--
// l'argument e n'est passé à la fonction que par les navigateur n'ayant pas
// implémenté event comme objet, IE posséde son propre objet bien connu
event
//--
function WhereMouse( e ){
var DocRef; // Variable pour IE uniquement

// L'événement est passée à la fonction
// donc tous sauf IE
if( e){ // Dans ce cas on obtient directement la
position dans la page
Mouse_X = e.pageX;
Mouse_Y = e.pageY;
}
else{ // Dans ce cas on obtient la position
relative à la fenêtre d'affichage
Mouse_X = event.clientX;
Mouse_Y = event.clientY;

//-- Il faut traiter le CAS des DOCTYPE sous IE
if( document.documentElement &&
document.documentElement.clientWidth) // Donc DOCTYPE
DocRef = document.documentElement; // Dans ce cas c'est
documentElement qui est réfèrence
else
DocRef = document.body; // Dans ce cas c'est
body qui est réfèrence

//-- On rajoute la position liée aux ScrollBars
Mouse_X += DocRef.scrollLeft;
Mouse_Y += DocRef.scrollTop;
}
//Phrase = "X"+Mouse_X+" Y : "+Mouse_Y+" Sens:"+SensX+"/"+SensY;
//document.getElementById("Mouse").innerHTML=Phrase;

}

//== INITIALISATION =
document.onmousemove = WhereMouse;

function initMove() {
id="ufo";

X_Origine =document.getElementById(id).offsetLeft;
Y_Origine =document.getElementById(id).offsetTop;
ecranX = document.body.scrollWidth;
ecranY = document.body.scrollHeight;
Largeur = document.getElementById(id).offsetWidth;
Hauteur = document.getElementById(id).offsetHeight;
X_Middle = Largeur / 2;
Y_Middle = Hauteur / 2;
}

function Sens (id) {
var Div_X = document.getElementById(id).offsetLeft;
var Div_Y = document.getElementById(id).offsetTop;

if (Mouse_X > Div_X+X_Middle) // De droite à gauche
SensX = -1;
else
SensX = 1; // De gauche à Droite

if (Mouse_Y > Div_Y+Y_Middle) // De Bas en Haut
SensY = -1;
else
SensY = 1; //De Haut en Bas
}

function Attack (id) {
var Width = document.getElementById(id).offsetWidth;
var Height = document.getElementById(id).offsetHeight;

Sens(id);
bounceImage();
ItterationFuite p0;
NbBounceMax--;
}

function RightToLeft(id) { //fonction qui permet de faire défiler de la
droite vers la gauche
// Cette fonction à été recopiée depuis la fonction
"bounceImage()" en virant
// le principe de variation en Y, et celle de recule en X
var XX = document.getElementById("ufo").offsetLeft;
var YY = document.getElementById("ufo").offsetTop;

var oldx=XX;
var oldy=YY;

SensX=-1;
//alert ("Ecran "+ecranX+"/"+ecranY);
if (XX+Largeur+Increment > 0) // Ancienne condition remplacée
par 0 : ecranX-10)
XX+=Increment*SensX;
else
XX = ecranX;

// Déplacement au nouvel emplacement
document.getElementById("ufo").style.left = XX+'px';
document.getElementById("ufo").style.top = YY+'px';

// Affichage des variables pour infos :P
var Phrase = "Ecran: "+ ecranX +" x "+ ecranY +"<br> Pos X: "+ XX +"
("+ oldx +")<br>Diff OldX -X : "+ (oldx - XX) +"<br>Y: "+ YY
+"("+oldy+")<br>Hauteur : "+ Hauteur +"<br>Increment:"+ Increment*SensX
+"/"+ Increment*SensY +" Larg:"+ Largeur +"<br>ItterationFuite :
"+ItterationFuite;
document.getElementById("TEST").innerHTML= Phrase;

if (ItterationFuite>0) {
ItterationFuite--;
window.setTimeout('bounceImage()',10);
}
else
window.setTimeout("RightToLeft('id')",10);

}

function bounceImage() { // fonction qui permet à l'image de rebondir
sur les 'bandes' d'écran, tel un billard

var XX = document.getElementById("ufo").offsetLeft;
var YY = document.getElementById("ufo").offsetTop;
var oldx=XX;
var oldy=YY;

if (SensX>0)
if (XX+Largeur+Increment > ecranX-10)
SensX=-1;
if (SensX<0)
if (XX-Increment <= 0)
SensX=1;
XX+=Increment*SensX;

if (SensY>0)
if (YY+Hauteur+Increment+10 > ecranY-10)
SensY=-1;
if (SensY<0)
if (YY-Increment-10 <= 0)
SensY=1;
YY+=Increment*SensY;

// Déplacement au nouvel emplacement
document.getElementById("ufo").style.left = XX+'px';
document.getElementById("ufo").style.top = YY+'px';

if (ItterationFuite>0) {
ItterationFuite--;
window.setTimeout('bounceImage()',10);
}
else
window.setTimeout("RightToLeft('id')",10);
}
</script>
</head>

<body style="background-color: #080808;color:#ffffff;"
onload="initMove();RightToLeft('ufo');">
<div id="TEST" style="Left:0px; Top:0px">Initialisation</div> <!-- Pour
mettre en place une zone pour y inscrire les infos des variables -->
<div id="ufo" class="movable" style="Left:397px; Top:50px"
onMouseOver="Attack('ufo')" >
<img src="1.gif">
</div>
</body>
</html>
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
SAM
Le #25065412
Le 17/12/12 13:07, eVlisse a écrit :
Bonjour,

J'essai de faire une petite animation avec une image qui se déplace de
droite à gauche, et qui se met à rebondir lorsque l'on touche l'image
avec le curseur de la souris ...
Mon soucis c'est que dès que l'on lui fait plusieurs fois des rebond,
lorsqu'i reprend sont glissage de droite à gauche il est à fond les
ballon mon père noel

Ici, pour voir en réel http://mininux.no-ip.org/Pere_noel/



Je n'ai pas regardé mais ...
si on ne veut pas qu'un setTimeout ou un setInterval ne déraille
il faut :
- le nommer
truc = setTimeout(maFonction, leDelai);
- et prévoir de le stopper si on y refait appel (à chaque rebond ?)
clearTimeout(truc);
truc = setTimeout(monAutreFonction, leDelai);


--
Stéphane Moriaux avec/with iMac-intel
eVlisse
Le #25065572
Oui mais voilà, comment je fais cela ?
Car là, dans l'actuel code, j'ai l'impression d'empiler les appels. A
tel point j'avais fait un bout de code assez goret en limitant l'écart
entre mon point X et son ancienne valeur. si la différence étaient de
plus de 2 pixel, je faisait en sorte de la forcer. Je ne suis jamais
passé dans cette condition, car l'écart était toujours de 2, ce qui me
permet d'en déduire qu'en fait je dois les empiler mes appels.
Comme je gère cette partie très mal, c'est pourquoi je me tournais vers vous

Merci à ceux qui m'accordent un peu de leur temps pour me répondre



Le 17/12/2012 14:00, SAM a écrit :
Le 17/12/12 13:07, eVlisse a écrit :
Bonjour,

J'essai de faire une petite animation avec une image qui se déplace de
droite à gauche, et qui se met à rebondir lorsque l'on touche l'image
avec le curseur de la souris ...
Mon soucis c'est que dès que l'on lui fait plusieurs fois des rebond,
lorsqu'i reprend sont glissage de droite à gauche il est à fond les
ballon mon père noel

Ici, pour voir en réel http://mininux.no-ip.org/Pere_noel/



Je n'ai pas regardé mais ...
si on ne veut pas qu'un setTimeout ou un setInterval ne déraille
il faut :
- le nommer
truc = setTimeout(maFonction, leDelai);
- et prévoir de le stopper si on y refait appel (à chaque rebond ?)
clearTimeout(truc);
truc = setTimeout(monAutreFonction, leDelai);


eVlisse
Le #25068472
N'est-ce pas dû au fait que mes deux fonctions de déplacement soit
récursives ?
Mais dans ce cas pourquoi le scrolling de l'image d'un point de vue
vitesse de déplacement ne s’augmente-t-elle pas plus lors du "droite à
Gauche" (lorsque l'on ne botte pas le 'Luc' du père Noël)

Là je suis pommé :'( :'( :'(

Le 17/12/2012 13:07, eVlisse a écrit :
Bonjour,

J'essai de faire une petite animation avec une image qui se déplace de
droite à gauche, et qui se met à rebondir lorsque l'on touche l'image
avec le curseur de la souris ...
Mon soucis c'est que dès que l'on lui fait plusieurs fois des rebond,
lorsqu'i reprend sont glissage de droite à gauche il est à fond les
ballon mon père noel

Ici, pour voir en réel http://mininux.no-ip.org/Pere_noel/

Le code :
========= > <html>

<head>
<title>Pere noel qui rebondit</title>

<style>
DIV.movable { position:absolute; }
</style>

<script language="javascript">
var x = 5; //Starting Location - left
var y = 5; //Starting Location - top
var ItterationFuite = 700;
var Increment = 2; //Move 10px every initialization
var IncrementR2L = 1; //Move 10px every initialization
var NbBounceMax = 356353;
var SpeedX, SpeedY;
var X_Origine=0;
var Y_Origine=0;
var X_Middle;
var Y_Middle;
var Largeur=0;
var Hauteur=0;
var SensX=0, SensY=0;
var N=0
var ecranX,ecranY;

var Mouse_X; // Variable globale Position X de la Mouse
var Mouse_Y; // Variable globale Position Y de la Mouse

//-----------------------------------------------------------------------------

// l'argument e n'est passé à la fonction que par les navigateur n'ayant
pas
// implémenté event comme objet, IE posséde son propre objet bien connu
event
//-----------------------------------------------------------------------------

function WhereMouse( e ){
var DocRef; // Variable pour IE uniquement

// L'événement est passée à la fonction
// donc tous sauf IE
if( e){ // Dans ce cas on obtient directement la
position dans la page
Mouse_X = e.pageX;
Mouse_Y = e.pageY;
}
else{ // Dans ce cas on obtient la position
relative à la fenêtre d'affichage
Mouse_X = event.clientX;
Mouse_Y = event.clientY;

//-- Il faut traiter le CAS des DOCTYPE sous IE
if( document.documentElement &&
document.documentElement.clientWidth) // Donc DOCTYPE
DocRef = document.documentElement; // Dans ce cas c'est
documentElement qui est réfèrence
else
DocRef = document.body; // Dans ce cas c'est
body qui est réfèrence

//-- On rajoute la position liée aux ScrollBars
Mouse_X += DocRef.scrollLeft;
Mouse_Y += DocRef.scrollTop;
}
//Phrase = "X"+Mouse_X+" Y : "+Mouse_Y+" Sens:"+SensX+"/"+SensY;
//document.getElementById("Mouse").innerHTML=Phrase;

}

//== INITIALISATION =============== > document.onmousemove = WhereMouse;

function initMove() {
id="ufo";

X_Origine =document.getElementById(id).offsetLeft;
Y_Origine =document.getElementById(id).offsetTop;
ecranX = document.body.scrollWidth;
ecranY = document.body.scrollHeight;
Largeur = document.getElementById(id).offsetWidth;
Hauteur = document.getElementById(id).offsetHeight;
X_Middle = Largeur / 2;
Y_Middle = Hauteur / 2;
}

function Sens (id) {
var Div_X = document.getElementById(id).offsetLeft;
var Div_Y = document.getElementById(id).offsetTop;

if (Mouse_X > Div_X+X_Middle) // De droite à gauche
SensX = -1;
else
SensX = 1; // De gauche à Droite

if (Mouse_Y > Div_Y+Y_Middle) // De Bas en Haut
SensY = -1;
else
SensY = 1; //De Haut en Bas
}

function Attack (id) {
var Width = document.getElementById(id).offsetWidth;
var Height = document.getElementById(id).offsetHeight;

Sens(id);
bounceImage();
ItterationFuite p0;
NbBounceMax--;
}

function RightToLeft(id) { //fonction qui permet de faire défiler de la
droite vers la gauche
// Cette fonction à été recopiée depuis la
fonction "bounceImage()" en virant
// le principe de variation en Y, et celle
de recule en X
var XX = document.getElementById("ufo").offsetLeft;
var YY = document.getElementById("ufo").offsetTop;

var oldx=XX;
var oldy=YY;

SensX=-1;
//alert ("Ecran "+ecranX+"/"+ecranY);
if (XX+Largeur+Increment > 0) // Ancienne condition
remplacée par 0 : ecranX-10)
XX+=Increment*SensX;
else
XX = ecranX;

// Déplacement au nouvel emplacement
document.getElementById("ufo").style.left = XX+'px';
document.getElementById("ufo").style.top = YY+'px';

// Affichage des variables pour infos :P
var Phrase = "Ecran: "+ ecranX +" x "+ ecranY +"<br> Pos X: "+ XX
+" ("+ oldx +")<br>Diff OldX -X : "+ (oldx - XX) +"<br>Y: "+ YY
+"("+oldy+")<br>Hauteur : "+ Hauteur +"<br>Increment:"+ Increment*SensX
+"/"+ Increment*SensY +" Larg:"+ Largeur +"<br>ItterationFuite :
"+ItterationFuite;
document.getElementById("TEST").innerHTML= Phrase;

if (ItterationFuite>0) {
ItterationFuite--;
window.setTimeout('bounceImage()',10);
}
else
window.setTimeout("RightToLeft('id')",10);

}

function bounceImage() { // fonction qui permet à l'image de rebondir
sur les 'bandes' d'écran, tel un billard

var XX = document.getElementById("ufo").offsetLeft;
var YY = document.getElementById("ufo").offsetTop;
var oldx=XX;
var oldy=YY;

if (SensX>0)
if (XX+Largeur+Increment > ecranX-10)
SensX=-1;
if (SensX<0)
if (XX-Increment <= 0)
SensX=1;
XX+=Increment*SensX;

if (SensY>0)
if (YY+Hauteur+Increment+10 > ecranY-10)
SensY=-1;
if (SensY<0)
if (YY-Increment-10 <= 0)
SensY=1;
YY+=Increment*SensY;

// Déplacement au nouvel emplacement
document.getElementById("ufo").style.left = XX+'px';
document.getElementById("ufo").style.top = YY+'px';

if (ItterationFuite>0) {
ItterationFuite--;
window.setTimeout('bounceImage()',10);
}
else
window.setTimeout("RightToLeft('id')",10);
}
</script>
</head>

<body style="background-color: #080808;color:#ffffff;"
onload="initMove();RightToLeft('ufo');">
<div id="TEST" style="Left:0px; Top:0px">Initialisation</div> <!--
Pour mettre en place une zone pour y inscrire les infos des variables -->
<div id="ufo" class="movable" style="Left:397px; Top:50px"
onMouseOver="Attack('ufo')" >
</div>
</body>
</html>
Clément
Le #25080552
Bonjour,

Ce que propose SAM, je pense, c'est ça : http://jsfiddle.net/RbcAh/

Mettre une variable dans le scope global (ici "timer")
faire un clearTimeout() pour annuler le setTimeout en cours
puis relancer un timeout (quel qu'il soit) en le donnant à la variable
"timer" : timer = setTimeout(bibi,10);

D'ailleurs, un setTimeout avec une string en 1er paramètre est une
horreur. Normalement, c'est une fonction de callback.
exemple :
timer = setTimeout('bounceImage()',10);
devient
timer = setTimeout(bounceImage,10);


Le 17/12/2012 15:55, eVlisse a écrit :
Oui mais voilà, comment je fais cela ?
Car là, dans l'actuel code, j'ai l'impression d'empiler les appels. A
tel point j'avais fait un bout de code assez goret en limitant l'écart
entre mon point X et son ancienne valeur. si la différence étaient de
plus de 2 pixel, je faisait en sorte de la forcer. Je ne suis jamais
passé dans cette condition, car l'écart était toujours de 2, ce qui me
permet d'en déduire qu'en fait je dois les empiler mes appels.
Comme je gère cette partie très mal, c'est pourquoi je me tournais vers
vous

Merci à ceux qui m'accordent un peu de leur temps pour me répondre

Publicité
Poster une réponse
Anonyme