Tutorial 3: Quiz programmieren


Erfolgsendungen wie „Wer wird Millionär“ und etliche Quizapps in den Appstores begeistern die Menschen. Perfekt um sich das Konzept von einem Quiz einmal anzuschauen und ein eigenes zu programmieren. Da dies mal das ganze twas umfangreicher ist, gibt es diesmal 2 Videos.
Teil 1:

Teil 2:

Mit einem Quiz kann man nicht nur Fragen wie in der Fernsehsendung stellen, sondern das ganze auch noch anders nutzen. Du kannst dir aus dem Quiz einen Trainer bauen, mit dem du bestimmte Dinge lernen kannst. Zum Beispiel kannst du Vokabeln oder Fachbegriffe damit lernen. Du könntest aber auch ein Quiz erstellen und dieses auf deiner Webseite oder in einer App anbieten. Das coole: Wenn du das ganze nicht nachprogrammieren willst, kannst du einfach den fertigen Quellcode nehmen und eigene Fragen einfügen. Die Vorlage für die Fragen ist im Quellcode enthalten.

Warum ein Quiz?

Das Quiz ist eine super Möglichkeit viele Aspekte zu beleuchten, die man auch in größeren Anwendungen beachten muss. Auch wenn die Funktionalität erstmal einfach scheint, zeigt sich die Komplexität erst, wenn man versucht as ganze mal eben kurz zu programmieren. Beim Quiz müssen wir mehrere Aufgaben lösen, denn wir müssen zum einen Daten aus einer Datei laden können, welche unsere Fragen enthält. Zusätzlich dazu müssen wir diese Fragen nach und nach in einer Oberfläche anzeigen. Dann haben wir die Logik, die einmal überprüfen muss, ob die Antwort richtig oder falsch war. Zum Schluss, also nach der letzten Frage zeigen wir einen Endpunktestand an. Wer also dieses Beipsiel durcharbeitet und verstanden hat, versteht langsam wie komplex auch einfache kleine Programme werden können. Dazu gibt es ein paar Technologien die wir verwenden werden:

Was wirst du hier heute lernen?

  • Einsatz von jQuery und Bootstrap
  • HTML Elemente und Attribute in Javascript benutzen
  • Elemente zeigen und verstecken
  • Mausklicks
  • Daten speichern/laden mit JSON

Wir werden typischerweise mit einer kurzen Planung anfangen, damit du verstehst welche Dinge du vor der Programmierung vorbereiten musst. Nur so kannst du es tatsächlich lernen. Was du hier nicht lernst ist, wie du dieses Quiz später online nimmst, denn das Tutorial ist zu Lernzwecken gestaltet. Der enthaltene Code wurde nicht sicherheitstechnisch überprüft und benötigt definitiv noch Anpassungen, bevor man diesen auf die Menschheit loslässt.

Was du brauchst

Wir starten, wie im letzten Tutorial auch mit dem Grundaufbau aus Tutorial 1. Dann schauen wir uns an, wie das Layout bzw. Design der App aussehen soll. Dann ist zu klären, wie wir unsere Fragen speichern und laden wollen, wir werden dafür eine eigene Javascript-Datei bauen in der die Fragen gespeichert sind und geladen werden können. Dann ist der Ablauf des Quizzes wichtig. Was passiert auf welchen Knopfdruck und wie geht es weiter?

TODO-Liste

Features, Design und Spezialitäten

Folgende Skizze zeigt die Idee der Quiz-App:
Quiz Programm Design und Ablauf
Das Quiz startet mit einer Begrüßung, wenn man dort auf Start drückt soll die erste Frage gestellt werden. Beim Start werden intern alle notwendigen Aufgaben ausgeführt, die das Quiz vorbereiten. Die Frage wird direkt mit ihren Antworten gezeigt. Wenn eine Antwort ausgewählt wurde, muss die Antwort erst bestätigt werden, bevor diese ausgewertet wird. Nach der Bestätigung erhält man die Auswertung ob die eigene Antwort richtig war. Dabei wird grün bei richtigen und rot bei falschen Antworten verwendet. Die Auswertung leitet mit Weiter zur nächsten Frage. Sind alle Fragen beantwortet worden, erhält man eine Gesamtpunktzahl. Wir haben also grob folgende 4 Bestandteile:

  • Startseite und Startbutton
  • Frageseite mit Antworten
  • Auswertung nach Antwort
  • Gesamtpunktzahl nach letzter Frage

