begin process at 2010 03 21 22:50:44
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Jeux

 > BILLARD EN JAVASCRIPT C'EST POSSIBLE !

BILLARD EN JAVASCRIPT C'EST POSSIBLE !


 Information sur la source

Note :
9 / 10 - par 2 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Jeux Classé sous :Billard, jeu, Bresenham, pool, javascript Niveau :Expert Date de création :07/04/2009 Date de mise à jour :20/04/2009 13:53:00 Vu / téléchargé :4 045 / 543

Auteur : amrounix

Ecrire un message privé
Site perso
Commentaire sur cette source (13)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Hello tout le monde,
je reviens en force avec un petit jeu que je suis en train de terminer, un jeu de billard en full javascript !
-le programme est basé sur mon moteur de collision encore quelques tout petits bugs sur les chocs (cas extrêmes qui n'arrive pas souvent)
-la queue de billard est dessinée à partir de l'algorithme de Bresenham (tracage de segement) + une modif perso pour l'épaisseur de la droite

vous pouvez déjà commencer à voir un aperçu du futur jeu, même si il n'est pas encore finalisé!
Même si il reste une grosse partie à faire, j'ai programmé la partie la plus difficile !

20/04/09 : ajout d'une méthode ultra rapide qui détecte les croisements de segements, cela me permet de détecter les rebords + les trous, les rebonds se font désormés en fonction de l'angle du rebord ... :)
dans le jeux cela correspond à l'encadré en rouge (pour enlever l'affichage tu rectangle rouge, remplacer dans le source "var d=true;" par "var d=false;"

