
// Bubble Shooter - by uja ------------------------------------------------------------------------------------------------
// plöpp, wenn mindestens 3 gleiche, Punkte ab 3 potenzieren
// plöpp, wenn dadurch keine Verbindung mit oben, Punkte je 5
// 17.08.2002: Screen, Images und Sprite, Bildaufbau bei neu(), Shooter
// 19.08.2002: Schuss, Flugbahn, Kollisionscheck, Fixierung, Endcheck
// 21.08.2002: Reaktion auf Schuss (Kette>2 abräumen, schwebende Kugelgebilde platzen lassen, dazu Liste der "festen" Ketten)
// 22.08.2002: Reaktion auf weisse Kugeln (umfärben in "aktuell"), Test mit I5/6, NN6 Moz1,Op6-Moz5, NN4 ist aussen vor.
// 23.08.2002: Hiscore-Routinen, Hilfe-Routinen, Interleave für Mozilla und andere langsame Browser
// 05.09.2002: Eingaberoutine geändert zu Studienzwecken, Tastatureinbindung, Zielzeit begrenzt auf 10s
// 29.09.2002: Beschleunigen der Timer-Routine mit zunehmender Zeit: V.1.0
// 05.09.2003: Anbindung an das generelle Highscore-Modul
// 12.10.2003: Punktebremse eingebaut
// ------------------------------------------------------------------------------------------------------------------------

xmax=10; ymax=12; dx=24; dy=21; zmax=xmax*(ymax+2); x0=194; y0=312;
xoff=80; yoff=48; dxoff=12; 

var i,j,k,t,xa,ya,vx,vy,punkte,level,shoot,count,count2,ende,my_sprite;
var aktuell,farbe,naechster=Math.floor(6*Math.random())+1,interleave=1,zeit=10;
var f=new Array(zmax);
// --- Listen: --------------------------------------------------------------------------------------------
var s_liste=new Array();
var f_liste=new Array();
var liste=new Array();
var liste2=new Array();
var liste3=new Array();

function in_liste(e,l)  { var i,k=-1; if (l[0]>0) for (i=1; i<=l[0]; i++) if (l[i]==e) k=i; return k; }
function sub_liste(e,l) { var k=in_liste(e,l); if (k>0) { l[k]=l[l[0]]; l[0]--; } }  
function add_liste(e,l) { var k=in_liste(e,l); if (k<0) { l[0]++; l[l[0]]=e; } }  


// --- Bilder vorladen und Koordinatenbasen: -------------------------------------------------------------
var bild=new Array('leer','blau','cyan','gelb','gruen','magenta','rot','weiss');
var ima=new Array(); for (i=0; i<bild.length; i++) { ima[i]=new Image; ima[i].src=bild[i]+'.gif'; }
var rise=new Array();
var run=new Array();
var ima_s=new Array();
var i_voll=new Image(); i_voll.src="voll.gif";

k=7.5;
for (i=0; i<23; i++) 
{ ima_s[i]=new Image; ima_s[i].src='shooter_'+k+'.gif'; 
  run[i]=Math.cos(to_rad(k)); rise[i]=Math.sin(to_rad(k)); k=k+7.5;
}
function to_rad(deg) { return deg/360*2*Math.PI; }

function make_sprite(name,inh,sichtbar,x,y,z,dx,dy)
{ var t;
  if (my_browser=='nn4')
  { if (sichtbar) t='visibility="show"'; else t='visibility="hide"';
    t='<layer name="'+name+'" '+t+' z-index="'+z+'"  top="'+y+'" left="'+x+'" width="'+dx+'" height="'+dy+'">'; 
    t=t+inh+'</layer>';
  }
  else
  { if (sichtbar) t='visibility:visible;'; else t='visibility:hidden;';
    t='<div id="'+name+'" style="position:absolute; z-index:'+z+'; '+t;
    t=t+' top:'+y+'px; left:'+x+'px; width:'+dx+'px; height:'+dy+'px; ">'+inh+'</div>';
  }
 document.writeln(t);
}

