Forty in 49: Ein Spiel für Gedächtnis und räumliches Vorstellungsvermögen

Beitragsbild forty in 49 - ein Spiel für das Gedächtnis und das räumliche Vorstellungsvermögen

Autor: Jannis Fortmann

Link zum Spiel
Zip Datei zum Download

Inhalt

Konzept

Von Anfang an war es mein Plan, ein simples und optisch ansprechendes kleines Spiel zu designen, bei dem Animationen sinnvoll zum Einsatz kommen.

Nach ein paar verworfenen Ideen entschied ich mich für diese Variante, bei der die räumliche Wahrnehmung und das Gedächtnis des Spielers auf die Probe gestellt wird. Das Konzept des Spiels ist angelehnt an einen Intelligenztest für Schimpansen, bei dem deren Arbeitsgedächtnis getestet wird. Bei diesem werden aufeinanderfolgende Zahlen auf einem Bildschirm abgebildet, diese zahlen müssen dann in der richtigen Reihenfolge gedrückt werden. Nachdem die erste Zahl gedrückt wurde, werden alle anderen hinter identisch aussehenden Feldern versteckt.

Mein Spiel „forty in 49“ funktioniert nach einem ähnlichen Prinzip. Anstatt einer bestimmten Reihenfolge geht es hierbei aber um die Position der Felder. In einem Raster sind 7×7 Felder angeordnet,. Zu Beginn des Spiels verschwinden 40 der 49 Felder für wenige Sekunden. Der Spieler muss sich die Position der übrigen 9 Felder (Bomben) merken und diese vermeiden. Das Ziel ist es, möglichst viele der 40 Felder anzuklicken. Klickt man auf eine Bombe, ist das Spiel vorbei.

Animationen

Die Animationen erfüllen sowohl funktionale als visuelle Zwecke.

Um die Orientierung zu vereinfachen, werden Felder größer und ändern ihre Farbe, wenn der Mauszeiger darüber hovert. Wird ein Feld angeklickt, wird es entweder grün und verschwindet in einer rotierenden Animation, oder es wird rot und dreht sich langsam um 180° um die y-Achse und um 45° um die z-Achse. Dadurch wird dem Spieler visuell verdeutlicht, ob er richtig lag. Um das Ganze auditiv zu unterstützen, gibt es für den Klick auf die zwei Arten von Feldern jeweils einen Soundeffekt.

Ist das Spiel vorbei (alle richtigen Felder oder eine Bombe wurden geklickt), erscheint eine Karte mit der Punktzahl. Sie bewegt sich von unten nach oben und landet mittig über dem Spielfeld. Außerdem gibt es natürlich die fade-out/fade-in Animation am Anfang, ohne die das Spiel überhaupt nicht möglich wäre.

Technische Umsetzung

Die Seite wurde mithilfe von HTML, CSS und JavaScript erstellt.

HTML

In der HTML-Datei wird der Aufbau der Seite bestimmt. Alle nicht-dynamischen Inhalte werden definiert und mithilfe von DIV-Containern positioniert.

In dem DIV „wrap“ befinden sich alle anderen Objekte, es definiert den Abstand zu den Seitenrändern. Unter der Überschrift und einer kurzen Spielbeschreibung befindet sich der Start-Button und darunter der aktuelle Punktestand.

Das Spielfeld besteht aus 49 einzelnen DIVs für die kleinen, quadratischen Felder. Diese sind umschlossen von dem DIV „grid“, welches sich innerhalb des DIV „background“ befindet.

Darunter befinden sich die DIVs „gameOver“ und „finalScore“ sowie der Restart-Button. Diese Elemente bestimmen die Karte, die zum Ende des Spiels erscheint, bis dahin sind sie unsichtbar.

Jedem der 49 Spielfeld-DIVs werden drei Klassen zugeordnet. Alle bekommen die Klasse „cell“, über die alle Felder auf einmal angesprochen werden können. Außerdem bekommt jedes Feld eine individuelle Klasse (c1 bis c49) und entweder die Klasse „bomb“ oder „noBomb“. Damit können die beiden Arten von Feldern getrennt voneinander bearbeitet werden.

<!DOCTYPE html>
<html lang="en" >
  <head>
    <meta charset="UTF-8">
    <title>forty in 49</title>
    <link rel="stylesheet" href="./style.css">
  </head>
  <body>
    <div class="wrap">
      <h1>
        forty in 49
      </h1>
      <p>
        a simple game<br>
        49 tiles - 40 are good 9 are bad<br>
        press start to see the bad ones<br>
        click on all the good ones
      </p>
      <button id="start">
        start
      </button>
      <div id="score">
        score: 0
      </div>
      <div class="background">
      </div>
      <div class="gameOver">
        your final sccore is: 
        <div id="finalScore">
          0
        </div>
        <button id="restart">
          restart
        </button>
      </div>
    </div>
    <script  src="./script.js">
    </script>
  </body>