Source

  • var balles = new Array();
  • var tmp = null;
  • var d=false ; //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 coefLin=0.005 ; //coeficient de ralentissement (décroissance liénaire)
  • var seuilStop=0.1; // stop le deplacement si vitesse<seuil
  • var a_v1 = 0, v_v1 = 5;
  • var pause = true;
  • var col=[/*j*/1,/**/2,1,/**/1,3,2,/**/2,1,2,1,/**/1,2,1,2,2];
  • var src=['blanche','jaune','rouge','noir']
  • var fichier
  • //distance & force maxi de la queue
  • var dmin = 10, dmax = 70, fmax = 30;
  • //creation de la bille
  • function Balle(id,x,y,a,v,r,t)
  • {
  • 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.t = t; //couleur/type de la balle
  • this.bouge =true; //patch pour eviter les chevauchements
  • }
  • /*creation de la queue
  • angle : angle entre queue et boule
  • deltaF : distance de la boule en fonction de la force
  • posX,posY : position de la boule
  • */
  • function dessinQueue(angle,deltaForce,posX,posY)
  • {
  • Lq = 200; // longueur de la queue
  • pcos=Math.cos(angle);
  • psin=Math.sin(angle);
  • xmin= posX+(dmin+deltaForce)*pcos;
  • ymin= posY+(dmin+deltaForce)*psin;
  • xmoy= posX+(dmin+deltaForce+10)*pcos;
  • ymoy= posY+(dmin+deltaForce+10)*psin;
  • xmax= posX+(dmin+deltaForce+Lq)*pcos;
  • ymax= posY+(dmin+deltaForce+Lq)*psin;
  • htm=ligne2(xmin,ymin,xmoy,ymoy,6,'#c0c0c0');//embout
  • htm+=ligne2(xmoy,ymoy,xmax,ymax,6,'brown');
  • return htm;
  • }
  • /*
  • convertie position souris
  • en angle + distance => force
  • */
  • function bougerQ(px,py)
  • {
  • //coordonnée de la balle blanche
  • var posX = balles[0].x,posY = balles[0].y;
  • py-=miny;px-=minx;
  • a_v1= Math.atan2(py-posY,px-posX);
  • deltaForce= Math.sqrt((py-posY)*(py-posY)+(px-posX)*(px-posX));
  • deltaForce=((deltaForce+dmin)>dmax) ? dmax : deltaForce;
  • deltaForce=(deltaForce<dmin) ? dmin : deltaForce;
  • v_v1 = deltaForce/10;
  • balles[0].a = a_v1 * rad2deg + 180;
  • balles[0].v = v_v1;
  • _("ecran2").innerHTML=dessinQueue(a_v1,deltaForce,posX,posY);
  • }
  • /*
  • capture deplacement de la souris
  • (onmousemove)
  • */
  • function bougerQueue(event)
  • {
  • var ev = event || window.event;
  • //getProp(ev);
  • if (pause)
  • {
  • tmp=setTimeout("bougerQ("+(ev.pageX||ev.clientX)+","+(ev.pageY||ev.clientY)+")",10);
  • }
  • }
  • /*
  • capture clic de la souris
  • (onclick)
  • */
  • function tirer()
  • {
  • pause=false;
  • _("ecran2").innerHTML="";
  • boucle();
  • }
  • //pr simplifier les appel des objets
  • function _(idx)
  • {return document.getElementById(idx);}
  • function _v(idx)
  • {return parseFloat(document.getElementById(idx).value,10);}
  • //initialisation/reset
  • function depart()
  • {
  • //Retourne l'air du plateau + onresize
  • getPosition();
  • //efface tempo
  • if (tmp!=null)
  • {clearTimeout(tmp);}
  • //lise des boules
  • balles = new Array();
  • //coefficient de freinage
  • //decroissance linéaire
  • coefLin = 0.005;
  • //ajout de la boule blanche
  • balles.push(new Balle("b1",120,120,a_v1,v_v1,8.5,0));
  • blanche=balles[0];
  • //d=false;
  • //ajout des boules + disposition en triangle
  • n=0;
  • for (x=0;x<6;x++)
  • for (y=0;y<x;y++)
  • {
  • balles.push(new Balle("r"+n,270+x*20,150-y*20-(5-x)*10,0,0,9,col[n]));
  • n++;
  • }
  • //affiche les boules a l'ecran
  • ajoutBalle();
  • //associe les evenements
  • document.onmousemove=bougerQueue;
  • }
  • 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);
  • //ajuste le div de la queue
  • _("ecran2").style.left=minx;
  • _("ecran2").style.top=miny;
  • _("ecran2").style.width=maxx;
  • _("ecran2").style.height=maxy;
  • }
  • //retourne les proprietes d'un objet (debug)
  • 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
  • if (!pause)
  • {
  • 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;
  • }
  • }
  • //test de collision
  • 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="";
  • stopper = false;
  • for (e=0;e<balles.length;e++)
  • {
  • b=balles[e];
  • //seuil de deplacement avant stop
  • if (b.v<seuilStop)
  • b.v=0;
  • if (b.v>0 && !stopper)
  • stopper = true;
  • //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 (!stopper) {
  • //alert('stop');
  • pause = true;
  • }
  • //pause = !stopper;
  • 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='img/"+src[b.t]+".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;
  • }
  • //-------------------------------------
  • //-------------------------------------
  • function ajoutPix(x, y, l, h, c)
  • {
  • return "<div style='left:"+x+"px;top:"+y+"px;width:"+l+"px;height:"+h+"px;background-color:"+c+";overflow:hidden;position:absolute;'><\/div>";
  • }
  • /*
  • tracer d'une droite avec l'algorithme Bresenham
  • -modifié pour créer un effet d'epaisseur
  • x1,y1,x2,y2 : coordonnée du segment
  • diam : diametre du segment
  • c : couleur
  • */
  • function ligne2(x1, y1, x2, y2, diam, c)
  • {
  • htm="";
  • if (c==null)
  • c="black"; //couleur par defaut
  • if (diam==null)
  • diam=2; //epaiseur par defaut
  • if(x1 > x2)
  • {
  • //swap(x1,x2);
  • var z = x2;x2 = x1;x1 = z;
  • z = y2;y2 = y1;y1 = z;
  • }
  • var dx = x2-x1, dy = Math.abs(y2-y1); //delta x & y
  • var x = x1, y = y1;
  • var ySens = (y1 > y2)? -1 : 1; //direction de Y
  • if(dx < dy)
  • {
  • var d2 = diam>>1; //equivalent à Math.round(diam/2);
  • var dxy = 2*(dx - dy),
  • p = 2*dx-dy,
  • py = y;
  • if(y2 > y1)
  • {
  • while(dy > 0)
  • { --dy;
  • y += ySens;
  • if(p > 0)
  • {
  • htm+=ajoutPix(x++, py, diam, y-py+d2,c);
  • p += dxy;
  • py = y;
  • }
  • else p += 2*dx;
  • }
  • htm+=ajoutPix(x2, py, diam, y2-py+d2+1,c);
  • }
  • else
  • {
  • while(dy > 0)
  • {--dy;
  • if(p > 0)
  • {
  • htm+=ajoutPix(x++, y, diam, py-y+d2,c);
  • y += ySens;
  • p += dxy;
  • py = y;
  • }
  • else
  • {
  • y += ySens;
  • p += 2*dx;
  • }
  • }
  • htm+=ajoutPix(x2, y2, diam, py-y2+d2,c);
  • }
  • }
  • else
  • {
  • var dxy = 2*(dy - dx),
  • p = 2*dy-dx,
  • px = x;
  • d2 = diam>>1 ;
  • while(dx > 0)
  • {--dx;
  • ++x;
  • if(p > 0)
  • {
  • htm+=ajoutPix(px, y, x-px+d2, diam,c);
  • y += ySens;
  • p += dxy;
  • px = x;
  • }
  • else p += 2*dy;
  • }
  • htm+=ajoutPix(px, y, x2-px+d2+1, diam,c);
  • }
  • return htm;
  • }
