Da hat man mal wieder Lust auf ein Ründchen Patience, holt die Karten aus dem Schrank, mischt sie gründlich, teilt sie erwartungsvoll aus, holt sich ein Likörchen oder lecker Weinchen und einige Kekse, legt los, und dann kommt eine bestimmte Karte nicht, die man dringend braucht!
Sie kommt überhaupt nicht, denn das Söhnchen hat sie verschleppt, sie fiel beim letzten Canasta-Treffen unter den Tisch und schimmelt hinter der Heizung vor sich hin, oder beim letzten Umzug verdünnisierte sie sich auf die Straße, als ein Karton auf die Straße fiel und seinen Inhalt in den Rinnstein ergoß.
Vielleicht hat man aber auch gar kein Kartenspiel, aber einen Computer mit einem Browser. - Na, prima, bringen wir dem Browser bei, mit uns Patience zu spielen!
Patience ist ein Kartenlegespiel, bei dem Karten in der Reihenfolge ihres Wertes nach Farben sortiert auf Ablagen gesammelt werden sollen. Wie das zu geschehen hat, ist in den jeweiligen Regeln festgelegt.
Die "Belagerung" ist zwar eine Patience, die nicht sehr oft aufgeht, aber sie ist schnell zu "Freecell" erweitert. Der Quelltext ist nicht allzu lang, so dass er sich als Beispiel gut eignet.
zum Seitenanfang | ||
zum Seitenende |
Das zu erstellende Dokument soll den Tisch nachbilden, auf der die Patience gespielt wird. Im Fall der "Belagerung" muss man 4 Ablagen unterbringen sowie 8 Reihen, in denen die 52 Karten offen ausgeteilt werden. Da die Karten fast beliebig verschiebbar sind, kann es sein, dass in einer Reihe über 40 Karten auftauchen, in anderen gar keine.
Will man in diesen Fällen mit fest positionierten Grafikelementen arbeiten, muss man also 40x8+4=324 verweissensitive Grafiken unterbringen. Und arbeitet man mit einem doppelten Kartenspiel wie z.B. für die "Neuner" oder "Große Harfe", sind es mehr als 10*100+10+2=1012 zu erstellende, gut gefüllte Objekte.
Das Laden der Seite stellt den Anwender auf eine Geduldsprobe, also verbietet sich dieser Weg. Was dann? - OOP ist angesagt!
zum Seitenanfang | ||
zum Seitenende |
Ein Informatiker erklärte mir die objekt-orientierte Programmierweise folgendermaßen:
Wir wollen was nachbilden. Sagen wir: ein Haus. Das heisst dann(Hier driftete das Gespräch dann etwas ab.)mein_haus=new Haus()
.
Dieses Haus hat ein paar Zimmer:with(mein_haus) { Wohnzimmer=new Zimmer(); Kueche=new Zimmer(); }
In der Küche steht ein Stuhl und ein Tisch:with(mein_haus.kueche) { Tisch=new Moebel(); Stuhl=new Moebel(); }
Auf dem Stuhl kann man sitzen:mein_Haus.Kueche.Stuhl.sitzen();
Der Stuhl ist braun:mein_Haus.Kueche.Stuhl.Farbe=braun;
Übertragen auf unser Kartenspiel heisst das: Wir haben 52 Karten, diese haben je ein Bild (und eine Rückseite, die hier aber eher uninteressant ist). Wenn sie auf dem Tisch liegen, haben sie Koordinaten. An den Koordinaten erkennt man, ob sie im Talon, in einer der Reihen oder auf einer der Ablagen liegen. Das Bild enthält Informationen zu Farbe und Wert.
Na, dann bilden wir die Karten doch mal nach. Schicke Bilder, 52 Stück an der Zahl in doppelter Ausführung für
Merkeffekte sind ein Fall für Paintshop oder ein anderes Grafikprogramm. Die Bilder benennen wir geordnet nach
1.Farbe und 2.Wert cxx.gif
und cxxa.gif
, wobei xx von 0 bis 51 geht.
Die Farbe ist dann Math.floor(xx/13)
, der Wert xx%13
.
So, und nun noch schöne Platzhalter für die Reihen und die Ablagen, vielleicht noch ein Kartenrücken, das war's
dann auch schon mit den Vorarbeiten mit einem Grafikprogramm.
Den Zugriff auf Koordinaten liefert uns das Objekt div
im Objekt document
des Objektes
window
. Sobald ein Fenster aufgerufen wird, ist das window
-Objekt schon da,
das document
entsteht spätestens durch die body
-Tags, nach DOM2 schon direkt nach Bereitstellen des Fensters. Die benötigten
div
-Objekte erzeugt man durch durch div
-Tags, und damit man sie auseinanderhalten kann, verpasst man ihnen
eine id
. Die Raum-Koordinaten bekommen sie durch die style
-Attribute
position:absolute; top:12px; left:8px; z-index:4
: 8.Pix von links, 12.Pix von oben, 4.Schicht von unten.
Das Bild bekommen sie, indem zwischen den div
-Tags ein Image-Objekt <img ... >
geschrieben wird. Ab dann lassen sie sich hin- und herschieben. Dann noch die Grafik verweissensitiv gemacht,
fertig sind die Spielkarten!
zum Seitenanfang | ||
zum Seitenende |
Kartenobjekte schon fertig? Wirklich? Nein, da ist ein kleines Dorf, äh, ein alter Browser, der die Schieberei nicht mitmacht! Und dies ist der Einstieg in das traurige Kapitel der Browserinkompatibilitäten! -
Für Netscape 4.xx werden die Karten also nicht in div
s verpackt, sondern in layers
.
Und wenn man sich das DocumentObjectModel, kurz:DOM anschaut und etwas herumprobiert, so stellt man fest,
dass bei layers styles
ziemlich fehl am Platze sind. Die Karten bekommen auf folgende Weise ihre
Raumkoordinaten: <layer name="k_name" left="yy" top="xx"
z-index="zz">
xx,yy und zz stehen für die Koordinaten, k_name für das id
-Äquivalent.
Am besten schreiben wir uns eine Funktion, die uns die Karten erstellt.
Als Vorarbeit müssen wir erst mal bestimmen, mit welchem Browser (DOM) gearbeitet wird. Wir unterscheiden hier zwischen nn4, nn5, ie4, ie5 und sonstige:
var xyz=new Array(3); // temp.Wert fuer Koordinaten der Objekte var my_browser=get_browser(); Kennung des Browsers fuer DOM function get_browser() { var t=navigator.appName; if (t=='Netscape') t='nn'; else if (t.search(/Internet.+/)>-1) t='ie'; if (navigator.appVersion.substring(0,1) == "4") t=t+4; else if (navigator.appVersion.substring(0,1) == "5") t=t+5; if (t=='ie4') if (document.documentElement) t='ie5'; return t; }
Warum fragen wir nicht einfach auf Objekte ab? - Es gibt Browser wie z.B. Opera, die meinen, ein Objekt zu kennen,
aber dann kennen sie nicht mehr als den Namen dieses Objektes. Sagt ihm der Anwender aber, er soll das DOM von IE
oder Mozilla/Netscape benutzen, dann klappt die Zusammenarbeit auf einmal.
Desweiteren sollte man die "crossbrowser"-Funktionen immer so anlegen, dass im letzen Fall (sonstige)
das neueste DOM (nn5) herangezogen wird.
Somit werden erst die "bewährten" Modelle durchprobiert, bevor es an etwas noch nicht ganz Ausgegorenes geht.
Die Karten werden also folgendermaßen erzeugt und erscheinen erst mal alle oben links (Talon):
zmax=52; // 52 Karten dx=56; dy=80; dy2=12; // Kartengroesse und der Teil, // der bei den Reihen nicht überlappt rmax=8; smax=4; // 8 Reihen, 4 Stacks var gewaehlt=-1; // aktuell gewaehlte Karten function gen_karten() { var i,t,t1; for (i=0; i<zmax; i++) { // -- verweissensitives Bild: t1='<a href="javascript:klick('+i+')">'; t1=t1+'<img src="'+ima_c[i].src+'" width=56 height=80 '; t1=t1+'alt="" name="k'+i+'" border=0></a>'; // - Verpackung in div/layer wg. Koordinaten-Zugriff: if (my_browser=='nn4') { t='<layer name="k_"'+i+'" z-index="'+(i+1) t=t+'"top="12" left="12" width="'+dx+'" height="'+dy+'">'; t=t+t1+'</layer>'; } else { t='<div id="k_'+i+'" style="position:absolute; top:12px; '; t=t+'left:12px; width:'+dx+'px; height:'+dy+'px; '; t=t+'z-index:'+(i+1)+'">'+t1+'<div>'; } document.writeln(t); } }
Da die Objekte als Unterobjekte des document
-Objektes geplant sind, rufen wir die Funktion direkt nach dem
öffnenden body
-Tag auf, bevor die nicht verrückbaren div
s erzeugt werden, auch als Unterobjekte
von document/body
.
<body> <script type="text/javascript"> gen_karten(); </script> <div id="kopf" style="position:absolute; top:16px; left:60px; width:588px; height:32px; font-size:16pt; font-weight:bold;"> Belagerung <br> uja Vers. 1.0 </div> <div id="knoepfe" style="position:absolute; top:96px; left:480px; width:96"> <div class="button"><a href="javascript:neu(true)">neues Spiel</a></div> <div class="button"><a href="javascript:neu(false)">von vorne</a></div> <div class="button"><a href="javascript:abraeumen()">abräumen</a></div> <div class="button"><a href="javascript:hilfe()">Hilfe</a></div> </div> ...(weiterer Text)
Jetzt haben wir Karten mit der Id "k_0" bis "k_51", diese enthalten die Bilder
"k0" bis "k51", deren Aussehen von "c0.gif" bis "c51.gif"
bestimmt werden und die bei Bedarf auch das Aussehen von "c0a.gif" bis "c51a.gif"
annehmen können, und die bei Anwählen mit klick(0)
bis klick(51)
reagieren.
zum Seitenanfang | ||
zum Seitenende |
Die Platzhalter geben an, wohin eine Karte hochgelegt werden kann. Sie markieren die erlaubten Reihen. Wir schreiben sie
als div
s in den Body-Teil, damit sind sie direkte Unterobjekte von document
.
Und weil ich bequem bin, lasse ich den Text mit Javascript erzeugen,
vgl. Making of Logelei.
<div id="reihen" style="position:absolute; top:108px; left:8px; z-index:0;"> <script type="text/javascript"> t=''; for (var i=0; i<rmax; i++) t=t+'<a href="javascript:reihe_hoch('+i+')">'; t=t+'<img src="null.gif" width=56 height=80 alt="" border=0></a>'; document.writeln(t); </script> </div>
Die Karten werden derzeit links oben generiert, die Function neu(schalter)
mischt (oder auch nicht,
je nach Wert des Schalters), verteilt die Asse auf die Ablagen, die restlichen Karten auf die Reihen.
Damit man gleich ein hübsches Bild geboten bekommt, wird im Body-Tag onload="neu(true)"
direkt nach Erstellen der Seite aufgerufen. Danach ist der Body-Teil fertig.
zum Seitenanfang | ||
zum Seitenende |
Damit der Bildwechsel bei der Auswahl der Karte flüssig abläuft, sollten die Bilder schon mal über die Internet-Leitung gekommen sein. Dies geschieht mit:
// ----- 52 Kartenbilder vorladen: -------------------- var leer=new Image; leer.src='leer.gif'; var nulli=new Image(); nulli.src='null.gif'; var ima_b=new Image; ima_b.src='bg.gif'; var ima_c =new Array(); var ima_ca=new Array(); for (i=0; i<52; i++) { ima_c[i] =new Image(); ima_c[i].src='c'+i+'.gif'; ima_ca[i]=new Image(); ima_ca[i].src='c'+i+'a'+'.gif'; }
zum Seitenanfang | ||
zum Seitenende |
Bei einem genauen Blick auf die ausgeteilten Karten auf dem Tisch fällt auf, dass Talon, Ablagen und Kartenreihen je eine Einheit bilden, die Karten werden zwischen diesen Einheiten hin- und hergeschoben. Alle diese Einheiten lassen sich durch Listen nachbauen. In dieser Patience wechselt jeweils die letzte Karte in der jeweiligen Liste den Platz.
Bauen wir erst mal den Talon: eine Liste der Karten von 0 bis 52. Wir packen nicht die ganzen 52 Kartenobjekte in diese Liste, sondern *nur* deren Kennziffern! Mischen, Austauschen und Sortieren geht damit erheblich schneller!
Da die javascript-eigenen Funktionen zur Listenverwaltung mir im IE4 mal eine böse Überraschung bei
push
serviert hat, und ich so von Pascal
her so meine eigenen Gedanken habe, was mit Listen alles anzustellen ist, baue ich mir lieber selbst eine
"Listenverwaltung". Ich benutze dafür ein Array, dessen erster Wert die Listenlänge angibt (counted array).
var talon=new Array()
talon[0]=0()
(statt etlichen pop
s)// -- Talon mit 52 Karten generieren: zmax=52; // Patience mit 52 Karten var talon=new Array(); tliste[0]=zmax; for (i=0; i<tliste[0]; i++) tliste[i+1]=i; function in_liste(nr,liste) { var i,k=0; if (liste[0]>0) for (i=1; i<=liste[0]; i++) if (liste[i]==nr) k=i; return k; } function add_liste(nr,liste) { if (in_liste(nr,liste)<1) { liste[0]++; liste[liste[0]]=nr; } } function sub_liste(nr,liste) { var k=in_liste(nr,liste); if (k>0) { liste[k]=liste[liste[0]]; liste[0]--; } }
Als weiteres brauchen wir 4 Ablagen und 8 Kartenreihen, jede Ablage und Reihe wieder eine Liste mit den Kennziffern der darin befindlichen Karten, aufgebaut nach demselben Schema wie der Talon. Diesmal wird die Liste nicht "händisch" erzeugt, sondern wir basteln eine Funktion, die so ein Listen-Array erstellt und den ersten Wert auf 0 setzt. Diese Function lassen wir auf alle 4 Stacks los und alle 8 Reihen:
smax=4; // 4 Ablagen rmax=8; // 8 Reihen var rliste=new Array(); for (i=0; i<rmax; i++) rliste[i]=gen_liste(); // Kartenreihen var sliste=new Array(); for (i=0; i<smax; i++) sliste[i]=gen_liste(); // Ablagen function gen_liste() { var f=new Array(); f[0]=0; }
Mit diesen Listen "tliste", "rliste[0]" bis "rliste[7]" und "sliste[0]" bis "sliste[3]" können wir zusammen mit den Kartenobjekten von oben den Talon, alle Reihen und Ablagen nachbauen.
zum Seitenanfang | ||
zum Seitenende |
gewaehlt
wird auf -1 gesetzt,
ein Wert, der bei der Kartenkennziffer, die von 0 bis 51 geht, nicht vorkommt.sliste[i][0]=0
.
Die Werte, die danach irgendwann mal in der Liste landeten, interessieren ab jetzt nicht die Bohne.
Bei Bedarf wird gemischt und dann ausgeteilt. - Und so sieht das Ganze aus:
function neu(flag) { var i,j,k; // Spielfeld leeren: for (i=0; i<smax; i++) sliste[i][0]=0; for (i=0; i<rmax; i++) rliste[i][0]=0; if (flag) // --- Karten mischen: --- { for (i=1; i<zmax; i++) { k=Math.floor(zmax*Math.random())+1; j=tliste[i]; tliste[i]=tliste[k]; tliste[k]=j; } } // --- alle Karten austeilen, Asse auf Stacks, Rest in Reihen j=0; for (i=1; i<=zmax; i++) { normal(tliste[i]); if (tliste[i]%13==0) // Abfrage auf As { k=Math.floor(tliste[i]/13); // Abfrage auf Farbe add_liste(tliste[i],sliste[k]); // ab auf die Ablage } else { add_liste(tliste[i],rliste[j%rmax]); // ab auf die Reihe 0-7 j++; } } // -- Listen sind jetzt belegt, wie der Spielanfang vorgibt. // -- Jetzt alle Listen (ausser Talon diesmal) darstellen: for (i=0; i<smax; i++) zeige_stack(i); for (i=0; i<rmax; i++) zeige_reihe(i); // -- gewaehlt haben wir noch nichts gewaehlt=-1; } function zeige_reihe(nr) { if (rliste[nr][0]>0) for (var i=1; i<=rliste[nr][0]; i++) set_koords('k_'+rliste[nr][i],(xoff+nr*dx),(yoff+dy2*i),i); } function zeige_stack(nr) { for (var i=1; i<=sliste[nr][0]; i++) set_koords('k_'+sliste[nr][i],(xoff_s+nr*dx),yoff_s,i); }
Was soll die Zeile set_koords('k_'+rliste[nr][i],(xoff+nr*dx),(yoff+dy2*i),i)
?
Die Karte mit der Id ":k_xx" soll auf die Koordinate xoff plus irgendwas, yoff plus irgendwas, i.-te
Schicht von unten geschoben werden.
Ja und? set_koords()
gibt es in Javascript nicht, in keinem der DOMs.
Na und? Der Informatiker sagte damals noch was: "Wenn es was nicht gibt, muss man es sich programmieren!" -
Recht hat er, der Mann. Und schon sind wir in Teil 2 des traurigen Kapitels der Browser-Kompatibilität!
zum Seitenanfang | ||
zum Seitenende |
Wir brauchen eine Funktion, die die Karten verschiebt, eine weitere, die deren Koordinaten ausliest, und eine dritte, die das Bild im Layer ändert. Und da sage ich nur: 3 Browser, 4 DOMs :-(
DOM-Type | Zugriff auf Koordinaten | Zugriff auf Bilddarstellung |
---|---|---|
ie4 | document.all[Karten-Id].style.pixelLeft document.all[Karten-Id].style.pixelTop document.all[Karten-Id].style.zIndex |
document.images[Bild].src |
nn4 | document.layers[Karten-Id].left document.layers[Karten-Id].top document.layers[Karten-Id].zIndex |
document.layers[Karten-Id]. document.images[Bild].src; (alles in 1 Zeile) |
nn5 |
document.getElementById(Karten-Id).style.left document.getElementById(Karten-Id).style.top document.getElementById(Karten-Id).style.zIndex |
document.images[Bild].src |
neuestes W3C: |
document.getElementById(Karten-Id).style.left document.getElementById(Karten-Id).style.top document.getElementById(Karten-Id).style.zIndex |
document.getElementById(Bild). setAttribute('src',bilddaten) (alles in 1 Zeile) |
Und so sieht dann der 2.Teil der Crossbrowser-Bibliothek aus:
var xyz=new Array(); function set_bild(lay,bild,datei) { if (my_browser=='ie4') document.images[bild].src=datei; else if (my_browser=='nn4') document.layers[lay].document.images[bild].src=datei; else if (my_browser=='nn5') document.images[bild].src=datei; // Mozilla >0.9 else document.getElementById(bild).setAttribute('src',datei); } function set_koords(lay,x,y,z) { if (my_browser=='ie4') { with (document.all[lay].style) { pixelLeft=x; pixelTop=y; zIndex=z; } } else if (my_browser=='nn4') { document.layers[lay].left=x; document.layers[lay].top=y; document.layers[lay].zIndex=z; } else { with (document.getElementById(lay).style) { left=x; top=y; zIndex=z; } } } function get_koords(lay) { var x,y,z; if (my_browser=='ie4') { with (document.all[lay].style) { x=pixelLeft; y=pixelTop; z=zIndex; } } else if (my_browser=='nn4') { x=document.layers[lay].left; y=document.layers[lay].top; z=document.layers[lay].zIndex; } else { with (document.getElementById(lay).style) { x=left; y=top; z=zIndex; } } xyz[0]=parseInt(x); xyz[1]=parseInt(y); xyz[2]=parseInt(z); }
zum Seitenanfang | ||
zum Seitenende |
Die Karten sollten jetzt ausgebreitet auf dem Bildschirm liegen, jetzt kann es (fast) losgehen: erster Klick auf eine Karte in den Reihen: Karte zum Bewegen markieren, zweiter Klick auf eine der Listen oder auf einen Reihen-Platzhalter: Karte dort ablegen.
Beim ersten Klick ist die globale Variable gewaehlt<0
, ist der Zug erlaubt, d.h. es wurde
die letzte Karte in einer der Reihen gewählt, erhält sie die Kennziffer der Karte. Zweckmäßigerweise merkt man sich
auch die Reihennummer. Nun kann man aber auch auf irgendeine Karte in den Reihen klicken, es wird die letzte
Karte der Reihe ermittelt und gewählt.
function klick(nr) { var i,j,k; get_koords('k_'+nr); // Koordinaten ermitteln if (gewaehlt<0) { if (xyz[1]>=yoff) // Karte stammt aus Reihe { x_alt=Math.floor((xyz[0]-xoff)/dx); // Reihennr. gewaehlt=rliste[x_alt][rliste[x_alt][0]]; // letzte Karte in Reihe hilite(gewaehlt); // Merker setzen } } else { // ... der Teil für den 2.Klick } }
Dank der Crossbrowser-Bibliothek sind hilite(nr)
und normal(nr)
nur Einzeiler und
werden hier zwischengeschoben:
function hilite(nr) { set_bild('k_'+nr,'k'+nr,ima_ca[nr].src); } function normal(nr) { set_bild('k_'+nr,'k'+nr,ima_c[nr].src); }
Beim 2.Klick, also, wenn bereits eine Karte gewählt ist, wird das Ziel ermittelt, entweder eine Ablage oder eine Reihe.
Die Marke wird wieder gelöscht, es wird gecheckt, ob die Karte passt, dann der Zug ausgeführt,
gewaehlt
wieder auf -1 gesetzt, das war's! Beim Ausführen des Zuges wird die gewählte Karte
ihrer Reihe entnommen und der neuen Reihe oder Ablage zugefügt, wie im richtigen Leben!
// ... der Teil für den 2.Klick if (xyz[1]<yoff) // Reihe x_alt auf Stack (y<yoff) { j=Math.floor(gewaehlt/13); // Ermitteln des Stacks = Farbe der Karte k=gewaehlt%13; // Kartenwert ermitteln i=sliste[j][sliste[j][0]]%13; // letzter Kartenwert im Stack if ((k-i)==1) // Kartenwert um 1 größer als letzte Stackkarte { sub_liste(gewaehlt,rliste[x_alt]); // Karte verschwindet aus der Reihe add_liste(gewaehlt,sliste[j]); // und taucht auf der Ablage wieder auf // Koordinaten der Karte aktualisieren: set_koords('k_'+gewaehlt,(xoff_s+j*dx),yoff_s,sliste[j][0]); } } else // von Reihe x_alt nach neuer Reihe (y>=yoff) { j=Math.floor((xyz[0]-xoff)/dx); // neue Reihe bestimmen k=gewaehlt%13; // Wert der gewählten Karte i=rliste[j][rliste[j][0]]%13; // Wert der letzten Karte der neien Reihe if ((i-k)==1) // Kartenwert der anzulegenden Karte muss 1 kleiner sein { sub_liste(gewaehlt,rliste[x_alt]); // Karte verschwindet aus der alten Reihe add_liste(gewaehlt,rliste[j]); // und taucht in der neuen wieder auf // Koordinaten der Karte aktualisieren: set_koords('k_'+gewaehlt,(xoff+j*dx),(yoff+dy2*rliste[j][0]),rliste[j][0]); } } // Auswahl zurücksetzen: normal(gewaehlt); gewaehlt=-1;
Was bleibt noch zu tun? Gewählte Karte hochlegen, ausgelöst durch reihe_hoch(nr)
,
die Funktion, mit der wir die Platzhalter ausgestattet haben:
function reihe_hoch(nr) { if (gewaehlt>-1) { sub_liste(gewaehlt,rliste[x_alt]); // Karte verschwindet aus der alten Reihe add_liste(gewaehlt,rliste[nr]); // und taucht in der neuen wieder auf // Koordinaten der Karte aktualisieren: set_koords('k_'+gewaehlt,(xoff+nr*dx),(yoff+dy2),rliste[nr][0]); // Auswahl zurücksetzen: normal(gewaehlt); gewaehlt=-1; } }
Damit kann man die Patience "Belagerung" jetzt spielen. Man sollte dem Benutzer aber noch ein paar nette Kleinigkeiten gönnen. Da wäre erstens ein Hilfe-Bildschirm, in dem die Patience erklärt wird, und zweitens eine Automatik, die zu Ende spielt, wenn klar ist, dass die Patience aufgeht.
zum Seitenanfang | ||
zum Seitenende |
Die Function zum Einlesen des Hilfetextes sieht folgendermaßen aus:
function hilfe() { var win2=window.open('hilfe.htm','popup','width=560,height=360,scrollbars=auto'); }
Dies öffnet das Dokument hilfe.htm im Zielfenster namens popup, welches mit der Größe 560x360 initialisiert wird. Das Hilfedokument oder andere Popup-Fenster wie Bestenliste sollten im Body-Tag onload="this.focus()" enthalten, denn wenn das Zielfenster schon existiert, bleibt es sonst da, wo es ist, oft verborgen im Hintergrund. Denn Zocker zocken nicht nur eine Runde!
Wichtig an diesem Teil ist, dass es sklavisch genauso hingeschrieben wird, wie es da steht. Ein Leerzeichen vor den Kommata oder danach, und die Größenangabe wird ignoriert.
Warum hier der Weg über Javascript? Warum kein ordinärer Link?
Das Hilfefenster sieht ohne Toolbar einfach schicker aus, verdeckt nicht den ganzen Schirm,
und durch Hin- und Herschieben hat man Hilfetext und Spielfeldlayout zusammen im Blickfeld.
Und hier noch die "Abräum-Automatik": sie checkt die untersten Karten der Reihen, ob sie auf eine Ablage passen. Falls ja, wird die Karte dahin geschoben und die Reihen nochmal durchsucht.
function abraeumen() { var i,j,k,weiter=true; if (gewaehlt>-1) { normal(gewaehlt); gewaehlt=-1; } // Marke löschen while(weiter) { weiter=false; for (i=0; i<rmax; i++) if (rliste[i][0]>0) // von allen 8 Reihen { k=rliste[i][rliste[i][0]]; // die unterste Karte checken j=Math.floor(k/13); // deren Farbe if ((k-sliste[j][sliste[j][0]])==1) // Kenn muss 1 höher sein als auf Ablage { weiter=true; sub_liste(k,rliste[i]); // das Verschiebe-Triplett add_liste(k,sliste[j]); set_koords('k_'+k,(xoff_s+j*dx),yoff_s,sliste[j][0]); } } } }
zum Seitenanfang | ||
zum Seitenende |