Anbei die Screenshots der fertigen App:

Startseite

Startbildschirm des Quiz-Programms

Frageseite

Frageseite des Quiz-Programms

Frageseite beantwortet (richtige Antwort)

Auswertung der Frage im Quiz-Programm

Gesamtpunktzahl

Gesamtpunktzahl des Quiz Programms

Ran an die Tastatur!

Jetzt gehen wir schrittweise durch alle 45(!) Schritte. Möchtest du nicht programmieren, kannst du unten den fertigen Code herunterladen und nach deinen eigenen Wünschen anpassen.

1. Basisstruktur mit HTML, CSS und Javascript

Wir starten mit der Dateistruktur aus dem ersten Tutorial. 3 simple Dateien mit HTML, CSS und Javascript, wobei Bootstrap und jQuery bereit eingerichtet sind.

2. Container

<div class="container">

</div>

3. Navbar

  <nav class="navbar navbar-default">
    <div class="container-fluid">
        <div class="navbar-header">
          <a class="navbar-brand" href="#">Quiz</a>
        </div>
      </div>
  </nav>

4. Jumbotron von Bootstrap für Start

  <div id="start_screen" class="jumbotron quiz_start">
    <h1>Herzlich Willkommen!</h1>
    <p>Das Quiz startet sofort...</p>
    <p><button id="start_btn" class="btn btn-primary btn-lg" role="button">Jetzt starten</button></p>
  </div>

5. Jumbotron für Ende

      <div id="over" class="jumbotron quiz_end" hidden>
        <h1>Quiz Vorbei!</h1>
        <p>Dein Punktestand ist: <span id="endpoints">0</span> von <span id="possiblepoints">0</span></p>
        <p><button class="restart btn btn-primary btn-lg" role="button">Nochmal starten</button></p>
      </div>
  

6. Jumbotron für Frage/Antwort

      <div id="question" class="jumbotron" hidden>
        <h2>Frage <span id="qno">1</span></h2>
        <p id="question_text">Was macht man mit einer Programmiersprache?</p>
      </div>

7. Layout für Antworten

        <div class="row">
          <div class="col-md-6"></div>
          
        </div>

8. Antwort-Möglichkeit

        <p><button id="answer_a_btn" class="answer btn btn-default btn-lg btn-block" role="button">A: <span id="answer_a">Wandern</span></button></p>

9. Antwort Möglichkeit 2

  <div class="col-md-6"><p><button id="answer_c_btn" class="answer btn btn-default btn-lg btn-block" role="button">C: <span id="answer_c">Programmieren</span></button></p></div>
  

10. Die anderen Antworten in der nächsten Zeile

        <div class="row">
          <div class="col-md-6"><p><button id="answer_b_btn" class="answer btn btn-default btn-lg btn-block" role="button">B: <span id="answer_b">Kochen</span></button></p></div>
          <div class="col-md-6"><p><button id="answer_d_btn" class="answer btn btn-default btn-lg btn-block" role="button">D: <span id="answer_d">Zeichnen</span></button></p></div>
        </div>
        

11. Antwort abschicken Layout

        <div class="row">
          <div class="col-md-10"></div>
          <div class="col-md-2">
          </div>
        </div>      
  

12. Antworten Button

  <p><button id="answer_commit_btn" class="btn btn-primary btn-lg btn-block" role="button"><span id="commit_text">Antworten</span></button></p>
  

13. Weiter Button (vor oder nach Auswertung der Antwort)

              <p><button id="continue_btn" class="btn btn-primary btn-lg btn-block" role="button" hidden><span id="commit_text" >Weiter</span></button></p>

14. Quiz-Script für Fragen

Dazu müssen wir eine quiz.js erstellen und im Ordner js ablegen. In dieser bauen wir nun die Bibliothek für die Fragen/Antworten. Du kannst auch die script.js kopieren und umbenennen.

<script src="js/quiz.js"></script>

15. Variablen

var currentQuestionNo = 0;
var points = 0;
var rightAnswerPoints = 10;
var currentQuestion;

16. Fragen-Objekt