var balles = new Array();
var tmp = null;
var d=false ; //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 coefLin=0.005 ; //coeficient de ralentissement (décroissance liénaire)
var seuilStop=0.1; // stop le deplacement si vitesse<seuil
var	a_v1 = 0, v_v1 = 5;
var pause = true;
var col=[/*j*/1,/**/2,1,/**/1,3,2,/**/2,1,2,1,/**/1,2,1,2,2];	
var src=['blanche','jaune','rouge','noir']
var fichier
//distance & force maxi de la queue
var dmin = 10, dmax = 70, fmax = 30;


//creation de la bille
function Balle(id,x,y,a,v,r,t)
{
	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.t = t; //couleur/type de la balle
	this.bouge =true; //patch pour eviter les chevauchements
}

/*creation de la queue
angle : angle entre queue et boule 
deltaF : distance de la boule en fonction de la force
posX,posY : position de la boule
*/
function dessinQueue(angle,deltaForce,posX,posY)
{
	Lq = 200; // longueur de la queue	
	pcos=Math.cos(angle);
	psin=Math.sin(angle);
	xmin= posX+(dmin+deltaForce)*pcos;
	ymin= posY+(dmin+deltaForce)*psin;
	xmoy= posX+(dmin+deltaForce+10)*pcos;
	ymoy= posY+(dmin+deltaForce+10)*psin;
	xmax= posX+(dmin+deltaForce+Lq)*pcos;
	ymax= posY+(dmin+deltaForce+Lq)*psin;	

	htm=ligne2(xmin,ymin,xmoy,ymoy,6,'#c0c0c0');//embout
	htm+=ligne2(xmoy,ymoy,xmax,ymax,6,'brown');	
	
	return htm;
}

/*
convertie position souris
en angle + distance => force
*/
function bougerQ(px,py)
{
//coordonnée de la balle blanche
var posX = balles[0].x,posY = balles[0].y;
py-=miny;px-=minx;
a_v1= Math.atan2(py-posY,px-posX);
deltaForce= Math.sqrt((py-posY)*(py-posY)+(px-posX)*(px-posX));
deltaForce=((deltaForce+dmin)>dmax) ? dmax : deltaForce;
deltaForce=(deltaForce<dmin) ? dmin : deltaForce;
v_v1 = deltaForce/10;
balles[0].a = a_v1 * rad2deg + 180;
balles[0].v = v_v1;
_("ecran2").innerHTML=dessinQueue(a_v1,deltaForce,posX,posY);
}
/*
capture deplacement de la souris
(onmousemove)
*/
function bougerQueue(event)
{
var ev = event || window.event;
//getProp(ev);
if (pause)
	{
	tmp=setTimeout("bougerQ("+(ev.pageX||ev.clientX)+","+(ev.pageY||ev.clientY)+")",10);
	}
}