function init_sprite()
{ var t='<img src="cyan.gif" width=24 height=24 alt="" border=0 name="sprite">';
  make_sprite('l_sprite',t,true,194,312,3,24,24);
}

function add_reihe(flag)
{ var i,j,k,kk,ende=false;
  for (i=0; i<xmax; i++)
  { for (j=ymax; j>1; j--) 
    { k=i+j*xmax;
      f[k]=f[k-2*xmax];
      zeige_feld(k);
      if (f[k]>0) f_liste[in_liste(k-2*xmax,f_liste)]=k;
    }
    if (flag) f[i]=7; else f[i]=Math.floor(6*Math.random())+1;
    zeige_feld(i); add_liste(i,f_liste);
    if (flag) f[i+xmax]=7; else f[i+xmax]=Math.floor(6*Math.random())+1;
    zeige_feld(i+xmax); add_liste(i+xmax,f_liste);
  }
}

function zeige_feld(nr)
{ var i,j,k;
  i=nr%xmax; j=Math.floor(nr/xmax); k=j%2;
  set_bild('ebene'+k,'i_'+i+'_'+j,ima[f[nr]].src);
}
// -----------------------------------------------------------------------------------------------------------------

function neu()
{ var i,j,k,ok;
  stoppen();
  speed=1000;
  punkte=0; level=0; shoot=11; count=0; f_liste[0]=0;
  for (i=0; i<zmax; i++) { f[i]=0; zeige_feld(i); }
  add_reihe(false);
  add_reihe(false);
  ende=false;
  count=0;
  setze(11);
  set_input('knoeppe','form1','punkte',punkte);
  next_ball(6);
}

function next_ball(max)
{ if (ende) { eingabe(punkte); punkte=0; }
  else
  { aktuell=naechster;
    naechster=Math.floor(max*Math.random())+1;
    set_koords('l_sprite',x0,y0,3);
    set_bild('knoeppe','next',ima[naechster].src);
    set_bild('l_sprite','sprite',ima[aktuell].src);
    show_hide('l_sprite',true);
    zeit=10;
    if (get_formobject('knoeppe','form1').spiel.value=='bubbles') { speed=speed-10; if (speed<10) speed=10; }
    starten();
  }
}

function setze(nr) { shoot=nr; set_bild('rahmen','shooter',ima_s[shoot].src); }
function links()   { if (shoot<22) shoot++; set_bild('rahmen','shooter',ima_s[shoot].src); }
function rechts()  { if (shoot>0) shoot--; set_bild('rahmen','shooter',ima_s[shoot].src); }

function schuss()  
{ stoppen();
  xa=x0; ya=y0; vx=8*run[shoot]; vy=8*rise[shoot]; count2=0; 
  var my_object= get_formobject('knoeppe','form1');
  interleave=my_object.inter.value;
  if (!isFinite(interleave)) interleave=1;
  else if (interleave<1) interleave=1;
  window.setTimeout('flugbahn()',50);
}

function flugbahn(ri)
{ var xi,yi,oben=-1,treffer=-1;
  xa=xa+vx;
  ya=ya-vy;
  xi=Math.floor(xa);
  yi=Math.floor(ya);
  count2++; if (count2%interleave==0) set_koords('l_sprite',xi,yi,3);
  if (xa<xoff) { xa=xoff; vx=-vx; }
  else if (xa>(xoff+xmax*dx-dx/2)) { xa=xoff+xmax*dx-dx/2; vx=-vx; }
  treffer=get_treffer();
  if (ya<yoff) { oben=xa; ya=yoff; fix_oben(xa); }
  if (treffer>=0) haenger(treffer);  
  if ((oben>0) || (treffer>=0)) { next_ball(6); } else window.setTimeout('flugbahn()',20);
}