var questions = [
  {
    "id":"1",
    "question" : "Was macht man mit einer Programmiersprache?",
    "answers" : {
      "A":"Wandern",
      "B":"Kochen",
      "C":"Programmieren",
      "D":"Zeichnen"
    }, 
    "right":"C"
  },{
    "id":"2",
    "question" : "Wie nennt man einen Fehler in einem Computerprogramm?",
    "answers" : {
      "A":"Bug",
      "B":"Hat",
      "C":"Pen",
      "D":"Code"
    }, 
    "right":"A"
  }
];

17. Nächste Frage laden

function showNextQuestion() {
  console.log("Loading Question:" + currentQuestionNo);
  currentQuestion = questions[currentQuestionNo];
}

18. Frageninformationen in HTML zeigen

  
function showNextQuestion() {
  console.log("Loading Question:" + currentQuestionNo);
  currentQuestion = questions[currentQuestionNo];

  $("#qno").text(currentQuestionNo + 1);
  $("#question_text").text(currentQuestion.question);
  $("#answer_a").text(currentQuestion.answers.A);
  $("#answer_b").text(currentQuestion.answers.B);
  $("#answer_c").text(currentQuestion.answers.C);
  $("#answer_d").text(currentQuestion.answers.D); 
}

19. Richtige Antwort zurückgeben als Funktion

  function getRightAnswer() {
  return currentQuestion.right;
}

20. Quiz starten in script.js

$(".start").click(function() {
  console.log( "Start" );
});

21. Startseite ausblenden und Quiz starten

$(".start").click(function() {
  console.log( "Start" );
  $(".quiz_start").fadeOut();
  startQuiz();
});

22. Quiz starte NACH Ausblendung !nach fadeOut (sooo siehts gut aus!)

Da das Quiz noch während des fadeOut startete, müssen wir dies über einen Callback realisieren. Die Funktion wird erst nach Ende des fadeOut aufgerufen.
So ist das in der jQuery-Dokumentation für das fadeOut beschrieben.

$(".start").click(function() {
  console.log( "Start" );
  $(".quiz_start").fadeOut(function() {
    startQuiz();
  });
});

23. Quizfrage zeigen und Frage einblenden.

 function startQuiz() {
  showNextQuestion();
  $("#question").fadeIn();    
}

24. Antwort selektieren (mehrere probieren)

function selectAnswer(id) {
  $(id).addClass("btn-primary");
  $(id).removeClass("btn-default");
}

25. andere Antworten deselektieren

function deselectAnswer(id) {
  $(id).addClass("btn-default");
  $(id).removeClass("btn-primary");  
}

26. Antworten anklicken

$("#answer_a_btn").click(function() {
  
});

27. Passende Antwort selektieren, alle anderen deselektieren

$("#answer_a_btn").click(function() {
  selectAnswer("#answer_a_btn");
  deselectAnswer("#answer_b_btn");
  deselectAnswer("#answer_c_btn");
  deselectAnswer("#answer_d_btn");
});

28. Alle anderen Antworten darunter innerhalb der Funktion hinzufügen

$("#answer_b_btn").click(function() {
  deselectAnswer("#answer_a_btn");
  selectAnswer("#answer_b_btn");
  deselectAnswer("#answer_c_btn");
  deselectAnswer("#answer_d_btn");
});

$("#answer_c_btn").click(function() {
  deselectAnswer("#answer_a_btn");
  deselectAnswer("#answer_b_btn");
  selectAnswer("#answer_c_btn");
  deselectAnswer("#answer_d_btn");
});

$("#answer_d_btn").click(function() {
  deselectAnswer("#answer_a_btn");
  deselectAnswer("#answer_b_btn");
  deselectAnswer("#answer_c_btn");
  selectAnswer("#answer_d_btn");
});  

29.Antwort abschicken und überprüfen

$("#answer_commit_btn").click(function() {
  validateAnswer();
});

30. Nicht nochmal abschicken lassen und richtige Antwort holen.

function validateAnswer() {
  $("#answer_commit_btn").hide();
  var rightAnswer = getRightAnswer();
  
}

31. Welche Antwort wurde angeklickt und stimmen diese überein?

function validateAnswer() {
  $("#answer_commit_btn").hide();
  var rightAnswer = getRightAnswer();
  
  var selectedAnswer = $(".answer.btn-primary").text()[0]; 
  if (selectedAnswer == rightAnswer) {

  } else {

  }
}

32. Punkte hochzählen