/*
capture clic de la souris
(onclick)
*/
function tirer()
{
pause=false;
_("ecran2").innerHTML="";
boucle();	
}

//pr simplifier les appel des objets
function _(idx) 
	{return document.getElementById(idx);}	
function _v(idx) 
	{return parseFloat(document.getElementById(idx).value,10);}

//initialisation/reset 
function depart()
{
	//Retourne l'air du plateau + onresize
	getPosition();

	//efface tempo
	if (tmp!=null)
		{clearTimeout(tmp);}
	
	//lise des boules
	balles = new Array();

	//coefficient de freinage
	//decroissance linéaire
	coefLin = 0.005;
	
	//ajout de la boule blanche
	balles.push(new Balle("b1",120,120,a_v1,v_v1,8.5,0));
	blanche=balles[0];
	
	//d=false;
	//ajout des boules + disposition en triangle
	n=0;
	for (x=0;x<6;x++)
		for (y=0;y<x;y++)
			{
			balles.push(new Balle("r"+n,270+x*20,150-y*20-(5-x)*10,0,0,9,col[n]));		
			n++;
			}

	//affiche les boules a l'ecran
	ajoutBalle();
	//associe les evenements
	document.onmousemove=bougerQueue;
}

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);
	
	//ajuste le div de la queue
	_("ecran2").style.left=minx;
	_("ecran2").style.top=miny;
	_("ecran2").style.width=maxx;
	_("ecran2").style.height=maxy;
	
}

//retourne les proprietes d'un objet (debug)
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
	if (!pause)
		{
		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;
	}
}

//test de collision
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="";
	stopper = false;
	for (e=0;e<balles.length;e++)
	{
	b=balles[e];
	//seuil de deplacement avant stop
	if (b.v<seuilStop)
		b.v=0;
	if (b.v>0 && !stopper) 
		stopper = true;
	//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 (!stopper) {
	//alert('stop');
	pause = true;
	}
	//pause = !stopper;
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='img/"+src[b.t]+".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;
}

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

function ajoutPix(x, y, l, h, c)
{
	return "<div style='left:"+x+"px;top:"+y+"px;width:"+l+"px;height:"+h+"px;background-color:"+c+";overflow:hidden;position:absolute;'><\/div>";
}

/*
tracer d'une droite avec l'algorithme Bresenham
-modifié pour créer un effet d'epaisseur 
x1,y1,x2,y2 : coordonnée du segment
diam : diametre du segment
c : couleur
*/

function ligne2(x1, y1, x2, y2, diam, c)
{
htm="";
if (c==null) 
	c="black"; //couleur par defaut
if (diam==null) 
	diam=2; //epaiseur par defaut	
	if(x1 > x2)
	{
	//swap(x1,x2);
		var z = x2;x2 = x1;x1 = z;
		z = y2;y2 = y1;y1 = z;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1); //delta x & y
	var x = x1, y = y1;
	var ySens = (y1 > y2)? -1 : 1; //direction de Y
	
	if(dx < dy)
		{
		var d2 = diam>>1; //equivalent à Math.round(diam/2);

		var dxy = 2*(dx - dy),
		p = 2*dx-dy,
		py = y;
		
		if(y2 > y1)
		{
			while(dy > 0)
			{   --dy;
				y += ySens;
				if(p > 0)
				{
					htm+=ajoutPix(x++, py, diam, y-py+d2,c);
					p += dxy;
					py = y;
				}
				else p += 2*dx;
			}
			htm+=ajoutPix(x2, py, diam, y2-py+d2+1,c);
		}
		else
		{
			while(dy > 0)
			{--dy;
				if(p > 0)
				{
					htm+=ajoutPix(x++, y, diam, py-y+d2,c);
					y += ySens;
					p += dxy;
					py = y;
				}
				else
				{
					y += ySens;
					p += 2*dx;
				}
			}
			htm+=ajoutPix(x2, y2, diam, py-y2+d2,c);
		}
	}
	else
	{
		var dxy = 2*(dy - dx),
		p = 2*dy-dx,
		px = x;
		d2 = diam>>1 ;
		
		while(dx > 0)
		{--dx;
			++x;
			if(p > 0)
			{
				htm+=ajoutPix(px, y, x-px+d2, diam,c);
				y += ySens;
				p += dxy;
				px = x;
			}
			else p += 2*dy;
		}
		htm+=ajoutPix(px, y, x2-px+d2+1, diam,c);
	}
	return htm;
}


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