// --- Ende der Flugbahn: --------------------------------------------------------------------------------------

function get_treffer()
{ var i,k,kx,ky,kq,dxq=dx*dx,dxh=Math.floor(dx/2),treffer=-1;
  if (f_liste[0]>0) for (i=1; i<=f_liste[0]; i++)
  { k=f_liste[i];
    kx=(k%xmax)*dx+xoff;
    ky=Math.floor(k/xmax);
    if (ky%2>0) kx=kx+dxh;
    ky=ky*dy+yoff;
    kq=(kx-xa)*(kx-xa)+(ky-ya)*(ky-ya);
    if (kq<dxq) treffer=k;
  }
  return treffer;
}

function haenger(nr)
{ var li,re,lio,liu,reo,reu,x0=(nr%xmax)*dx+xoff,y0=Math.floor(nr/xmax),xx,yy,dxh=Math.floor(dx/2),t,min;
  if (y0%2>0) x0=x0+dxh;
  y0=y0*dy+yoff;
  yy=y0;    xx=x0-dx;  li =(xx-xa)*(xx-xa)+(yy-ya)*(yy-ya); xx=x0+dx;  re =(xx-xa)*(xx-xa)+(yy-ya)*(yy-ya);
  yy=y0-dy; xx=x0-dxh; lio=(xx-xa)*(xx-xa)+(yy-ya)*(yy-ya); xx=x0+dxh; reo=(xx-xa)*(xx-xa)+(yy-ya)*(yy-ya);
  yy=y0+dy; xx=x0-dxh; liu=(xx-xa)*(xx-xa)+(yy-ya)*(yy-ya); xx=x0+dxh; reu=(xx-xa)*(xx-xa)+(yy-ya)*(yy-ya);
  min=li; t='li';
// Randeffekte:
  if ((nr%xmax==0) && (y0%2==0)) { li=9999; lio=9999; liu=9999; }
  else if ((nr%xmax==(xmax-1)) && (y0%2==1)) { re=9999; reo=9999; reu=9999; }
  if (min>re) { min=re; t='re'; }
  if (min>lio) { min=lio; t='lio'; }
  if (min>reo) { min=reo; t='reo'; }
  if (min>liu) { min=liu; t='liu'; }
  if (min>reu) { min=reu; t='reu'; }
  fixiere(nr,t);
}

function fixiere(nr,wo)
{ var ziel,x0=(nr%xmax)*dx+xoff,y0=Math.floor(nr/xmax),flag;
  flag=(y0%2>0)
  if (wo=='li') ziel=nr-1; else if (wo=='re') ziel=nr+1;
  else if (wo=='lio') { ziel=nr-xmax; if (!flag) ziel=ziel-1; }
  else if (wo=='liu') { ziel=nr+xmax; if (!flag) ziel=ziel-1; }
  else if (wo=='reo') { ziel=nr-xmax; if (flag) ziel=ziel+1; }
  else if (wo=='reu') { ziel=nr+xmax; if (flag) ziel=ziel+1; }
  f[ziel]=aktuell;
  zeige_feld(ziel);
  add_liste(ziel,f_liste);
  farbe=aktuell; get_nachbar3(ziel); // markieren zum Umfaerben
  kette(ziel);
  window.setTimeout("auswertung()",200);
  ende=(ziel>=xmax*ymax);  
}

function fix_oben(xx)
{ var ziel=Math.floor((xx-xoff)/dx),dxh=Math.floor(dx/2);
  if ((xx-ziel*dx-xoff)>dxh) ziel++;
  f[ziel]=aktuell;
  zeige_feld(ziel);
  add_liste(ziel,f_liste);
  kette(ziel);
  window.setTimeout("auswertung()",200);
  ende=(ziel>=xmax*ymax);  
}

// ---------------------------------------------------------------------------------------------------

