jQuery Memory Spiel

Da mich schon lange Interessiert hat, ob es möglich ist ein kleines Memory Spiel mit jQuery zu erstellen, werde ich es jetzt mal versuchen zu programmieren. Die Schritte zum Erfolg möchte ich euch gern Beschreiben.

Was brauchen wir, eine Box in der unsere Bildchen angezeigt werden und eine Ergebniszeile. Die Bilder lesen wir mit jQuery aus dem Ordner "memory_spiel" aus, damit niemand auf die Idee kommt, anhand vom Quellcode schneller zum Ziel zu gelangen.

Du hast 0 Gleiche in 0 Sekunden gefunden und 0 Bilder aufgedeckt. Neu mischen
<div class="memory_spiel" data-ordner="pfad/zu/images/memory_spiel">
	<div class="memory_spiel_bilder"></div>
	<div class="memory_spiel_ergebnis">
		Du hast <span class="memory_spiel_gleiche">0</span> Gleiche in <span class="memory_spiel_zeit">0</span> Sekunden gefunden und <span class="memory_spiel_aufgedeckt">0</span> Bilder aufgedeckt.
		<a class="memory_neu_mischen">Neu mischen</a>
	</div>
</div>

Es sieht so aus, als wäre das Auslesen mit JavaScript allein nicht möglich, mein Idee ist, dass mit Ajax zu realisieren. Falls jemand ein kleines, schnelleres JavaScript kennt, bitte als Kommentar posten.

Für die Übergabe des richtigen Verzeichnisses, in dem unsere Bilder liegen, nutzen wir das Attribut "data-ordner" in der "memory_spiel" Box. So können wir mehrere Memory Soiele auf einer Seiter nutzen.

Die Idee, die Bilder mit Ajax auszulesen, war gar nicht so schlecht, in der Datei "memory_spiel.ajax.php" stell ich alle Bilderboxen, durcheinander zusammen und hole diese mit einem JavaScript in mein Dokument.

memory_spiel.ajax.php

<?php class MemorySpielAjax
{	
	public function getBilder()
	{
		$root = $_SERVER['DOCUMENT_ROOT'];
		$memory_spiel_bilder = $_GET['ordner']; // $_GET bitte Filtern
		if(is_dir($root.$memory_spiel_bilder))
		{
			$bilder = array();
			$bilder_zwei = array();
			$scan_ordner = scandir($root.$memory_spiel_bilder);
			foreach($scan_ordner as $bild)
			{
				if($bild != '.' && $bild != '..' && strpos($bild, '-hintergrund') === FALSE)
				{
					$bilder[] = $bild;
					$bilder_zwei[] = strstr($bild, '.', TRUE).'|2|'.strstr($bild, '.');
				}
				elseif(strpos($bild, '-hintergrund') !== FALSE)
				{
					$hintergrund = $bild;
				}
			}
			$memory_bilder = array_merge($bilder, $bilder_zwei);
			shuffle($memory_bilder);
			$memory_spiel = NULL;
			foreach($memory_bilder as $key=>$memory_bild)
			{
				$memory_spiel .= '<div class="memory_bild_outer">'."\n";
					$memory_spiel .= '<img class="memory_bild" src="/'.$memory_spiel_bilder.'/'.str_replace('|2|', '', $memory_bild).'" alt="Memory Bild'.($key + 1).'" />'."\n";
					$memory_spiel .= '<img class="memory_hintergrund" src="/'.$memory_spiel_bilder.'/'.$hintergrund.'" data-bild="'.strstr($memory_bild, '.', TRUE).'" alt="Memory Hintergrund" />'."\n";
				$memory_spiel .= '</div>'."\n";
			}
			return $memory_spiel;
		} else {
			return 'Das angegebene Verzeichnis existiert nicht.';
		}
	}
}
$memory_spiel = new MemorySpielAjax();
$images = $memory_spiel->getBilder();
if(!empty($images)) echo $images; ?>

Mit Ajax lesen wir den angegebenen Ordner aus und filtern die Bilder aus, alle außer "-hintergrund" fügen wir dem Array $bilder und $bilder_zwei hinzu. Beide Arrays verbinden wir mit der Funktion "array_merge" zu einem.

Mit "shuffle" verändern wir die Reihenfolge des Bilder Arrays. Jetzt haben wir ein Array, welches in einer "foreach" Schleife durchläuft und unsere Ausgabe zusammenstellt. Dabei bekommt jedes Bild eine Box "memory_bild_outer", diese beinhaltet das Bild und den Hintergrund.

memory_spiel.js