11 avril 2009 12:26:31 :
ajout de détails graphique, amélioration du dessin de la queue,et amélioration de la jouabilité (+ de réalisme)
20 avril 2009 13:53:01 :
ajout du gameplay (en test), optimisation des rebond et détection de trou, correction des collisions

 Sources du même auteur

Source avec Zip Source avec une capture CRYPTOR - PROTEGEZ VOS CODES SOURCES !
Source avec Zip Source avec une capture CODE UTF-8
Source avec Zip Source avec une capture QUIZZ MASTER : 2000 QUESTIONS POUR TESTER VOTRE CULTURE
Source avec Zip Source avec une capture COLLISION V1.2 : GESTION DE CHOCS
Source avec Zip Source avec une capture DIRECTION DE LA MECQUE AVEC GOOGLE MAP

 Sources de la même categorie

Source avec Zip SPACE INVADER par aurelardie
Source avec Zip Source avec une capture DEMINEUR JAVACSCRIPT | PHP, CONFIGURABLE AVEC LE FRAMWORK JQ... par Nementon
Source avec Zip Source avec une capture ATTRAPE MOI SI TU PEUT par kazma
Source avec Zip LE CÉLÈBRE JEU SNACK par lesnouesremy
Source avec Zip Source avec une capture QUIZZ MASTER : 2000 QUESTIONS POUR TESTER VOTRE CULTURE par amrounix

 Sources en rapport avec celle ci

HTML_ENTITIES_DECODE par zen69
DÉSACTIVER UN BOUTON SUBMIT APRÈS ENVOI DU FORMULAIRE par SoftDeath
AFFICHER OU CACHER UN COMPOSANT AVEC JAVASCRIPT V1.0 par xloadx
Source avec Zip Source avec une capture PALETTE DE COULEURS par titnome
Source avec Zip CRÉATION DE SUDOKU EN JAVASCRIPT par pabbati

Commentaires et avis

Commentaire de jdmcreator le 07/04/2009 23:24:28

Bonjour !

Comme ton projet Collision, cette source me fassionne et j'aimerais beaucoup aidé à l'amélioré. Par exemple, je crois qu'il serait assez simple de faire "rentrer les balles dans les trous" en intérogeant les positions des balles. Félicitation pour le travail (ça du être un grand boulot) c'est sûr que si on pourrait diriger la force du bâton.

Cordialement,

JDMCreator

Commentaire de JJDai le 08/04/2009 11:41:18

Je n'ai pas encore regardé le source, mais c'est tout simplement génial.

Commentaire de amrounix le 08/04/2009 12:42:53

Bonjour,
Merci pour vos commentaires , actuellement je réfléchi à une méthode pour la gestion du jeu la plus light possible !
Merci JDMCreator pour ta proposition, là où j'aurais besoin d'aide c'est dans les petits détails pour améilorer le graphisme et la jouabilité c'est à dire :
-image d'une table de billard à l'échelle (avec les trou) ce sera bcp mieu que mon ptit carrée vert
-refaire les images des boules au bon diamètre par rapport à l'air de jeu(ca m'a pris 10 minutes chrono avec photoshop) et rajouter des effets d'ombre etc..
-trouver des valeurs cohérentes à la force minimim, force maximum, coefficient de freinage ... constante : dmin, dmax, fmax,coefLin et seuilStop
c'est tout ces petits détails qui prennent du temps mais qui font tout le jeu !
je vais aussi essayer d'améliorer le dessin de la queue de billard, je ne m'attendais pas à ce que l'affichage soit aussi fluide !

Commentaire de Kimjoa le 08/04/2009 14:20:36

c'est vrai que c'est sympa, même si y a encore comme tu le dit des détails a peaufiner, le gros du taff y est. J'ai essayé vite fait , le gros default c'est que y a pas assé de friction , les billes restes tros longtemps en mouvement.
J'ai pas le temps de regardé le code, mais je suis intrigué du comment tu as fais la queue de billard, avec des div de 1px successif?
Sinon pk ne pas avoir fait ça en canvas , ca aurait été bien plus fluide... bon je parle pas de flash ;).
good job !! a++

