Soyez le premier à donner votre avis sur cette source.
Vue 8 152 fois - Téléchargée 535 fois
<html> <head> <script language="javascript"> var balles = new Array(); var tmp = null; var d=true ; //debug = true var minx=10,miny=30,maxx=440,maxy=230; //position absolu de la fenetre de jeux var rad2deg=180/Math.PI; //conversion du radian au degres var deg2rad=Math.PI/180; //conversion du degres au radian var cas_extreme=0; var coefLin=0.005 ; //coeficient de ralentissement (décroissance liénaire) var seuilStop=0.1; // stop le deplacement si vitesse<seuil //creation de la bille function Balle(id,x,y,a,v,r) { this.id = id; //identifiant this.x =x; //position x this.nx =x; // prochaine position -> pour les chocs this.y =y; this.ny =y; //TODO: remplacer angle,vitesse par dx & dy (+rapide pr les calculs) this.a = a; //angle this.v = v; //vitesse this.m = 4; //masse this.r = r; //rayon this.bouge =true; //patch pour eviter les chevauchements } //pr simplifier les appel des objets function _(idx) {return document.getElementById(idx);} function _v(idx) {return parseFloat(document.getElementById(idx).value,10);} //initialisation/reset code=true -> debut du deplacement function depart(code) { if(d&!code) { //retourne les propriétés d'un div //getProp(_("ecran")); } //Retourne l'air du plateau + onresize getPosition(); if (tmp!=null) {clearTimeout(tmp);} balles = new Array(); cas_extreme=_v("cas"); a_v1 = _v("a1"); v_v1 = _v("v1"); coefLin = _("frein").checked?0.005:0; switch(cas_extreme) { case 0: //mode billard { //d=false; n=0; for (x=0;x<5;x++) for (y=0;y<x;y++) { balles.push(new Balle("r"+n,270+x*15,150-y*15-(5-x)*7.5,0,0,7)); n++; } }; break; case 1: //choc Horizontal a_v1=0; v_v1=1; balles.push(new Balle("r1",200,120,0,-1,7)); break; case 2: //choc Vertical a_v1=90; v_v1=1; balles.push(new Balle("r1",120,200,90,-1,7)); break; case 3: // diagonale opposé a_v1=45; v_v1=1; balles.push(new Balle("r1",200,200,45,-1,7)); break; case 4: // diagonale même sens a_v1=45; v_v1=.5; balles.push(new Balle("r1",50,50,45,1.5,7)); break; } balles.push(new Balle("b1",_v("x1"),_v("y1"),a_v1,v_v1,7)); //affiche les boules a l'ecran ajoutBalle(); //si code =true alors demarre les deplacements if (code) { boucle(); } } function getPosition() { //position de l'air du plateau, ok sous IE & firefox minx=parseInt(_("ecran").offsetLeft,10); miny=parseInt(_("ecran").offsetTop,10); maxx=parseInt(_("ecran").offsetWidth,10); maxy=parseInt(_("ecran").offsetHeight,10); } //retourne les proprietes d'un objet function getProp(x) { htm=""; for (e in x) htm+=e+":"+x[e]+"<br>"; _("debug_").innerHTML=htm; } //boucle de deplacement function boucle() { //deplace les boules bougeMoi(); //test les chocs contre les murs et entre les boules testChoc(); //replace les boules placeMoi(); //relance la fonction apres 10ms //a ajuster en fonction de la vitesse de la machine tmp = setTimeout("boucle()",10); } function testChoc() { for (e=0;e<balles.length;e++) { b=balles[e]; //collision avec les murs if (b.nx<b.r) {b.nx=b.r; b.a = 180-b.a;} if ((b.nx+b.r)>maxx) {b.nx=maxx-b.r; b.a = 180-b.a;} if (b.ny<b.r) {b.ny=b.r; b.a = -b.a;} if ((b.ny+b.r)>maxy) {b.ny=maxy-b.r; b.a = -b.a;} } for (e=0;e<balles.length;e++) { b=balles[e]; for (k=e+1;k<balles.length;k++) { bk=balles[k]; //distance entre 2 balles < sommes des 2 rayons //version light pr la vitesse d'execution distn=(b.nx-bk.nx)*(b.nx-bk.nx)+(b.ny-bk.ny)*(b.ny-bk.ny); if ((distn<=((b.r+bk.r)*(b.r+bk.r)))&&(b.v>0||bk.v>0)) { collision(b,bk); b.bouge=false; } } } //attribue les nouvelles positions à la boule for (e=0;e<balles.length;e++) { b=balles[e]; if(b.bouge) { b.x = b.nx; b.y = b.ny; } b.bouge=true; } } //même version mais en + rapide function collision(aa,bb) { angle= Math.atan2(bb.ny-aa.ny,bb.nx-aa.nx); //dy/dx ra=aa.a*deg2rad;rb=bb.a*deg2rad;m2=aa.m+bb.m;//constante pr eviter les recalculs ca=Math.cos(angle); sa=Math.sin(angle); //if (d) alert("aa [angle depart="+aa.a+", vitesse="+aa.v+"]\nbb [angle depart="+bb.a+", vitesse="+bb.v+"]\n angle collision="+angle*rad2deg); //calcul des vitesses normal et perpendiculaire au choc va_norm=aa.v*Math.cos(-ra+angle); va_perp=aa.v*Math.sin(-ra+angle); vb_norm=bb.v*Math.cos(-rb+angle); vb_perp=bb.v*Math.sin(-rb+angle); //if (d) alert("va_norm :"+va_norm+", va_perp :"+va_perp+"\nvb_norm :"+vb_norm+", vb_perp :"+vb_perp); //conservation energie va2_norm=( (aa.m-bb.m)/m2)*va_norm+( (2*bb.m)/m2 )*vb_norm; vb2_norm=( (bb.m-aa.m)/m2)*vb_norm+( (2*aa.m)/m2 )*va_norm; //if (d) alert("va2_norm :"+va2_norm+", vb2_norm :"+vb2_norm); //nouvelle position, on resort ses cours de maths va2x=va2_norm*ca-va_perp*Math.cos(angle+Math.PI/2); //cos(a+PI/2) = -sin(a) va2y=va2_norm*sa-va_perp*Math.sin(angle+Math.PI/2); //sin(a+PI/2) = cos(a) vb2x=vb2_norm*ca-vb_perp*Math.cos(angle+Math.PI/2); vb2y=vb2_norm*sa-vb_perp*Math.sin(angle+Math.PI/2); //if (d) alert("va2x :"+va2x+", va2y :"+va2y+"\nvb2x :"+vb2x+", vb2y :"+vb2y); //recalcul angle + vitesse aa.v = Math.sqrt(va2x*va2x+va2y*va2y); bb.v = Math.sqrt(vb2x*vb2x+vb2y*vb2y); aa.a = Math.atan2(va2y,va2x)*rad2deg; bb.a = Math.atan2(vb2y,vb2x)*rad2deg; } //effecute le deplacement de la boule function bougeMoi() { htm=""; for (e=0;e<balles.length;e++) { b=balles[e]; //seuil de deplacement avant stop if (b.v<seuilStop) b.v=0; //b.v*=0.998; b.v-=coefLin; //retourne un angle entre 0 & 360 if (b.a<0) do {b.a+=360;} while(b.a<0); if (b.a>360) do {b.a-=360;} while(b.a>360); nx=b.x;ny=b.y; if (b.v>0) //en javascript 0*cos(a) <>0 ??? { nx = b.x+b.v*Math.cos(b.a*deg2rad); ny = b.y+b.v*Math.sin(b.a*deg2rad); } //TODO: il faudrait trouver un truc ici pr eviter que les boules se chevauche b.nx=nx; b.ny=ny; //si mode debug on affiche les info de positions //if (d) htm+="a :"+parseInt(b.a,10)+" - x :"+parseInt(nx,10)+" - y :"+parseInt(ny,10)+" - v :"+parseInt(b.v*100)/100+"<br>"; } if (d) _("debug_").innerHTML=htm; } //replace les boules au bonne positions function placeMoi() { for (e in balles) { b=balles[e]; _(b.id).style.left=parseInt(b.x,10)-b.r+minx; _(b.id).style.top=parseInt(b.y,10)-b.r+miny; } } //places les elements à l'ecran function ajoutBalle() { htm=""; for (e in balles) { b=balles[e]; htm+="<img id='"+b.id+"' src='balle.png' style='position:absolute; top:"+(b.y-b.r+miny)+"px;left:"+(b.x-b.r+minx)+"px;width:"+(b.r*2)+"px;height:"+(b.r*2)+"px;'>"; } _("ecran").innerHTML = htm; } </script> <style> input{font-family:Tahoma;font-size:12px;width:40px;} </style> </head> <body onload="depart(false);" onresize="getPosition();"> <center> <b>collision v1.2β</b></br> <div id="ecran" style="background:#c0c0c0;left:0px;width:450px;height:250px;"></div></br> liste des cas possible :<select id="cas" onchange="depart(false);"><option value="0" selected>mode billard</option><option value="1">choc H</option><option value="2" >choc V</option><option value="3" >choc c1</option><option value="4" >choc c2</option></select></br></br> position x <input type="text" id ="x1" value ="120" onchange="depart(false);"> position y <input type="text" id ="y1" value ="120" onchange="depart(false);"> vitesse <input type="text" id ="v1" value ="5" onchange="depart(false);"> angle <input type="text" id ="a1" value ="0" onchange="depart(false);"> frein<input type="checkbox" checked id="frein" onchange="depart(false);"><br/><br/> <button onclick="depart(true)">depart</button> </center> <div id="debug_" style="font-family:Tahoma;font-size:12px;"></div> <center><br/><br/><br/><div style="font-family:Tahoma;font-size:9px">dernière mise à jour sur mon site : <a href="http://www.crew.free.fr">http://www.crew.free.fr</a><br>powered by <b>AmRouNiX</b> / <b>MaSTeR-KiLLeR</b> (<i>A. Selim</i>) <br> Toutes copies autorisées !</div></center> </body> </html>
pourquoi avoir déactivé le jeu sur votre site ? problème de compatibilité ? Bug ?
++
Un excellent source javascript.
Je n'ai pas le niveau pour regarder en détail la fonction 'collision'.
J'ai fais un test dans "chocH", en faisant passer la bille entre deux autres :
---------------------------------------
case 1: //choc Horizontal
a_v1=0;// v_v1=1;
diametre=13;
balles.push(new Balle("r1",200,120+diametre,0,-1,7));
balles.push(new Balle("r2",200,120-diametre,0,-1,7)); break;
---------------------------------------
La bille du bas a un comportement qui n'est pas correct, car les 2 billes partent dans le même sens, mais de force différentes alors qu'elles sont exactement de part et d'autre de la trajectoire.
Est-ce que ce serait possible de regarder ?
Merci d'avance
Merci pour la note, je viens de mettre à jour mon script justement pour corriger ce genre d'anomalie ! Maintenant ça fonctionne beaucoup mieux même si il y a encore des cas extrêmes , si la vitesse est trop grandes, il y a des cas où la bille atterrit à l'intérieur d'une autre bille et on a des phénomènes bizarres ...
ex : 120 120 8 5 + frein
le fait d'avoir tout mis dans la page HTML est volontaire, j'attends de pondre "THE SCRIPT" qui va tout déchirer avant de mettre dans une .js :)
Tout mes tests se font sur Firefox, je m'assure quand même que ça fonctionne sous IE, par contre je ne l'ai pas testé sous Safari, tu l'a essayé avec un setTimeout à 1 ?
NB: dans mon source j'ai ajouté différent cas de figure que je compte compléter pour avoir tout les cas possibles ...
Cordialement,
Selim A.
Félicitation ta source est extraordinaire ! :O Je mettrais 10/10 mais je vais mettre 9 car il y a encore quelques défauts comme tu le dis. Aussi, le fichier javascript est à l'intérieur du fichier HTML, il est préférable de le mettre dans un fichier externe .js ;)
Pour ceux qui aimerait reproduire le bug dont parle amrounix, mettez les coordonées suivantes : 242 166 10 180. Sur IE du moins, cela cause un bug... mais par contre pas pour Safari.
Pour l'autre navigateur a lequel je teste les sources habituellement, Safari fonctionne au ralenti comme dans tous les cas de SetTimeOut (je n'ai pas regardé le code, mais il doit sûrement en avoir un ou un setInterval)
Je n'ai pas testé Firefox, mais tu dois l'avoir fait non ? ;)
Bonne continuation ;)
JDMCreator
Ajout => Description + Fichiers + etc. => Prévisualisation => Mot clés => Terminé
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.