jQuery(document).ready(function() {
	jQuery(".memory_spiel").each(function() {
		var this_memory = jQuery(this);
		var this_memory_spiel = jQuery(this).find(".memory_spiel_bilder");
		var memory_spiel_bilder = jQuery(this).data("ordner");
		getBilder(this_memory, this_memory_spiel, memory_spiel_bilder);
		this_memory.find(".memory_neu_mischen").click(function() {
			getBilder(this_memory, this_memory_spiel, memory_spiel_bilder);
			this_memory.find(".memory_spiel_gleiche").text("0");
			this_memory.find(".memory_spiel_zeit").text("0");
			this_memory.find(".memory_spiel_aufgedeckt").text("0");
		});
	});
});
function getBilder(this_memory, this_memory_spiel, memory_spiel_bilder) {
	jQuery.ajax({
		type: "GET",
		cache: false,
		url: "/jquery_memory_spiel/memory_spiel.ajax.php",
		data: {
			ordner: memory_spiel_bilder
		},
		success: function(data) {
			this_memory_spiel.html(data);
			var gleiche = 0;
			var aufgedeckt = 0;
			this_memory_spiel.find(".memory_bild_outer").each(function() {
				jQuery(this).find(".memory_hintergrund").click(function() {
					jQuery(this).fadeOut(100, function() {
						jQuery(this).prev(".memory_bild").fadeIn(100);
					});
					jQuery(".memory_spiel_aufgedeckt").text(++aufgedeckt);
					if(this_memory_spiel.data("bild1") !== undefined && this_memory_spiel.data("bild2") !== undefined  && this_memory_spiel.data("bild3") === undefined) {
						this_memory_spiel.data("bild3", this_memory_spiel.data("bild1"));
						this_memory_spiel.data("bild1", jQuery(this).data("bild"));
					}
					if(this_memory_spiel.data("bild1") !== undefined && this_memory_spiel.data("bild2") === undefined) {
						this_memory_spiel.data("bild2", jQuery(this).data("bild"));
					}
					if(this_memory_spiel.data("bild1") === undefined) {
						this_memory_spiel.data("bild1", jQuery(this).data("bild"));
					}
					if(this_memory_spiel.data("bild1") !== undefined && this_memory_spiel.data("bild2") !== undefined  && this_memory_spiel.data("bild3") !== undefined) {
						this_memory_spiel.find("img[data-bild='"+this_memory_spiel.data("bild2")+"']").prev(".memory_bild").fadeOut(100);
						this_memory_spiel.find("img[data-bild='"+this_memory_spiel.data("bild2")+"']").fadeIn(100);
						this_memory_spiel.find("img[data-bild='"+this_memory_spiel.data("bild3")+"']").prev(".memory_bild").fadeOut(100);
						this_memory_spiel.find("img[data-bild='"+this_memory_spiel.data("bild3")+"']").fadeIn(100);
						this_memory_spiel.removeData("bild2").removeData("bild3");
					}
					if(this_memory_spiel.data("bild1") !== undefined && this_memory_spiel.data("bild2") !== undefined  && this_memory_spiel.data("bild3") === undefined) {
						if(this_memory_spiel.data("bild1").replace("|2|", "") != this_memory_spiel.data("bild2").replace("|2|", "")) {
							var timer = setTimeout(function() {
								if(this_memory_spiel.data("bild1") !== undefined && this_memory_spiel.data("bild2") !== undefined  && this_memory_spiel.data("bild3") === undefined) {
									this_memory_spiel.find("img[data-bild='"+this_memory_spiel.data("bild1")+"']").prev(".memory_bild").fadeOut(100);
									this_memory_spiel.find("img[data-bild='"+this_memory_spiel.data("bild1")+"']").fadeIn(100);
									this_memory_spiel.find("img[data-bild='"+this_memory_spiel.data("bild2")+"']").prev(".memory_bild").fadeOut(100);
									this_memory_spiel.find("img[data-bild='"+this_memory_spiel.data("bild2")+"']").fadeIn(100);
									this_memory_spiel.removeData("bild1").removeData("bild2");
								}
							}, 3000);
						} else {
							clearTimeout(timer);
							jQuery(".memory_spiel_gleiche").text(++gleiche);
							if(this_memory_spiel.data("bild1") !== undefined && this_memory_spiel.data("bild2") !== undefined  && this_memory_spiel.data("bild3") === undefined) {
								this_memory_spiel.removeData("bild1").removeData("bild2");
							}
						}
					}
				});
			});
			var interval = false;
			this_memory_spiel.find(".memory_bild_outer").find(".memory_hintergrund").click(function() {
				if(interval == false) {
					interval = setInterval(function() {
						jQuery(".memory_spiel_zeit").text(parseInt(jQuery(".memory_spiel_zeit").text()) + 1);
					}, 1000);
				}
				if(jQuery(".memory_spiel_gleiche").text() == (this_memory_spiel.children(".memory_bild_outer").size() / 2)) {
					clearInterval(interval);
				}
			});
			this_memory.find(".memory_neu_mischen").click(function() {
				clearInterval(interval);
			});
			//console.log(this_memory_spiel.data("bild1")+" "+this_memory_spiel.data("bild2")+" "+this_memory_spiel.data("bild3"));
		}
	});
}

Mit unserem JavaScript fragen wir ab, wie viele Memory Spiele "class=memory_spiel" auf einer Seite existieren, eigentlich sollten pro Seite mehrere Spiele möglich sein, aber das habe ich nicht getestet.