Commentaire de amrounix le 09/04/2009 17:09:34

Salut Kimjoa, pour les frictions, ca fait parti des détails que je voulais améliorer pour me rapprocher de la réalité, pour changer la resistance de freinage, il faut modifier la variable coefLin qui est à 0.005 (ligne 122) , donc à chaque boucle, la vitesse va diminier de 0.005 jusqu'à l'arrêt ! donc si on monte cette valeur, la boule freinera plus vite ! la vitesse va décroître de façon linéaire (b.v-=coefLin; ligne 275), on pourrait aussi imaginer y inclure une décroissance exponentielle (b.v*=coefMul; avec coefMul=0.9998 proche de 1) pour se rapprocher de la réalité ... bref ça c'est le freinage !
En ce qui concerne la queue de billard, c'est un code spécial killer (moi) lol ! l'astuce c'est justement de ne pas faire de div de 1px mais de n pixels avec n le diamètre du trait, avec chaque pixel du trait passant par le centre de ces div, c à dire de (x-n/2,y-n/2) à (x+n/2,y/n/2) d'où par exemple à la ligne 362 je fais un diam/2 (diam est l'epaisseur du trait) ou plutot je fait un d2 = diam>>1 ; (rotation binaire à droit de 1 qui équivaut à un math.round(diam/2); en + rapide !)
voila j'espère avoir tuer personne avec mes explications, lol

pr info : en ce mmt je bosse sur les rebonds au abord des trous en réutilisant ma méthode collisions (simulation d'un choc avec une boule à l'arrêt qui ne bougerait pas) en test ...

Commentaire de Kimjoa le 10/04/2009 15:47:10 10/10

j'ai mal au crane  aiiee :).
En tout cas pour réviser ses math et sa physique, c'est type top !!
Je me suis renseigné un peu sur wiki sur l'algo de la queue ...
Concernant le freinage, je suis pas sur , mais plus y a de vitesse et plus y'a de frottement non? donc un systeme basé dessus serait plus réaliste... le mieux serait de choper les vrai fonction ,mais là à appliquer j'imagine po :)
Sinon lors d'une collision y'a une déperdissions d'energie dut au choc ?
Prochaine étape la rotation de la balle avec les effets ect ...  bon courage ;) ?

a++  

Commentaire de kazma le 11/04/2009 11:07:53 8/10

bonjour

pour la vitesse des boules ce serait bien de donner un poids aux boules

Commentaire de amrounix le 11/04/2009 13:25:26

Bonjour à tous,
Je viens de mettre à jour ma source, après avoir joué plusieurs partie en vrai, j'ai placé le coefficient de frottement à 0.018, dite moi ce que vous en pensé, j'ai aussi amélioré l'image du plateau, l'image de la queue(ca va plaire à Kimjoa) augementé la taille des boules, on ne peut toujours pas rentrer les boules dans les trous parce que je n'ai pas fini d'améliorer les collisions...
pour les effets, ce sera la prochaine étape quand tout sera opérationnel !