function validateAnswer() {
  $("#answer_commit_btn").hide();
  var rightAnswer = getRightAnswer();
  
  var selectedAnswer = $(".answer.btn-primary").text()[0]; 
  if (selectedAnswer == rightAnswer) {
    points += rightAnswerPoints;
  } else {

  }
}

33. Id vom Button holen um das Aussehen ändern zu können

function validateAnswer() {
  $("#answer_commit_btn").hide();
  var rightAnswer = getRightAnswer();
  var selectedAnswerId = $(".answer.btn-primary").attr("id");  
  
  var selectedAnswer = $(".answer.btn-primary").text()[0]; 
  if (selectedAnswer == rightAnswer) {
    points += rightAnswerPoints;
  } else {

  }
}

34. Selektion und Deselektion von Buttons entfernen

function validateAnswer() {
  $("#answer_commit_btn").hide();
  var rightAnswer = getRightAnswer();
  var selectedAnswerId = $(".answer.btn-primary").attr("id");  
  $(".answer.btn-primary").removeClass("btn-primary");
  $(".answer.btn-default").removeClass("btn-default");  
  var selectedAnswer = $(".answer.btn-primary").text()[0]; 
  if (selectedAnswer == rightAnswer) {
    points += rightAnswerPoints;
  } else {

  }
}

35. Richtige antwort: Button Grün markieren!

function validateAnswer() {
  $("#answer_commit_btn").hide();
  var rightAnswer = getRightAnswer();
  var selectedAnswerId = $(".answer.btn-primary").attr("id");  
  $(".answer.btn-primary").removeClass("btn-primary");
  $(".answer.btn-default").removeClass("btn-default");  
  var selectedAnswer = $(".answer.btn-primary").text()[0]; 
  if (selectedAnswer == rightAnswer) {
    points += rightAnswerPoints;
    $("#"+selectedAnswerId).addClass("btn-success");  
  } else {

  }
}

36. Falsche antwort: Button rot markieren!

function validateAnswer() {
  $("#answer_commit_btn").hide();
  var rightAnswer = getRightAnswer();
  var selectedAnswerId = $(".answer.btn-primary").attr("id");  
  $(".answer.btn-primary").removeClass("btn-primary");
  $(".answer.btn-default").removeClass("btn-default");  
  var selectedAnswer = $(".answer.btn-primary").text()[0]; 
  if (selectedAnswer == rightAnswer) {
    points += rightAnswerPoints;
    $("#"+selectedAnswerId).addClass("btn-success");  
  } else {
    $("#"+selectedAnswerId).addClass("btn-danger");
  }
}

37. Nächste Frage Button zeigen

function validateAnswer() {
  $("#answer_commit_btn").hide();
  var rightAnswer = getRightAnswer();
  var selectedAnswerId = $(".answer.btn-primary").attr("id");  
  $(".answer.btn-primary").removeClass("btn-primary");
  $(".answer.btn-default").removeClass("btn-default");  
  var selectedAnswer = $(".answer.btn-primary").text()[0]; 
  if (selectedAnswer == rightAnswer) {
    points += rightAnswerPoints;
    $("#"+selectedAnswerId).addClass("btn-success");  
  } else {
    $("#"+selectedAnswerId).addClass("btn-danger");
  }
  $("#continue_btn").show();
}

$("#continue_btn").click(function() {

});

38. Nächste Frage-Knopf kann bei Klick wieder versteckt werden und Weiter-Knopf wird wieder gezeigt

$("#continue_btn").click(function() {
  $("#continue_btn").hide();
  $("#answer_commit_btn").show();
});

39. Nächste Frage-Variabe hochzählen (für Fragendaten-Array) und Frage laden

$("#continue_btn").click(function() {
  $("#continue_btn").hide();
  $("#answer_commit_btn").show();
  currentQuestionNo++;
  showNextQuestion();  
});

40. Alle Markierungen für nächste Frage auf Standard setzen

  
function showNextQuestion() {
  $(".answer").removeClass("btn-primary btn-danger btn-success btn-default");
  $(".answer").addClass("btn-default");

  console.log("Loading Question:" + currentQuestionNo);
  currentQuestion = questions[currentQuestionNo];

  $("#qno").text(currentQuestionNo + 1);
  $("#question_text").text(currentQuestion.question);
  $("#answer_a").text(currentQuestion.answers.A);
  $("#answer_b").text(currentQuestion.answers.B);
  $("#answer_c").text(currentQuestion.answers.C);
  $("#answer_d").text(currentQuestion.answers.D); 
}