Beim Start wird unser Memory Spiel mit Karten gefüllt, damit wir die Möglichkeit haben neu zu mischen, erstellen wir eine Funktion "getBilder", welche beim Start und auch bei neu mischen aufgerufen wird.

Die Funktion arbeitet mit Ajax und holt uns den fertigen html Code, im Hintergrund, aus der "memory_spiel.ajax.php". Das Ergebnis laden wir in den Container "memory_spiel". Da wir das Bild und den Hintergrund in einer Bilderbox haben, legen wir bei in einen anderen z-index und absolut zu "memory_bild_outer", das Bild blenden wir mit css aus, so dass nur der Hintergrund sichtbar ist.

Jetzt suchen wir alle Bilderboxen und beim Klick darauf, blenden wir den Hintergrund aus und das Bild darunter ein. Gleichzeitig geben wir unserer Memory Spiel Box Datas, diese habe ich in der ajax.php dem Hintergrundbild mitgegeben. "data-bild" ist der Name des Bildes ohne ".endung", ist das Bild eines aus dem Array "bilder_zwei" hänge ich dafür eine Identifizierung "|2|" an.

Bei jedem Klick auf einen Hintergrund, speichern wir uns "data-bild1", "data-bild2" und "data-bild3" ab, so zählen wir die aufgedeckten Karten mit und können gleichzeitig vergleichen. Ist jetzt "data-bild1" gleich "data-bild2" bleiben diese Karten offen und alle "data-bild" angaben werden gelöscht. Sind beide Karten ungleich, werden diese nach einer Bestimmten Zeit wieder verdeckt, da ich selbst aber sehr schnell klicke, war mir die Wartezeit zu lang.

Deshalb habe ich "data-bild3" als Angabe hinzugefügt, klickt man das dritte Bild an, werden die beiden ersten Bilder wieder versteckt und gleichzeitig wird das dritte Bild "data-bild1" zugewiesen. Jetzt kommt die Identifizierung ins Spiel, beim Vergleichen der Karten, hat sich manchmal Bild drei mit geschlossen, wenn es gleich mit Bild eins oder zwei war. Zum Vergleichen von "data-bild1" und "data-bild2" entferne ich die Identifizierung.

Gleichzeitig mit dem ersten Klick starten wir unseren Sekundenzähler und erweitern mit "interval = 1000ms" den letzten Wert um eins und übergeben den Wert an "memory_spiel_zeit". Alle Klicks zählen wir mit "++aufgedeckt" und übergeben an "memory_spiel_aufgedeckt". Das Selbe machen wir mit den gleichen Karten "++gleiche", immer wenn es Übereinstimmungen gibt erhöhen wir um eins und übergeben an "memory_spiel_gleiche", haben wir alle Gleichen aufgedeckt, stoppen wir den Sekundenzähler und freuen uns.

memory_spiel.css

.memory_spiel {
	display: block;
	margin: 0px auto 0px auto;
	padding: 0px;
	width: 625px;
	height: 500px;
	background-color: #fff;
	border: 10px solid #eaeaea;
	box-shadow: 0px 0px 10px #000;
}
.memory_spiel .memory_spiel_bilder {
	display: block;
	margin: 0px;
	padding: 5px 0 0 5px;
	width: 620px;
	height: 465px;
}
.memory_spiel .memory_spiel_bilder .memory_bild_outer {
	float: left;
	margin: 0 4px 4px 0;
	padding: 0px;
	width: 150px;
	height: 150px;
	border-right: 1px solid #666;
	border-bottom: 1px solid #666;
	position: relative;
}
.memory_spiel .memory_spiel_bilder .memory_bild_outer .memory_bild,
.memory_spiel .memory_spiel_bilder .memory_bild_outer .memory_hintergrund {
	display: none;
	margin: 0px;
	padding: 0px;
	width: 150px;
	height: 150px;
	border: none;
	position: absolute;
	z-index: 1;
	top: 0px;
	left: 0px;
}
.memory_spiel .memory_spiel_bilder .memory_bild_outer .memory_hintergrund {
	display: block;
	cursor: pointer;
	z-index: 2;
}
.memory_spiel .memory_spiel_ergebnis {
	display: block;
	margin: 0px;
	padding: 10px 5px 0 5px;
	width: 615px;
	line-height: 20px;
	background-color: #eaeaea;
	color: #a4a4a4;
	font-size: 15px;
	text-shadow: 1px 1px 1px #fff;
}

Mit css machen wir noch alles schön. Die Menge der Bilder sollte unendlich sein, es muss bei mehr Bildern nur die css angepasst werden. Hier ist der Download jquery_memory_spiel.zip, viel Spaß damit, sollte es Verbesserungen geben bitte posten.

Kommentare

Geschrieben von sebastian

01.03.2015 12:19
neuer test

Geschrieben von sebastian

01.03.2015 12:18
test
Kommentare können nur mit einer Verifizierten E-Mail-Adresse geschrieben werden, die E-Mail-Adresse muss einmal bestätigt werden.
@
(success)