function auswertung()
{ var i,j,k;
  if (liste[0]>2)
  { for (i=1; i<=liste[0]; i++) { f[liste[i]]=0; zeige_feld(liste[i]); sub_liste(liste[i],f_liste); }
    if (liste[0]>2) // Bremse eingebaut 12.10.2003:
    { punkte=punkte+3;
      k=liste[0]-3;
      if (k>0) { if (k<8) punkte=punkte+(1<<k); else punkte=punkte+(1<<8); }
      if (k>8) punkte=punkte+(k-8)*50;
    }
    set_input('knoeppe','form1','punkte',punkte);
    kette2();
  }
  if (liste3[0]>0) for (i=1; i<=liste3[0]; i++) { f[liste3[i]]=farbe; zeige_feld(liste3[i]); } // umfaerben
  count++; 
  if (count%20==0) { if (count%80==20) window.setTimeout("add_reihe(true)",20); else window.setTimeout("add_reihe(false)",20); }
}

// --- Entfernen von Ketten von 3 oder mehr Baellen Laenge: ------------------------------------------
function kette(nr)
{ var i,j,k,k1,weiter=true;
  k=0; liste[0]=1; liste[1]=nr; k1=liste[0];
  while (weiter)
  { weiter=false;
    for (i=k+1; i<=k1; i++)
    { liste2[0]=0; get_nachbar(liste[i]);
      if (liste2[0]>0) { for (j=1; j<=liste2[0]; j++) add_liste(liste2[j],liste); weiter=true; }
    }
    k=k1;
    k1=liste[0];
  }
}

function get_nachbar(nr)
{ var i,x=nr%xmax,y=Math.floor(nr/xmax),z=f[nr];
  i=nr-1; if (x>0)        if (f[i]==z) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  i=nr+1; if (x<(xmax-1)) if (f[i]==z) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  i=nr-xmax; if (i>=0)    if (f[i]==z) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  i=nr+xmax; if (i<xmax*ymax) if (f[i]==z) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  if (y%2>0)
  { i=nr-xmax+1; if (i>=0) if (i%xmax>0) if (f[i]==z) if (in_liste(i,liste)<0) add_liste(i,liste2); 
    i=nr+xmax+1; if (i<xmax*ymax) if (i%xmax>0) if (f[i]==z) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  }
  else
  { if (x>0)
    { i=nr-xmax-1; if (i>=0) if (f[i]==z) if (in_liste(i,liste)<0) add_liste(i,liste2); 
      i=nr+xmax-1; if (i<xmax*ymax) if (f[i]==z) if (in_liste(i,liste)<0) add_liste(i,liste2); 
    }
  }
}

// --- Entfernen von nicht an der Decke hängenden Bällen: ------------------------------------------------
function get_nachbar2(nr)
{ var i,x=nr%xmax,y=Math.floor(nr/xmax);
  i=nr-1; if (x>0)       if (f[i]>0) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  i=nr+1; if (i%xmax>0)  if (f[i]>0) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  i=nr-xmax; if (i>=0)   if (f[i]>0) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  i=nr+xmax; if (i<xmax*ymax) if (f[i]>0) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  if (y%2>0)
  { i=nr-xmax+1; if (i>=0) if (i%xmax>0) if (f[i]>0) if (in_liste(i,liste)<0) add_liste(i,liste2); 
    i=nr+xmax+1; if (i<xmax*ymax) if (i%xmax>0) if (f[i]>0) if (in_liste(i,liste)<0) add_liste(i,liste2); 
  }
  else
  { if (x>0)
    { i=nr-xmax-1; if (i>=0) if (f[i]>0) if (in_liste(i,liste)<0) add_liste(i,liste2); 
      i=nr+xmax-1; if (i<xmax*ymax) if (f[i]>0) if (in_liste(i,liste)<0) add_liste(i,liste2); 
    }
  }
}