41. Was nach der letzten Frage kommt.

  
function showNextQuestion() {
  if (currentQuestionNo >= questions.length) {
    showEnd();
    currentQuestionNo = 0;
  }
  
  $(".answer").removeClass("btn-primary btn-danger btn-success btn-default");
  $(".answer").addClass("btn-default");

  console.log("Loading Question:" + currentQuestionNo);
  currentQuestion = questions[currentQuestionNo];

  $("#qno").text(currentQuestionNo + 1);
  $("#question_text").text(currentQuestion.question);
  $("#answer_a").text(currentQuestion.answers.A);
  $("#answer_b").text(currentQuestion.answers.B);
  $("#answer_c").text(currentQuestion.answers.C);
  $("#answer_d").text(currentQuestion.answers.D); 
}

42. Das Ende zeigen

  
function showEnd() {
  $("#question").fadeOut(function() {
    $(".quiz_end").fadeIn();  
  });  
}

43. Punkte zählen und Punkte anzeigen

  
function showEnd() {
   $("#endpoints").text(points);
   $("#possiblepoints").text(rightAnswerPoints * questions.length);
  $("#question").fadeOut(function() {
    $(".quiz_end").fadeIn();  
  });  
}

44. Nochmal Spielen anstoßen

$(".restart").click(function() {
  $(".quiz_end").fadeOut(function() {
    startQuiz();  
  });
});

45. Weiter-Knopf verstecken

function startQuiz() {
  showNextQuestion();
  $("#continue_btn").hide();
  $("#question").fadeIn(); 
  
}

Test und Zusatzfeatures

Auch wenn das nun fast 50. Einzelschritte waren, bist du nun dran um das Quiz zu erweitern. Du kannst mal probieren eigene Fragen in das JSON-Objekt zu packen. Eine andere Erweiterung wäre andere Antwortmöglichkeiten zu programmieren, wie wäre eine Kombination mit den Antworten aus dem Textadventure aus Tutorial 2? Wenn man dieses Quiz später Online stellen möchte, sollte man die Fragen nicht direkt im Code speichern. Besser wäre eine Lösung, in der man sich die Fragen und die Richtige Antwort über einen Server holt. Sonst könnte man ja einfach über den Quelltext herausfinden, welche Antwort richtig ist 😉 .

Fazit

In diesem etwas umfassenderen Tutorial hast du gesehen, dass selbst ein kleines Programm wie eine Quiz-App, schon viele Programmier-Schritte benötigt. Dies sollte dir einen kleinen Einblick in die Komplexität geben und dir zeigen woran man eigentlich alles denken muss, wenn man so eine App schreibt. Falls du nicht klargekommen bist schau doch am besten in den Code rein, dann kannst du direkt vergleichen.

Hier kannst du den Quellcode zu diesen Tutorial herunterladen.

Im nächsten Tutorial wird es wieder etwas einfacher, allerdings gibt es auch ein anderes Thema. Da werden wir das erste Mal mit Zeit arbeiten. Du darfst dich also schon freuen!
Hast du Feedback oder Fragen schreib mich einfach an oder kommentiere unten. Sollte dir das Tutorial gefallen haben, freue ich mich, wenn du meine Seite abonnierst und ein Like bzw. Daumen hoch da lässt.

Keine Zeit zum nachprogrammieren?

2 Kommentare
  1. Chris sagte:

    Hallo, Super Tutorial!
    Hat auf Anhieb funktioniert,
    Nun möchte ich, dass die erreichte Punktezahl in eine DB geschrieben wird. Dafür muss diese a nach PHP übergeben werden.
    Wie stelle ich das am besten an? Gibt es da eine einfache Methode zu?

    Antworten
    • Arek sagte:

      Hi Chris,
      sehr gut! Freut mich, dass dir das Tutorial weitergeholfen hat.
      Um die Punktezahl zu speichern, benötigst du einen Server mit einer Datenbank und das geht dann in die Serverprogrammierung. Mit PHP bedeutet das, dass du ein PHP-Skript benötigst, welches vom Skript aufgerufen werden kann, z.B. mit einem Parameter mit der Punktzahl.
      Dieses Thema wurde nicht in dem Tutorial behandelt.

      Beste Grüße
      Arek

      Antworten

Dein Kommentar

An Diskussion beteiligen?
Hinterlasse uns Deinen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.