</html>
<div class="background">
   <div class="grid">
     <div class="cell c1 noBomb"></div>
     <div class="cell c2 bomb"></div>
     <div class="cell c3 noBomb"></div>
     <div class="cell c4 noBomb"></div>
     <div class="cell c5 noBomb"></div>
     <div class="cell c6 noBomb"></div>
     <div class="cell c7 noBomb"></div>
     <div class="cell c8 noBomb"></div>
     <div class="cell c9 noBomb"></div>
     <div class="cell c10 noBomb"></div>
     <div class="cell c11 bomb"></div>
     <div class="cell c12 noBomb"></div>
     <div class="cell c13 bomb"></div>
     <div class="cell c14 noBomb"></div>
     <div class="cell c15 noBomb"></div>
     <div class="cell c16 noBomb"></div>
     <div class="cell c17 noBomb"></div>
     <div class="cell c18 noBomb"></div>
     <div class="cell c19 noBomb"></div>
     <div class="cell c20 noBomb"></div>
     <div class="cell c21 noBomb"></div>
     <div class="cell c22 noBomb"></div>
     <div class="cell c23 noBomb"></div>
     <div class="cell c24 bomb"></div>
     <div class="cell c25 noBomb"></div>
     <div class="cell c26 bomb"></div>
     <div class="cell c27 noBomb"></div>
     <div class="cell c28 noBomb"></div>
     <div class="cell c29 bomb"></div>
     <div class="cell c30 noBomb"></div>
     <div class="cell c31 noBomb"></div>
     <div class="cell c32 noBomb"></div>
     <div class="cell c33 noBomb"></div>
     <div class="cell c34 bomb"></div>
     <div class="cell c35 noBomb"></div>
     <div class="cell c36 noBomb"></div>
     <div class="cell c37 bomb"></div>
     <div class="cell c38 noBomb"></div>
     <div class="cell c39 noBomb"></div>
     <div class="cell c40 noBomb"></div>
     <div class="cell c41 noBomb"></div>
     <div class="cell c42 noBomb"></div>
     <div class="cell c43 noBomb"></div>
     <div class="cell c44 noBomb"></div>
     <div class="cell c45 noBomb"></div>
     <div class="cell c46 bomb"></div>
     <div class="cell c47 noBomb"></div>
     <div class="cell c48 noBomb"></div>
     <div class="cell c49 noBomb"></div>
   </div>
 </div>

CSS

In CSS wird das optische Erscheinungsbild der Seite bestimmt.

Die Hintergrundfarbe und Stil der Schrift werden definiert.

body {
  background-color: #4d4d4d;
  color: #b488b8;
  font-family: Calibri;
  text-align: center;
  text-transform: uppercase;
}

h1 {
  font-size: 60px;
}

Die Buttons werden abgerundet und bekommen jeweils eine Hintergrundfarbe.

#start {
  color: #b488b8;
  background-color: #fff;
  font-family: Arial;
  font-size: 24px;
  text-transform: uppercase;
  border: none;
  border-radius: 5px;
  padding: 10px;
  margin: 20px;
}

#restart {
  display: none;
  color: #b488b8;
  background-color: #4d4d4d;
  font-family: Arial;
  font-size: 24px;
  text-transform: uppercase;
  border: none;
  border-radius: 5px;
  padding: 10px;
  margin: 20px;
}

Der Bereich unter dem Spielfeld wird abgerundet und bekommt eine andere Farbe.

.background {
  position: relative;
  box-sizing: border-box;
  float: left;
  background-color: #ababab;
  width: 100%;
  border-radius: 10px;
  padding-bottom: 5%;
  margin-top: 30px;
}

Die Spielfelder werden zu abgerundeten Quadraten und bekommen einen Rand und eine Farbe.

.cell {
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  float: left;
  width: 14.28%;
  padding-bottom: 13.8%;
  border: 1px solid white;
  background-color: #1e1e1e;
  border-radius: 5px;
}

Die Karte, die nach Beendung des Spiels erscheint, wird im gleichen Stil designt.

.gameOver {
  opacity: 0;
  box-sizing: border-box;
  float: left;
  background-color: #fff;
  width: 94%;
  padding: 5%;
  margin: 3%;
  border-radius: 10px;
  transition: transform 1s cubic-bezier(0.38, 0.4, 0, 1.18);
  transition-delay: 3s;
}

Auch die Animationen werden in CSS erzeugt.

Beim Klick auf den Start-Button werden alle Felder, die keine Bomben sind, für wenige Sekunden langsam durchsichtig und dann wieder sichtbar.