pour info :
- le poid de boule est situé à la ligne 29 : "this.m = 4;", et le choc dépend beaucoup du rapport des masses entre les 2 boules !
- le coef de frottement, est bien par rapport à la vitesse (donc décroissance linéaire, elle aurait été logarthimique si elle était liée à l'accélération ... elle l'est mais c'est négligable)
-pr les pertes liées aux chocs, on a un dégagement de chaleur qui est quasi null !
-on peu aussi avoir une perte lié à la déformation des matériaux, mais ce n'est pas le cas ici ! lol

Commentaire de jdmcreator le 11/04/2009 14:45:21

Bonjour,

Mon premier constat de ta nouvelle version est que la présentation graphique a été amélioré mais ici, le jeu est beaucoup plus lent et fonctionne au ralenti.

Est-ce normal ?

JDMCreator

Commentaire de amrounix le 11/04/2009 14:49:29

c'est parce que j'ai beaucoup diminué la vitesse maximale (trop vite) et augmenter les forces de frottement. Le seul souci c'est que ça dépend aussi de la vitesse de la machine, faudrait que je teste mon programme sur d'autre plateforme
Cordialement,

Selim A.

Commentaire de jdmcreator le 11/04/2009 16:50:29

Je l'ai essayé avec les mêmes navigateurs/OS que la dernière fois : IE7 et Safari sur Windows XP ;)

Commentaire de kazma le 12/04/2009 18:49:42

autant pour moi sinon pas mal la nouvelle version largement plus esthétique meme si il est vrais que pour un projet en cour l'estetisme passe apres la fonctionalite en tout cas tu semble bien maitriser ton sujet du moins tu essai de faire le mieux possible
++

Commentaire de amrounix le 20/04/2009 14:06:45

HeLLo les amis ... un petit message pour vous prévenir que j'avais mis a jour mon code, avec pas mal d'amélioration :

-correction des collisions; on avait les boules qui se chevauchaient dans certains cas, le problème était du à la distance entre les boules (variable distn) explication :
b[x,y] : boule d'origine N°1, b[nx,ny] : nouvelle position
b2[x,y] : boule d'origine N°2, b2[nx,ny] : nouvelle position
la distance était calculé entre les boules b[nx,ny] & b2[nx,ny], sauf qu'on ne tennait pas compte de la position d'origine ! bref la distance² correspond à la vitesse² donc pour pallier à ce pb, j'ai fait : distn = distn - b.v² - b2.v² qui correspond au pire scénario ... Je crois que j'ai perdu des gens en route... lol

-les rebords se font par détection de croisement, entre les segements de déplacement de la boule b[x,y] à b[nx,ny] et le rebord, si ca se croise il y'a donc collision, on récupère la normale du plan de contact "p.n" et on sort son livre de physique sur la réflexion d'onde et puis voila ! lol

bon ok j'arret de vous saouler , ce qui compte c'est de pouvoir s'amuser ! En ce moment je cherche les règles du jeux de pool pour adapter le jeu avec les vrais règles ! c'est bientôt la fin ...

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Instit en détresse besoin d'aide - javascript [ par jojosse25 ] AideJ'essaie de fabriquer un jeu pour des enfants de l'école.Deux frames : à gauche la page jeu ( image mappée )à droite la réponse avec commentaire ( Heure visiteur en cookie ou autre [ par zonevirtuel ] bonjour, en fait j'ai un gros soucis ... je suis concepteur d'un jeu sur internet a traffic international, francais, canadiens, et autres viennent r& une map de jeu en javascript [ par lordfinalff ] J'ai trouvé un code source sur ce site (http://www.javascriptfr.com/codes/MOBY-BROS-AVENTURIER-ETOILES_21826.aspx)Je me suis interressé au projet ( bi Stratégie de jeu [ par ralota ] Je souhaite créer un jeu en ligne utilisant javascript et php comme langages. Ce jeu consiste à déplacer des poins tout comme l'échec mais il s'agit d problème javascript void(0) [ par manne1173 ] Bonjour,Je joue régulièrement sur un site de jeu en ligne qui est Equideow, un site de jeu de chevaux.Seulement voilà, depuis un peu plus d'une semain javascript [ par ouzb ] Bonjour a tous, j'ai un probleme j'ai crée une fonction javascript pour faire une verification d'une a cocher Je veux kan l'utilisateur coche la case Probleme Alert JavaScript [ par nanati02 ] Slt à tous,je cree une application en jsp et je dois faire un test sur un formulaire d'ajout si il est valide l'ajout s'affiche dans une liste qui app Pour un site multilangues [ par whombat ] Bonjour à tous, Je réalise un site multilangues en php. Tout va bien. Mais j'ai un script JavaScript qui contient des données qui doivent, elles aus Javascript Arbre [ par Kurus ] Bonjour,Je vous explique mon problème :Je possède un premier arbre que nous appellerons A1. A1 possède des noeuds, des sous noeuds etc ...A1|-Dossier  Problème lancement d'application non auto depuis javascript [ par aforpien ] Bonjour à tous,dans le cadre du deloppement d'un intranet, j'ai créé une liste de serveur de notre société. je souhaiterai ouvrir une connexion damewa


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,874 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales