Brauche Hilfe mit Schulprojekt
lenny099
- html
- javascript
- programmiertechnik
Hey, ich und ein Freund von mir haben ein Problem mit unserem Schulprojekt und wir finden die Lösung einfach nicht. Wir programmieren in der Schule ein Memory wir sind fast fertig aber uns fehlt die Überprüfung ob zwei Karten gleich sind. Wir wollen das mit den Variablen 'Bild1' und 'Bild2' machen kriegen es aber nicht hin da Bild1 irgendwie wieder glöscht wird. Wir würden uns für jede Hilfe freuen
<html>
<head>
<title>Erstes Spiel!</title>
</head>
<script>
var k = 0;
var bild1;
var bild2;
var paar1, paar2;
var hit = 0;
var back = "lol.png";
var r1;
var r2;
var temp;
var timer;
var i;
var kartenArray = ["kat.jpg", "kat.jpg", "teemo.jpg", "teemo.jpg", "blitz.jpg", "blitz.jpg", "yi.jpg", "yi.jpg", "garen.jpg", "garen.jpg", "yasuo.jpg", "yasuo.jpg",
"vel.jpg", "vel.jpg", "annie.jpg", "annie.jpg"];
for (var s = 0; s < 1010; s = s + 1) { // Hier wird gemischt
r1 = parseInt(Math.random() * 8) + 1;
r2 = parseInt(Math.random() * 8) + 1;
temp = kartenArray[r1 - 1];
kartenArray[r1 - 1] = kartenArray[r2 - 1];
kartenArray[r2 - 1] = temp;
}
function choose(i) { // K überprüft wie oft ein Bild angeklickt wurde.i speichert das Bild und den Pfad, welches angeklickt wurde.
if (k < 2) {
if (k == 0) {
var bild1 = i;
var paar1 = kartenArray[i - 1];
alert('erste Prüfung')
alert(bild1);
alert(bild2);
alert(i);
} else { //Wenn K nicht 0 ist wird das zweite Bild gespeichert und der Pfad
var bild2 = i;
var paar2 = kartenArray[i - 1];
alert('zweitePrüfung')
alert(bild1);
alert(bild2);
alert(i);
}
k++;
document.images[i-1].src = kartenArray[i-1];
prompt(paar1, paar2);
if (k == 2) { //Wenn K gleich 2 ist dann sollte eigentlich übprüft werden ob die gleichen Karten angeklickt wurden.
alert('dritte Prüfung')
alert(bild1);
alert(bild2);
alert(i);
if (kartenArray[bild1] == kartenArray[bild2]){
alert('jaaaaaaa');
} else {
alert('neeeeeeeeeein');
k = 0;
}
}
}
}
function zurueckdrehen(b, c) { //Hier sollen die karten zurückgedreht werden wenn sie nicht ein Paar sind.
document.images[b - 1].src = "lol.png";
document.images[c - 1].src = "lol.png";
k = 0;
}
</script>
<body background="hintergrund.jpg">
<h1 id="1"></h1>
<br><br>
<table align=center valign=middle border="3">
<tr>
<td> <img src="Lol.png" height="180" width="180" onclick="choose(1)">
</td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(2)">
</td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(3)">
</td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(4)">
</td>
</tr>
<tr>
<td> <img src="Lol.png" height="180" width="180" onclick="choose(5)">
</td>
<td> <img src="Lol.png" height="180" width="180" onclick="choose(6)">
</td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(7)">
</td>
<td> <img src="Lol.png" height="180" width="180" onclick="choose(8)">
</tr>
<tr>
<td><img src="Lol.png" height="180" width="180" onclick="choose(9)"></td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(10)"></td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(11)"></td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(12)"></td>
</tr>
<tr>
<td><img src="Lol.png" height="180" width="180" onclick="choose(13)"></td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(14)"></td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(15)"></td>
<td><img src="Lol.png" height="180" width="180" onclick="choose(16)"></td>
</tr>
</table>
</body>
</html>
@@lenny099
Wir würden uns für jede Hilfe freuen
Damit man überhaupt helfen kann: Online-Beispiel, bitte.
Aus den ersten Blick lässt sich sagen: Da fehlt ein bisschen bei der Grundstruktur.
<img src="Lol.png" height="180" width="180" onclick="choose(…)">
funktioniert nicht. Zum einen wegen fehlender Alternativtexte.
Zum anderen sind img
-Elemente allgemein nicht clickbar. Damit die Bilder auch per Tastatur clickbar sind, die img
jeweis in einen button
tun:
<td>
<button onclick="choose(…)">
<img src="Lol.png" alt="Rückseite">
</button>
</td>
Dem button
kannst du mit CSS Rahmen und Hintergrund wegnehmen:
button
{
padding: 0;
background: transparent;
border: none;
}
(Eine andere Möglichkeit wäre, button
neben dem img
im td
und per CSS über die gesamte Fläche des Bilds zu legen – wäre etwas aufwendiger.)
Eine andere Überlegung wäre, keine Tabelle zu verwenden, sondern eine Liste, und die Bilder mit CSS Grid plazieren.
LLAP 🖖
Lieber Gunnar,
Zum anderen sind
img
-Elemente allgemein nicht clickbar. Damit die Bilder auch per Tastatur clickbar sind, dieimg
jeweis in einenbutton
tun:
leider habe ich dafür auf die Schnelle keinen Wettgegner gefunden...
Liebe Grüße,
Felix Riesterer.
@@Felix Riesterer
Lieber Gunnar,
Zum anderen sind
img
-Elemente allgemein nicht clickbar. Damit die Bilder auch per Tastatur clickbar sind, dieimg
jeweis in einenbutton
tun:leider habe ich dafür auf die Schnelle keinen Wettgegner gefunden...
Hach, ich wünschte, ich könnte dich deine Wetten verlieren lassen und müsste das nicht immer wieder sagen …
LLAP 🖖
Hallo,
Hach, ich wünschte, ich könnte dich deine Wetten verlieren lassen und müsste das nicht immer wieder sagen …
Kann da nicht mal jemand einen Gunnar-Bot schreiben?
Gruß
Kalk
Lieber Tabellenkalk,
Kann da nicht mal jemand einen Gunnar-Bot schreiben?
den nennen wir dann lieber anders. Wie fändest Du ARIA-Monster?
Liebe Grüße,
Felix Riesterer.
Hi,
Kann da nicht mal jemand einen Gunnar-Bot schreiben?
Ist Gunnar etwa gar kein Bot?
cu,
Andreas a/k/a MudGuard
Hallo,
Ist Gunnar etwa gar kein Bot?
Lässt du Subbotnik gelten?
Gruß
Kalk
@@Gunnar Bittersmann
<td> <button onclick="choose(…)"> <img src="Lol.png" alt="Rückseite"> </button> </td>
An der Stelle habe ich schon mal die width
- und height
-Attribute weggelassen. Wenn die für alle Bilder gleich sind, kann man das auch mit einer Angabe im CSS für alle Bilder auf einmal haben – wenn man die Bilder denn überhaupt skalieren möchte.
width
- und height
-Attribute können helfen, das Seitenlayout gleich initial so zu rendern, dass der Platz für die (noch nicht geladenen) Bilder freigehalten wird. Das ist hier nicht erforderlich, denke ich.
Im nächsten Schritt wäre auch noch das onclick
-Attribut wegzulassen und der Eventhandler im JavaScript zu registrieren (addEventListener
, siehe molily). Am besten nicht für jeden Button einzeln, sondern per event delegation.
LLAP 🖖
Moin lenny099,
deine Variablen …
var bild1; var bild2; var paar1, paar2;
… werden hier …
var bild1 = i; var paar1 = kartenArray[i - 1];
… und hier lokal „überschrieben“:
var bild2 = i; var paar2 = kartenArray[i - 1];
Viele Grüße
Robert
(Edit: Verflixt, zu langsam 😉)
Hallo lenny099,
guckt mal, wo ihr die Variablen bild1 und bild2 überall deklariert. Und hört dabei nicht bei 1 mit Zählen auf...
JavaScript verwendet immer die nächstliegende Deklaration einer Variablen.
Rolf
Hallo lenny099,
euer Memory ist als erstes Lernprogramm eine schöne Idee. Ich möchte noch ein paar Tipps beisteuern, wie ihr euren Code verbessern könnt.
Arrayzugriffe. Array-Indexe beginnen in Javascript bei 0. Es ist daher eigentlich ganz sinnvoll, wenn man den Rest des Programms auf dieser Vorgabe aufbaut, und nicht bei jedem Zugriff 1 subtrahiert. Das bedeutet in euerem Spielfeld dann auch, im click-Handler eine um 1 kleinere Zahl an choose zu übergeben.
Mischen der Karten. Einfach tausend mal zwei beliebige Karten vertauschen ist eine Möglichkeit. Bei 64 Karten (Standard-Memory) wird das aber nicht reichen. Eine bessere Idee ist es, wenn ihr Karten aus einer zufälligen Position aus dem Array "zieht"
var eingabeStapel = [ "kat.jpg", "kat.jpg", "teemo.jpg", "teemo.jpg", "blitz.jpg", "blitz.jpg", "yi.jpg", "yi.jpg", "garen.jpg", "garen.jpg", "yasuo.jpg", "yasuo.jpg",
"vel.jpg", "vel.jpg", "annie.jpg", "annie.jpg" ];
// Beginne mit leerem KartenArray
var kartenArray = [];
// Bei 16 Karten: Schleife von 15 bis 0
for (var i=eingabeStapel.length-1; i>= 0; i--) {
// Zufallszahl von 0 bis i
var p = parseInt(Math.random() * i);
// Ermittelte Karte ans kartenArray anhängen
kartenArray.push(eingabeStapel[p]);
// gezogene Karte durch letzte Karte im eingabeStapel überschreiben
eingabeStapel[p] = eingabeStapel[i];
}
Auf diese Weise bekommt ihr auch eine Zufallsverteilung, braucht aber nur so viele Durchläufe wie ihr Karten habt. Der letzte Schritt in der Schleife, wo die wegkopierte Karte durch die letzte Karte des Eingabestapels überschrieben wird, löst das Problem dass es in JavaScript keine Funktion gibt, die mitten in einem Array einen Eintrag entfernt und die folgenden Einträge umnummeriert. Sowas kann man zwar nachbauen, das wäre aber langsam. Das Kopieren des letzten Eintrags füllt die entstandene Lücke ebenfalls, und weil i pro Durchlauf um 1 kleiner wird, wird der letzte Eintrag in den folgenden Durchläufen nicht mehr verwendet.
var spielfeld = document.getElementById("spielfeld");
var memoryBilder = spielfeld.querySelectorAll("img");
// Man kann das auch zu einer Zeile zusammenfassen:
var memoryBilder = document.getElementById("spielfeld").querySelectorAll("img");
querySelectorAll ist eine Funktion, die CSS Selektoren verwendet um HTML Elemente zu finden. "img" ist ein Selektor, der img-Elemente findet. Weil querySelectorAll auf dem Spielfeld-Element aufgerufen wird, sucht die Funktion nur die Bilder im Spielfeld.
Rolf
@@Rolf B
- Mischen der Karten. Einfach tausend mal zwei beliebige Karten vertauschen ist eine Möglichkeit.
Eine andere ist ein Einzeiler (von CSS Tricks: Shuffle array):
kartenArray.sort(function () { return 0.5 - Math.random() });
Mit arrow function sieht’s so aus:
kartenArray.sort(() => 0.5 - Math.random());
Oder Fisher–Yates Shuffle (s.a. Wikipedia, Stack Overflow)
Mischt eigentlich beides gleich gut?
Edit Rolf B, 18.08.2021: Gunnar möchte seinen Vorschlag zurückziehen und findet ihn nicht mehr gut. Diskussion hier.
querySelectorAll ist eine Funktion, die CSS Selektoren verwendet
Eben, Selektoren werden nicht nur in CSS verwendet, sondern auch anderswo, bspw. in JavaScript. Deshalb heißen sie besser „Selektoren“ (ohne CSS). Damit hätte sich auch das Problem des Deppenleerzeichens erledigt.
LLAP 🖖
Lieber lenny099,
ich und ein Freund von mir
Stil: Der Esel nennt sich immer zuerst.
haben ein Problem mit unserem Schulprojekt
Für ein Schulprojekt seid ihr in einer recht komplexen Sache unterwegs. Gut so!
Wir programmieren in der Schule ein Memory wir sind fast fertig
Ich habe für mein Memory-Spiel einen anderen Ansatz gewählt, damit ich das Script so oft einsetzen kann, wie ich will. Ihr müsstet jeweils das JavaScript umschreiben, wenn ihr andere Karten einsetzen wollt. Und mehrere Memory-Spiele auf einer Seite sind mit eurem Ansatz auch nicht möglich. Dazu bräuchte man das ganze Spiel als beliebig oft instantiierbares Objekt.
Liebe Grüße,
Felix Riesterer.
@@lenny099
var kartenArray = ["kat.jpg", "kat.jpg", "teemo.jpg", "teemo.jpg", "blitz.jpg", "blitz.jpg", "yi.jpg", "yi.jpg", "garen.jpg", "garen.jpg", "yasuo.jpg", "yasuo.jpg", "vel.jpg", "vel.jpg", "annie.jpg", "annie.jpg"];
Nicht die beste Idee, alle Karten doppelt aufzuschreiben. Die Arbeit kann man dem Computer überlassen, der kann das besser und vergisst nicht aus Versehen mal eine.
var bilderArray = ["kat.jpg", "teemo.jpg", "blitz.jpg", "yi.jpg", "garen.jpg", "yasuo.jpg", "vel.jpg", "annie.jpg"];
var kartenArray = bilderArray.concat(bilderArray);
hängt alle Elemente von bilderArray
nochmals an bilderArray
an und speichert das (dann doppelt so große) Array als kartenArray
. (Man kann natürlich auch dieselbe Variable wiederverwenden, wenn man das ursprüngliche Array nicht mehr braucht.)
Und in dem Array kann man auch die Alternativtexte für die Bilder mit unterbringen:
var bilderArray = [
{
src: "kat.jpg",
alt: "Kat"
},
{
src: "teemo.jpg",
alt: "Teemo"
},
⋮
];
LLAP 🖖