/* fade-out fade-in der nicht-Bomben beim Klick des Start-Buttons (keyframe fade) */
.noBomb.start {
  animation: fade 7s;
}
@keyframes fade {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

Beim hovern über einen der Buttons wird dieser um 10% größer.

#start:hover,
#restart:hover {
  transition: transform;
  transform: scale(1.1);
}

Die Farbe der der einzelnen Felder ändert sich beim hovern und sie wachsen langsam um 30%.

.cell:hover {
  transition: background-color, transform 0.5s;
  background-color: #b488b8;
  transform: scale(1.3);
}

Wird ein Feld angeklickt, das keine Bombe ist, wird es grün und in einer rotierenden Bewegung kleiner, bis es verschwunden ist.

/* Animation der nicht-Bomben nach Klick */
.noBomb.clicked {
  transition: background-color, transform 4s;
  background-color: #81c7a2 !important;
  transform: scale(0) rotate(720deg);
  pointer-events: none;   /* verhindert, dass ein Feld mehrfach geklickt werden kann */
}

Beim Klick auf eine Bombe wird diese rot und dreht sich um die y- und die z-Achse.

/* Animation der Bomben nach Klick */
.bomb.clicked {
  transition: background-color, transform 4s;
  background-color: #ff695e !important;
  transform: rotateY(180deg) rotateZ(45deg);
  pointer-events: none;
}

Nach Beendung des Spiels erscheint die Karte mit dem Punktestand, verliert langsam ihre Durchsichtbarkeit und wandert von unten nach oben, bis sie über der Mitte des Spielfelds landet.

JavaScript

JavaScript ist zuständig für die Funktionalität der Seite. Hier wird unter anderem definiert, was genau passiert, wenn ein bestimmtes Objekt angeklickt wird. Dabei wird dem Objekt eine neue Klasse zugeordnet, was die in CSS bestimmte Animation auslöst.

Beim Klick auf den Start-Button werden alle Objekte der Klasse „noBomb“ ausgewählt. Mithilfe einer For-Schleife wird ihnen die Klasse „start“ zugeordnet, was die in CSS definierte Animation auslöst.

// fade-out / fad-in bei Klick auf den Start-Button
let start = document.querySelector("#start");
let noBomb = document.querySelectorAll(".noBomb");
start.addEventListener("click", () => {
  for (var i = 0; i < noBomb.length; i++) {
    noBomb[i].classList.add("start");
  }
});

Ein Klick auf den Restart-Button sorgt dafür, dass die Seite neu geladen wird.

// neu laden der Seite bei Klick  auf Restart-Button
let restart = document.querySelector("#restart");
restart.addEventListener("click", () => {
  window.location.href = window.location.href;
});

Beim Klick auf eins der normalen Felder wird dem Objekt die Klasse „clicked“ zugeordnet und dadurch die CSS-Animation ausgelöst. Zusätzlich wird ein Soundeffekt abgespielt. Außerdem wird der Punktestand um 1 erhöht und überprüft, ob dadurch die maximale Punktzahl erreicht wurde. Falls dass der Fall ist, wird die Spielabschlusskarte gezeigt und animiert.

// Animation der nicht-Bomben und counter der Punktzahl
let c1 = document.querySelector(".c1");
c1.addEventListener("click", () => {
  c1.classList.add("clicked");
  count += 1;
  score.innerHTML = "score: " + count;
  finalScore.innerHTML = count;
  if (count == 40) {
    restart.classList.add("true");
    for (var i = 0; i < cell.length; i++) {
      cell[i].classList.add("over");
    }
    gameOver.classList.add("true");
  }
  audioNoBomb.play();
});

Der Klick auf eine der Bomben funktioniert ähnlich, auch hier wird die Animation ausgelöst. Außerdem wird allen Feldern die Klasse „over“ zugeordnet, was dafür sorgt, dass keine weiteren Felder angeklickt werden können.

// Animation der Bomben und der Karte nach Beendung des Spiels
let c2 = document.querySelector(".c2");
let cell = document.querySelectorAll(".cell");
c2.addEventListener("click", () => {
  finalScore.innerHTML = count;
  c2.classList.add("clicked");
  restart.classList.add("true");
  for (var i = 0; i < cell.length; i++) {
    cell[i].classList.add("over");
  }
  gameOver.classList.add("true");
  audioBomb.play();
});

Auch die Audiodateien werden über JavaScript eingebettet.


Dieser Beitrag ist im Studiengang Informationsmanagement an der Hochschule Hannover im Rahmen des Kurses Entwicklung von Multimediasystemen (Sommersemester 2021, Amy Linh Hoang,  Prof. Dr.-Ing. Steinberg) entstanden. Verwendete Techniken sind HTML5, CSS3 und JavaScript. Die besten Tutorials stellen wir Euch hier in den nächsten Wochen nach und nach vor.