// --------------------------------------------------------------------------------------------------
function kette2()
{ var i,i0,j,k,k1,pkt,weiter;
  liste[0]=0; 
  pkt=0;
  for (i0=0; i0<xmax; i0++) if (f[i0]>0) if (in_liste(i0,liste)<0)
  { k=liste[0]; add_liste(i0,liste); k1=liste[0];
    weiter=true;
    while (weiter)
    { weiter=false;
      for (i=k+1; i<=k1; i++)
      { liste2[0]=0; get_nachbar2(liste[i]); 
        if (liste2[0]>0) { for (j=1; j<=liste2[0]; j++) add_liste(liste2[j],liste); weiter=true; }
      }
      k=k1;
      k1=liste[0];
    }
  }
  pkt=f_liste[0]-liste[0];
  if (pkt>0)
  { for (i=0; i<=liste[0]; i++) f_liste[i]=liste[i];
    for (i=0; i<zmax; i++) if (in_liste(i,f_liste)<0) { f[i]=0; zeige_feld(i); }
    punkte=punkte+5*pkt;
    set_input('knoeppe','form1','punkte',punkte);
  }
}
// ---Joker umfärben: --------------------------------------------------------------------------------------------------

function get_nachbar3(nr)
{ var i,x=nr%xmax,y=Math.floor(nr/xmax);
  liste3[0]=0;
  i=nr-1; if (x>0)       if (f[i]==7) add_liste(i,liste3); 
  i=nr+1; if (i%xmax>0)  if (f[i]==7) add_liste(i,liste3); 
  i=nr-xmax; if (i>=0)   if (f[i]==7) add_liste(i,liste3); 
  i=nr+xmax; if (i<xmax*ymax) if (f[i]==7) add_liste(i,liste3); 
  if (y%2>0)
  { i=nr-xmax+1; if (i>=0) if (i%xmax>0) if (f[i]==7) add_liste(i,liste3); 
    i=nr+xmax+1; if (i<xmax*ymax) if (i%xmax>0) if (f[i]==7) add_liste(i,liste3); 
  }
  else
  { if (x>0)
    { i=nr-xmax-1; if (i>=0) if (f[i]==7) add_liste(i,liste3); 
      i=nr+xmax-1; if (i<xmax*ymax) if (f[i]==7) add_liste(i,liste3); 
    }
  }
}

function hilfe(nr)  { var win2=window.open('hilfe.htm','popup','width=592,height=376,scrollbars=yes'); }
function eingabe()  { eintrag('knoeppe','form1'); }

// ------------------------------------------------------------------------------------------------

function timefunct()
{ zeit--;
  for (var i=0; i<10; i++) 
  if (i>=zeit) document.images['c_'+i].src=ima[0].src; else document.images['c_'+i].src=i_voll.src;
  if (zeit<1) { stoppen(); schuss(); } else starten();
}

// --- Flag fuer Eventauswertung: -----------------------------------------------
var aktiv=true;

// --- Timer-Funktionen: --------------------------------------------------------
var timrec1,timrec2,speed=1000,my_funct="timefunct()";
function starten() { timrec1=window.setTimeout(my_funct,speed); aktiv=true; }
function stoppen() { if (timrec1) window.clearTimeout(timrec1); aktiv=false; }
// ------------------------------------------------------------------------------

// Tastaturcodes, Einbinde-Teil: ----------------
// ----------------------------------------------
function abmarsch(c)
{ aktiv=true;
  if (c>96) c=c-48; // NN4-Patch fuer Numlock
  if ((c==56) || (c==38)) schuss();
  if ((c==54) || (c==39)) rechts();
  else if ((c==50) || (c==40)) setze(11);
  else if ((c==52) || (c==37)) links();
// fuer Operaner und NN4: w,k,xy,j:  
  else if ((c==87) || (c==71)) schuss();
  else if ((c==75) || (c==59)) rechts();
  else if ((c==74) || (c==58)) links();
  else if ((c==88) || (c==89)) setze(11);
  else if ((c==72) || (c==73)) setze(11);
  
}
// ----------------------------------------------
