Only this pageAll pages
Powered by GitBook
1 of 29

Code: Trivia App

Loading...

Loading...

Code Template

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

More

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

About

This is the reference documentation for the iDEW Trivia library and template (see GitHub Repo).

Just getting started? Start with the Template Build Tutorial. or jump to the template Quick Start. Here is a live example of the basic template. Yeah, it is boring. It is up to you to make it interesting.

Copyright and License

Copyright © 2015-2018 Jim Lyst and Michael Frontz, Indiana University School of Informatics and Computing at IUPUI

This material is part of the Computing by Design high school computer science curriculum developed for the Informatics Diversity-Enhanced Workforce (iDEW) program, an award-winning community partnership in central Indiana that is broadening student participation in computing and helping students develop the skills essential for success in the 21st century workplace. The iDEW program is managed by the Indiana University School of Informatics and Computing at IUPUI.

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. You are free to use, share, or adapt this material for non-commercial purposes as long as you provide proper attribution and distribute any copies or adaptations under this same license.

Prerequisite Knowledge

Basic HTML/CSS/JS Programming Concepts

Familiarity with the following concepts are highly recommended before programming the trivia game. But mastery is NOT required.

HTML

  • Common HTML Elements and the basic tag syntax <div>, <h1>, <h2> (etc.), <button>, <span>

  • Nesting elements

  • id and class attributes

CSS

  • Selectors for elements, classes, and ids

  • Common properties used in styles: background-color, color, font-size, margin, padding, height, width, display, border, etc.

JavaScript

  • Variables - numbers, strings, objects

  • Functions

  • Conditionals -- if, else

  • jQuery selectors for elements, classes, and ids

  • Basic jQuery functions: $.show(), $.hide(), $.html()

Options to Learn or Revisit Concepts

Intro to Informatics and Web Development (Recommended)

The series of exercises covers HTML/CSS/JS and some informatics practices.

A Quick Dive

  1. ​​

  2. ​​

  3. ​​

  4. ​​

Deeper Dive Options

  • HTML - , , ​

  • CSS - , , ​

  • JavaScript - (JS) / (jQuery), (JS)/ (jQuery), (JS) / (jQuery)

Intro to Informatics and Web Development
HTML
CSS
Classes and id's
HTML Nesting
jQuery Basics
JS Variables
JS Functions
JS Conditionals
W3Schools
Khan Academy
Codecademy
W3Schools
Khan Academy
Codecademy
W3Schools
W3schools
Khan Academy 1
Khan Academy 2
Codecademy 1
Codecademy 2

Support True/False Questions

CSS

In order to display basic True/False questions, simply add the following CSS to your stylesheet. :empty identifies answer buttons that have no content and hides the element using display: none

.answer-btn:empty {
   display: none;
} 

Google Sheet Table of Questions

In your Google sheet table simply put the correct answer (whether "True" or "False") in the correct answer column and the incorrect (whether "False" or "True") in the first incorrect column. Leave the remaining two answers blank.

Likewise, you could have questions that offer only 3 multiple choice answers.

8. Finishing the Game

Once all questions are answered the trivia library will call your displayThankyou( ) function. Notice how the game results are also displayed in this function. Your thank you screen HTML provides a restart button that will allow the player to play again. Update your displayThankyou( ) function to match the one below.

JavaScript
function displayThankyou() {
  $(".screen").hide();
  $("#thankyou-screen").show();
  $("#game-results").html(`You got ${trivia.totalCorrect} of ${trivia.totalAnswered} correct.`);
}

Your core trivia game code should work from start to finish now.

2. Welcome Screen

HTML of Basic Welcome Screen Content

Now you will update your welcome screen HTML slightly by adding a <button> element and an h4 element. The button will start the game after we add more code later. Later you can customize your welcome message and even add some specific data about the trivia game.

Update your welcome screen HTML to match the code below. (Don't add another welcome screen!)

CSS for More Style

Add the following CSS styles to the bottom of your stylesheet for buttons and headings. Modify styles as you wish, but be careful about the effects of changing display, margin, and width , which can be problematic sometimes.

7. Respond to Answer Clicks

When a Player Clicks an Answer

The onClickedAnswer( ) function is called by the Trivia library when a button of class "answer-btn" is clicked. In the code below you will notice that a parameter, isCorrect, is "passed" to the function to indicate whether the answer is correct or not. Based on the answer we will provide appropriate feedback by inserting text and showing the "feedback" HTML element. We will also highlight the correct answer by adding a "highlight" class to the correct answer button. Finally, we will wait 3 seconds then use the trivia library method to gotoNextQuestion. Update your function to match the one below.

In order for the button highlight to work you need to add the following to your CSS. Add this to the bottom of your CSS.

If you run your trivia now the first question should respond nicely to a clicked answer, but you will notice a couple of problems once you get passed the first question. The highlight is stuck on and the feedback is not cleared. Let's fix that by adding two lines of code to your displayQuestion( ) function.

Add the code below just after $("#question-screen").show(); inside your displayQuestion( ) function. This resets your feedback.

Your trivia game should be clipping along well now. The final piece is to handle what happens when all questions have been answered.

4. Thank You Screen

HTML for Thank You Screen Content

Below you see that we are updating the thank you screen much like your welcome screen, but you will definitely want to put some game results here later instead of saying, "Looks like you did pretty well." The id called "game-results" will help us easily insert the game results later.

Update your thank you screen HTML to match the code below.

Again, no additional CSS to add.

HTML
<!-------------- WELCOME SCREEN --------------->
<div class='screen' id='welcome-screen'>
    <h1>Welcome to our example game!</h1>
    <h4>You have questions waiting for you.</h4>
    <button class="start-btn">Start</button>
</div>
CSS
h1, h4 {
  text-align: center;
}
button {
  background-color: rgba(255,255,255,.7);
  border: none;
  outline: none;
  border-radius: 19px;
  box-shadow: 3px 3px 7px black;
  font-size: 24px;
  display: block;
  margin: 10px auto;
  min-height: 70px;
  width: 100%;
}
JavaScript
function onClickedAnswer(isCorrect) {
  if (isCorrect) $("#feedback").html(`Way to go!`).show();
  else $("#feedback").html(`Better luck next time.`).show();
  $("#correctAnswer").addClass("highlight"); //highlight right answer
  setTimeout(trivia.gotoNextQuestion, 3000); //wait 3 secs...next question
}
CSS
.highlight {
  background-color: green;
  color: white;
}
JS
  $("#correctAnswer").removeClass("highlight");
  $("#feedback").hide();
HTML
<!-------------- THANK YOU SCREEN --------------->
<div class='screen' id='thankyou-screen'>
  <h1>Thanks for playing our game!</h1>
  <h4 id='game-results'>Looks like you did pretty well.</h4>
  <button class="start-btn">Restart</button>
</div>

6. Load Questions and Go

A Word About the iDEW Trivia Library

You will come across bits of code that use the iDEW trivia library -- for example, trivia.loadGoogleSheet( ) , trivia.insertQuestionInfo( ), trivia.totalQuestions. These methods and trivia values were designed to make programming your game easier. Once you dig in to your own game design you will want to review all the goodies offered in the Trivia Library Reference section of this book.

Load Questions Then Display Welcome

Update your setup ( ) function to match the one below that loads the example question database. You will eventually change the googleSheetLink value to your own. Notice that once the questions are loaded (see .then in code) the displayWelcome ( ) function is called.

JS
//Runs once at the beginning
function setup() {
  var googleSheetLink = "https://docs.google.com/spreadsheets/d/e/2PACX-1vRYCi4KENeZMlf9JbV8BhVrdOHse2250INSiRo7gEYWUYp3V0jiWFKWcnm1jzx5q1BMsmd9fOopk2Z_/pub?output=csv";
  trivia.loadGoogleSheet(googleSheetLink).then(displayWelcome); 
}

Note: The updated Google Sheet Link (as of August 30, 2021) used above works with the latest Trivia Library release (1.2.0 +).

Update your displayWelcome( ) function to match the one below. This function first hides all screens, since they are all of class "screen". Then, only the welcome-screen is displayed using it's unique id.

JS
function displayWelcome() {
  $(".screen").hide();
  $("#welcome-screen").show();
}

Responding to Start Button Click

The onClickedStart( ) function is called by the Trivia library when a button of class "start" is clicked, like the one in your welcome screen HTML and thank you screen HTML. Here we simply call the displayQuestion( ) function. You may add more code here later for additional game features.

Update your onClickedStart( ) function as below.

JS
function onClickedStart() {
  displayQuestion();
}

Below the displayQuestion( ) function hides all HTML screen then displays only the question screen. Then the question info (category, question, and answers) are inserted into the question screen HTML using a method from the Trivia library. The answers are then shuffled for obvious reasons. Update your displayQuestion( ) function to match.

Update your displayQuestion( ) function as below.

JS
function displayQuestion() {
  $(".screen").hide();
  $("#question-screen").show();
  trivia.insertQuestionInfo();
  trivia.shuffleAnswers();
}

Test your code. Your game will get stuck at the first question, but we will address that next.

Use Images with Questions

If you want questions to display a particular image, like shown above, here are the basic steps.

1 - Upload Images to Your App in an "images" folder.

  • index.html

  • style.css

  • code.js

  • images

    • question1image.png

    • question2image.png

2 - Add a Column in Your Spreadsheet for Image Names

3 - Add HTML to Hold the Image

You may want to place this right below your question, like the example at the top of this page.

<div id="image-holder"></div>

4 - Add the Javascript to Display the Image

You will want to add this right after trivia.insertQuestionInfo(); in your displayQuestion( ) function.

if (trivia.currentQuestion.image)
    $('#image-holder').html(`<img src='images/${trivia.currentQuestion.image}'</img>`);
else 
    $('#image-holder').html(``);

5 - Add CSS Styles

These styles will maintain the width of the image and center it on the screen. Change the styles as needed.

#image-holder {
  margin: auto;
  width: 150px;
}

#image-holder > img {
  width: 100%;
}

That's it. It should work for you now.

1. Screens as Containers

HTML for the Screen Containers

Below you see the HTML for the three screen "containers" as <div> elements. We will add more detail to each screen later. Notice that each screen has class='screen' . This will allow us to easily change the style (CSS) of all three screens later in the same way. Also, notice that each screen has a unique id that will allow us to target each screen in a particular way later.

Copy the HTML code and paste it into a new index.html file, or use the CodePen version if you are starting with CodePen's HTML. The browser page preview is not exciting, but it should contain text from all three screens.

<!DOCTYPE html>
<html>

<head>
  <title>iDEW Trivia</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <!-------------- WELCOME SCREEN --------------->
  <div class='screen' id='welcome-screen'>
    <h1>Welcome screen.</h1>
  </div>

  <!-------------- QUESTION SCREEN --------------->
  <div class='screen' id='question-screen'>
    <h1>Question screen.</h1>
  </div>

  <!-------------- THANK YOU SCREEN --------------->
  <div class='screen' id='thankyou-screen'>
    <h1>Thank you screen.</h1>
  </div>
  
  <script src="script.js"></script>
</body>

</html>
<!-------------- WELCOME SCREEN --------------->
<div class='screen' id='welcome-screen'>
  <h1>Welcome screen.</h1>
</div>

<!-------------- QUESTION SCREEN --------------->
<div class='screen' id='question-screen'>
  <h1>Question screen.</h1>
</div>

<!-------------- THANK YOU SCREEN --------------->
<div class='screen' id='thankyou-screen'>
  <h1>Thank you screen.</h1>
</div>

This is single page web app.

What is a single page web app? Most traditional web sites are a collection of HTML files (pages) that link to each other. With a single page web app you will create a single HTML file that contain different views (we call them screens in our case) that you hide or show depending on the state of the app.

For example, in the trivia game, you will hide the question and thank you screens at the beginning and show the welcome screen. When the visitor starts the game, you will hide the welcome screen and show the question screen, and so on.

Don't worry if this isn't totally clear yet. It will make more sense when we get to the JavaScript programming part later.

CSS for the Body and Screens

Let's add a little style to our screens next. In the code below notice how the body , which contains all contents of the page, is given a background color of "gray" and a margin of "0". This gives us a nice edge-to-edge background for placing our screen content.

Next you will see several styles being applied to screens, since .screen affects all elements with that class. Notice how background-color uses rgba( ) so that we can "see through" the screen a bit to the background. You will want this feature later. The rest of the styling has to do with sizing the screens and content in a way that fits nicely on any device, and you will probably want to leave these elements alone.

Copy the CSS code below into your style.css file and notice the change. You will need to scroll down in the live preview to see all the screens now.

CSS
body {
  margin: 0;
  background-color: gray;
}

.screen {
  background-color: rgba(255,255,255,.5);
  box-sizing: border-box;
  margin: 15px auto;
  padding: 15px;
  max-width: 700px;
  width: calc(100vw - 30px);
  height: calc(100vh - 30px);
}

Save your Code before the next step!

Add Background Animation

Spinning Block Example

The function below uses p5.js functions to create a spinning block that you can add to your app background.

1 - Add the following function to the bottom of your JavaScript.

2 - Now you simply need to call this function when you want it to display in the background. In the example below, spinningBlock( ) is called in the draw( ) function when the trivia game state is "welcome" on line 3. If you want, you can choose to call the function at a different point.

The spinningBlock is a simple example of adding an animation to your background, but you can come up with your own animation and call it something different than spinningBlock( ). For example, you may choose to create an animation that looks like balloons rising up and call it balloons( ). It may be challenging, but you can use functions from the (as we did above for the spinning block) to create some really interesting animations.

Other Example Animations

Here are more examples of custom animation functions that could be implemented like the spinningBlock() above.

JavaScript
function spinningBlock() { 
    background("gray"); 
    translate(width / 2, height / 2); //move to the middle
    rotate(PI / 90 * frameCount); //rotate more with each frame
    rect(-26, -26, 52, 52); //place the rectangle
}
JavaScript
//Loops continously for background effects and animations. (p5.js)
function draw() {
  if (trivia.state == "welcome") spinningBlock();
  else if (trivia.state == "question") background("lightblue");
  else if (trivia.state == "correct") background("green");
  else if (trivia.state == "incorrect") background("red");
  else if (trivia.state == "thankyou") background("orange");
}
//Just a ball that bounces around on the screen
function ballInBox() {
  background("gray");
  //adjust ball x/y positions based on frameCount
  //and know when to "bounce"
  var x = frameCount%width;
  if (floor(frameCount/width)%2 == 0) x = width - x;
  var y = frameCount*1.3%height;
  if (floor(frameCount*1.3/height)%2 == 0) y = height - y;
  translate(x, y);
  ellipse(0, 0, 3, 3);
}
//balloons rising to the top
function balloons() {
  background("gray");
  var sFrame = floor(frameCount / (4*height))*4*height; //starting frame for looping
  for (var i = 0; i < 30; i++) { //let's do 30 balloons
    randomSeed(10510 * i + 2); //ensures a repeatable random #
    var y = int(random(height*4) - (frameCount - sFrame)/2);
    randomSeed(30260 * i + 1); //ensures another repeatable random #
    var x = int(random(width));
    fill("red");
    line(x, y, x, y + 30);//balloon string
    ellipse(x, y, 10, 15);//balloon
  }
}
p5.js
spinningBlock( )
ballInBox( )
balloons( )
Creative Commons License

Trivia JS Library Reference

The information on this page is in development and is provided for advanced use of the library.

Trivia Methods

trivia.loadGoogleSheet(link)

Used to load a question bank from a Google Sheet.

trivia.getCategories()

Returns all category names in an array.

trivia.getUnfinishedCategories()

Returns category names of the categories having unanswered questions. Returns as an array.

trivia.gotoNextQuestion()

Advances the trivia game to the next question.

trivia.insertCategoryInfo()

This function places a button for each category into the HTML.

trivia.insertQuestionInfo()

This function puts the current question and answers taken from your database into the HTML to be displayed.

trivia.shuffleAnswers()

This function shuffles the multiple choice answers so that the correct answer does not always show at the top.

trivia.startClickListeners()

This function simply starts the event listeners for different types of player clicks.

Trivia Objects and Attributes

trivia.questions

This is an array of the trivia question objects.

trivia.currentQuestion

This is the current trivia question object which contains key/value pairs defined by the question database. For example, trivia.currentQuestion.category will contain the category label for the current question if it is available. The standard question object keys are below, but can be extended as needed.

  • category

  • question

  • correctAnswer

  • incorrectAnswer1

  • incorrectAnswer2

  • incorrectAnswer3

trivia.questionIndex

This provides the current question's index in the questions array.

trivia.totalQuestions

The provides the total questions in the game.

trivia.totalCorrect

This provides how many correct answers the player has at the moment.

trivia.totalAnswered

This provides how many questions have been answered by the player at that moment.

trivia.state

This provides the state of the game. Possible states -- 'welcome', 'question', 'correct', 'incorrect', and 'thankyou'.

Raw Library JavaScript

var trivia = {
  questions: [],
  currentCategory: null,
  categoriesEnabled: false,
  currentQuestion: {},
  questionIndex: 0,
  totalQuestions: 0,
  totalCorrect: 0,
  totalAnswered: 0,
  state: "welcome",
  loadGoogleSheet: function (link) {
    return new Promise((resolve, reject) => {
      var self=this;
      Papa.parse(link, {
        download: true,
        header: true,
        complete: function (results) {
          self.questions = results.data;
          console.log("Questions loaded: ",self.questions);
          self.questions = shuffle(self.questions);
          if (self.questions.length) self.currentQuestion = self.questions[0];
          self.questionIndex = 0;
          self.totalQuestions = self.questions.length;
          self.totalCorrect = 0;
          self.totalAnswered = 0;
          self.state = "welcome";
          self.startClickListeners();
          resolve("success");
        }
      })
    });
  },
  getCategories: function () {
    var cats = [];
    this.questions.filter((q) => {
      if (!cats.includes(q.category)) cats.push(q.category);
    });
    return cats;
  },
  getUnfinishedCategories: function () {
    var cats = [];
    this.questions.filter((q) => {
      if (!cats.includes(q.category) && !q.response) cats.push(q.category);
    });
    return cats;
  },
  gotoNextQuestion: function () { //this just forwards a "deprecated function"
    displayQuestion();
  },
  insertCategoriesInfo: function () {
    var cats = this.getCategories();
    var unfcats = this.getUnfinishedCategories();
    $('#category-set').html('');
    cats.forEach((c) => {
      var $catbtn = $(`<button class="category-btn">${c}</button>`);
      if (unfcats.includes(c)) {
        $catbtn.on('click', function (e) {
          trivia.currentCategory = c;
          onClickedCategory();
        });
      }
      else $catbtn.attr("disabled", true);
      $('#category-set').append($catbtn);
    })
  },
  insertQuestionInfo: function () {
    trivia.state = "question";
    $(".answer-btn").attr("disabled", null);
    trivia.questionIndex = trivia.questions.findIndex((q) => {
      if (!this.categoriesEnabled) return !q.response;
      else return !q.response && q.category == this.currentCategory;
    });
    if (trivia.questions[trivia.questionIndex]) {
      trivia.currentQuestion = trivia.questions[trivia.questionIndex];
      for (var prop in trivia.currentQuestion) {
        $("#" + prop).html(trivia.currentQuestion[prop]);
      }
    }
    else {
      if (this.totalAnswered == this.totalQuestions) {
        trivia.state = "thankyou";
        displayThankyou(); //game over
      }
      else if (this.categoriesEnabled) {
        trivia.state = "categories";
        displayCategories();
      }
      else alert('Yikes');
    }
  },
  shuffleAnswers: function () {
    $("#answer-set").html(shuffle($("#answer-set").children())); //shuffle answers
  },
  startClickListeners: function () {
    //listen for answer button clicks
    $(".screen").on("click", ".answer-btn", ev => {
      $(".answer-btn").attr("disabled", "disabled"); //turn off buttons to prohibit cheating :)
      trivia.triggerAnswer($(ev.target).is("#correctAnswer"));
    });

    //listen for restart button click
    $(".screen").on("click", ".start-btn", ev => {
      this.questions.forEach(function (q) { delete q.response });
      trivia.questionIndex = 0;
      if (!this.categoriesEnabled) trivia.state = "question";
      else trivia.state = "categories";
      trivia.currentQuestion = trivia.questions[0]; //reset to the first question
      onClickedStart();
    });
  },
  triggerAnswer: function (correct) {
    $(".answer-btn").attr("disabled", "disabled");
    if (correct) {
      trivia.currentQuestion.response = "correct";
      trivia.state = "correct";
    } else {
      trivia.currentQuestion.response = "incorrect";
      trivia.state = "incorrect";
    }
    trivia.totalCorrect = trivia.questions.filter(item => {
      return item.response == "correct";
    }).length;
    trivia.totalAnswered = trivia.questions.filter(item => {
      return item.response;
    }).length;
    onClickedAnswer(trivia.currentQuestion.response == "correct");
  }
};

Quick Start for Code Template

Copy the HTML/CSS/JavaScript below to get started immediately.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <!-------------- WELCOME SCREEN --------------->
<div class='screen' id='welcome-screen'>
    <h1>Welcome to our example game!</h1>
    <h4>You have questions waiting for you.</h4>
    <button class="start-btn">Start</button>
</div>

<!-------------- QUESTION SCREEN --------------->
<div class='screen' id='question-screen'>
  <h4 id="category">Category Name</h4>
  <h1 id="question">Question goes here?</h1>
  <div id="answer-set">
    <button class="answer-btn" id="correctAnswer">Correct Answer</button>
    <button class="answer-btn" id="incorrectAnswer1">Wrong Answer</button>
    <button class="answer-btn" id="incorrectAnswer2">Wrong Answer</button>
    <button class="answer-btn" id="incorrectAnswer3">Wrong Answer</button>
  </div>
  <h1 id="feedback">Feedback will go here.</h1>
</div>

<!-------------- THANK YOU SCREEN --------------->
<div class='screen' id='thankyou-screen'>
  <h1>Thanks for playing our game!</h1>
  <h4 id='game-results'>Looks like you did pretty well.</h4>
  <button class="start-btn">Restart</button>
</div>

    <!-- JS Libraries -->
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.min.js'></script>
    <script src="https://cdn.jsdelivr.net/gh/idewcomputing/code-trivia/src/trivia.js"></script> <!-- iDEW trivia -->

    <script src="code.js"></script>
  </body>
</html>
body {
  margin: 0;
  background-color: gray;
}

.screen {
  background-color: rgba(255,255,255,.5);
  box-sizing: border-box;
  margin: 15px auto;
  padding: 15px;
  max-width: 700px;
  width: calc(100vw - 30px);
  height: calc(100vh - 30px);
}

h1, h4 {
  text-align: center;
}
button {
  background-color: rgba(255,255,255,.7);
  border: none;
  outline: none;
  border-radius: 19px;
  box-shadow: 3px 3px 7px black;
  font-size: 24px;
  display: block;
  margin: 10px auto;
  min-height: 70px;
  width: 100%;
}

.highlight {
  background-color: green;
  color: white;
}

canvas {
  min-width: 100vw;
  min-height: 100vh; 
  position: absolute;
  top: 0;
  z-index: -1;
}
//Runs once at the beginning
function setup() {
  var googleSheetLink = "https://docs.google.com/spreadsheets/d/e/2PACX-1vRYCi4KENeZMlf9JbV8BhVrdOHse2250INSiRo7gEYWUYp3V0jiWFKWcnm1jzx5q1BMsmd9fOopk2Z_/pub?output=csv";
  trivia.loadGoogleSheet(googleSheetLink).then(displayWelcome); 
}

//Loops continously for background effects and animations. (p5.js)
function draw() {
  if (trivia.state == "welcome") background("yellow");
  else if (trivia.state == "question") background("lightblue");
  else if (trivia.state == "correct") background("green");
  else if (trivia.state == "incorrect") background("red");
  else if (trivia.state == "thankyou") background("orange");
}

function displayWelcome() {
  $(".screen").hide();
  $("#welcome-screen").show();
}

function displayQuestion() {
  $(".screen").hide();
  $("#question-screen").show();
  $("#correctAnswer").removeClass("highlight");
  $("#feedback").hide();
  trivia.insertQuestionInfo();
  trivia.shuffleAnswers();
}

function displayThankyou() {
  $(".screen").hide();
  $("#thankyou-screen").show();
  $("#game-results").html(`You got ${trivia.totalCorrect} of ${trivia.totalAnswered} correct.`);
}

function onClickedAnswer(isCorrect) {
  if (isCorrect) $("#feedback").html(`Way to go!`).show();
  else $("#feedback").html(`Better luck next time.`).show();
  $("#correctAnswer").addClass("highlight"); //highlight right answer
  setTimeout(trivia.gotoNextQuestion, 3000); //wait 3 secs...next question
}

function onClickedStart() {
  displayQuestion();
}

Add Basic Scoring

The following example code demonstrates how to add basic scoring to your trivia game.

HTML

Add an HTML element with a unique id that will display the score. For example, you could place the following example to the top of the question screen.

<h1 id="score">-</h1>

Javascript

Next you will need to update the score presented on the screen at the appropriate time. For starters, place the following line of Javascript inside the curly braces { } of the onClickedAnswer() function code block. Placing it at the top of the code block is a good place.

$('#score').html(`${trivia.totalCorrect} of ${trivia.totalAnswered} Correct`);

That's it, but you will likely want to customize how the score is presented. You could also add the core to the thank you screen in a similar way.

9. Visual Enhancement

Using P5.js to Add Animation (Optional)

Let's include a function that will enable you to create fancy animations later. Add the following function just after your setup( ) function. Examples of how to add visual effects to your trivia game are available in the code examples section, but for now we will simply change the background color.

JavaScript
//Loops continously for background effects and animations. (p5.js)
function draw() {
  if (trivia.state == "welcome") background("yellow");
  else if (trivia.state == "question") background("lightblue");
  else if (trivia.state == "correct") background("green");
  else if (trivia.state == "incorrect") background("red");
  else if (trivia.state == "thankyou") background("orange");
}

You will also need to add the following code to the end of your CSS.

CSS
canvas {
  min-width: 100vw;
  min-height: 100vh; 
  position: absolute;
  top: 0;
  z-index: -1;
}

You should now see that the screen’s background color changes based on the current state of the game.

Add a Question Timer

This is an example of adding a timer to the question screen that counts down to zero.

HTML

Add the following HTML element inside your question screen section--and probably at the top of the screen. This will be where your timer digits will be displayed.

Javascript

Add the code shown below to your displayQuestion ( ) function inside the curly braces { } of the function's code block. The Javascript function called setInterval runs a block of code at a set interval. In this example, we run a block of code every 100 milliseconds that allows us to update the countdown timer accurately. If the timer reaches zero, it triggers an incorrect answer using trivia.triggerAnswer(false). Notice that you can adjust the time limit by changing the timeLimit variable.

CSS

Below is an example of some basic CSS properties you could apply in your stylesheet. Adjust as needed.

That's it. You should have a functioning timer that you can modify as you wish.

<h1 id="timer">-</h1>
var timeLimit = 10;
var startTime = Date.now(); //get the time at the moment a user first sees the question
clearInterval(trivia.countDown);
trivia.countDown = setInterval(function () {
  if (trivia.state == "question") { //ensure the user has not already answered
    var elapsedTime = (Date.now() - startTime)/1000; //calculate the time elapsed
    var clock = timeLimit - Math.floor(elapsedTime);//calculate the countdown w/o decimals
    $('#timer').html(clock);// place the clock time in the html for viewing
    if (clock == 0) { //if time is up
      clearInterval(trivia.countDown); //stops our timer at 0. Don't want -1 ...
      trivia.triggerAnswer(false); //marks the answer as incorrect in trivia library
    }
  }
  else clearInterval(trivia.countDown);
}, 100);//100 is the time interval in milliseconds
#timer{
  text-align: center;
  width: fit-content;
  margin: auto;
}

3. Question Screen

HTML for Basic Question Screen Content

Take a look at the code below and carefully review the nested elements in this block along with the classes and ids used. The <div> with an id = "answer-set" encloses the four answer buttons to help with shuffling answers later on. We wouldn't want the correct answer to always be on top, would we? :) Also, notice the <div> with id = "feedback" that can be used to give a player feedback after answering.

Update your question screen HTML to match the code below.

HTML
<!-------------- QUESTION SCREEN --------------->
<div class='screen' id='question-screen'>
  <h4 id="category">Category Name</h4>
  <h1 id="question">Question goes here?</h1>
  <div id="answer-set">
    <button class="answer-btn" id="correctAnswer">Correct Answer</button>
    <button class="answer-btn" id="incorrectAnswer1">Wrong Answer</button>
    <button class="answer-btn" id="incorrectAnswer2">Wrong Answer</button>
    <button class="answer-btn" id="incorrectAnswer3">Wrong Answer</button>
  </div>
  <h1 id="feedback">Feedback will go here.</h1>
</div>

No additional CSS needed for the question screen, since we already added style for buttons and the screen class. Yea!

Code Mod Examples

In the menu to the left you can find a list of example code modifications you could make to the trivia game.

Add a Category Selection Screen

Let's add a screen for the player to choose a question category after they click start.

1 - Add the following HTML in your index.html file just after your welcome screen. This provides a place for the iDEW trivia library to place buttons for your categories.

<!-------------- CATEGORY SCREEN --------------->
	<div class='screen' id='category-screen'>
		<h1>Choose a category.</h1>
    	<div id="category-set">
    	</div>
	</div>

2 - Enable trivia categories in your code.js file by placing the following Javascript line inside your setup( ) function. This simply tells the iDEW trivia library that you would like to process your category screen.

trivia.categoriesEnabled = true;

3 - Add the following Javascript function in your code.js file after (not inside) your displayWelcome( ) function.

function displayCategories() {
  $(".screen").hide();
  $("#category-screen").show();
  trivia.insertCategoriesInfo();
}

4 - Modify your current onClickedStart( ) function to include displayCategories(), shown on line 2 below. You should remove displayQuestion()line inside your onClickedStart(). You simply want the player to see your categories screen after clicking start, instead of going straight to the question screen.

function onClickedStart() {
  displayCategories();
}

5 - Lastly, add a new Javascript function to handle what to do when a category is selected. In this case you will just move the player on to the question screen. The iDEW trivia library is keeping track of what category was selected. To keep things tidy, place this new function just before (but not inside) your onClickedStart( ) function.

function onClickedCategory() {
  displayQuestion();
}

That's it. Try it out.

Add a Question Timer with Pause Button

HTML

Add the following HTML element inside your question screen section--and probably at the top of the screen. This will be where your timer digits will be displayed.

Add the following HTML element insider your question screen section--possibly at the bottom. This is the button to pause the game.

Javascript

Add the code shown below to your displayQuestion ( ) function inside the curly braces { } of the function's code block. The Javascript function called setInterval runs a block of code at a set interval. In this example, we run a block of code every 100 milliseconds that allows us to update the countdown timer accurately. If the timer reaches zero, it triggers an incorrect answer using trivia.triggerAnswer(false). Notice that you can adjust the time limit by changing the timeLimit variable.

Add the following function to your Javascript file at the bottom. This will change the pause state of the game and change the text of the button appropriately. Your HTML button runs this function on a click.

Add the following line to the top (but inside the curly braces) of your onClickedAnswer function. This will hide the pause button after an answer is clicked. It probably doesn't make sense to have that button showing after the answer is clicked.

CSS

Below is an example of some basic CSS properties you could apply in your stylesheet. Adjust as needed.

That's it. You should have a functioning timer that you can modify as you wish.

5. Core JS Functions

HTML to Load JavaScript Libraries

In the code below the script tags load that make coding your game much easier. To all the people that work on free and open source projects, thank you!! You are adding the , , , and the iDEW trivia libraries here.

Add the code below to the bottom of your HTML body. (Place just before the tag for your custom JS code<script src="script.js"></script> if needed.

Core JavaScript Functions of Trivia Game

We are assuming you don't want your trivia game to be a static page and make people scroll down the screen just to see a trivia question. That's where JavaScript comes in to give you control of how the trivia game interacts and displays content when and where you want.

  • setup( ) This function runs once when the visitor first comes to the page. For example, we will load the question database here.

  • displayWelcome( ) , displayQuestion( ) , displayThankyou( ) These functions control what is displayed for each of our screens.

  • onClickedAnswer( ) , onClickedStart( ) These functions control what happens when buttons are clicked.

Copy the JavaScript below and paste it in a new script.js file. Nothing new will happen just yet. That's next.

Managing the Question DB

⚠️ Important update to instructions posted August 30, 2021.

Using Google Sheet as Database (Recommended)

  1. Login to Google Drive.

  2. Go to .

  3. Create your own copy of the spreadsheet by selecting File > Make a copy....

  4. Now publish your copy of the spreadsheet by selecting File > Publish to the web...

  5. Choose the Comma-separated value option as shown below.

  6. Click the Publish button and copy the full link provided.

    ⚠️ If you are using your school Google account, ensure that you turn off restricting access to your school. If you are using a personal Google account your published link should work fine without needing to do this.

  7. Find the setup() function in your JavaScript file, like the example below, and replace your link as the googleSheetLink.

  8. Now you can edit your Google Sheet and your question database will automatically be updated in your trivia app.

HTML
<!-- JS Libraries -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.min.js'></script>
<script src="https://cdn.jsdelivr.net/gh/idewcomputing/code-trivia/src/trivia.js"></script> <!-- iDEW trivia -->
JavaScript (code.js)
//Runs once at the beginning
function setup() {
  //more code will go here... 
}

function displayWelcome() {
  //more code will go here...
}

function displayQuestion() {
  //more code will go here...
}

function displayThankyou() {
  //more code will go here...
}

function onClickedAnswer(isCorrect) {
  //more code will go here...
}

function onClickedStart() {
  //more code will go here...
}
libraries
papaparse
jquery
p5.js
<h1 id="timer">-</h1>
<button id="pause-game" onclick="togglePause();">Pause</button>
  $("#pause-game").show(); //in case it was hidden
  $("#pause-game").html("Pause");
  var timeLimit = 10;
  var startTime = Date.now();
  var clock = 10;
  clearInterval(trivia.countDown);
  trivia.isPaused = false;
  trivia.countDown = setInterval(function () {
    if (trivia.state == "question" && !trivia.isPaused) { //ensure the user has not already answered
      var elapsedTime = (Date.now() - startTime) / 1000; //calculate the time elapsed
      clock = timeLimit - Math.floor(elapsedTime);//calculate the countdown w/o decimals
      $('#timer').html(clock);// place the clock time in the html for viewing
      if (clock == 0) { //if time is up
        clearInterval(trivia.countDown); //stops our timer at 0. Don't want -1 ...
        trivia.triggerAnswer(false); //marks the answer as incorrect in trivia library
      }
    }
    else if (!trivia.isPaused) clearInterval(trivia.countDown);
    else {
      timeLimit = clock;
      startTime = Date.now();
    }
  }, 100);//100 is the time interval in milliseconds
function togglePause() {
  trivia.isPaused = !trivia.isPaused; //changes pause state
  var btnTxt = trivia.isPaused ? "Resume" : "Pause";
  $("#pause-game").html(btnTxt);
  $(".answer-btn").attr("disabled",trivia.isPaused);//disable answer buttons when paused.
}
$("#pause-game").hide();
#timer{
  text-align: center;
  width: fit-content;
  margin: auto;
}
//Runs once at the beginning
function setup() {
  var googleSheetLink = "https://docs.google.com/spreadsheets/d/e/2PACX-1vRYCi4KENeZMlf9JbV8BhVrdOHse2250INSiRo7gEYWUYp3V0jiWFKWcnm1jzx5q1BMsmd9fOopk2Z_/pub?output=csv";
  trivia.loadGoogleSheet(googleSheetLink).then(displayWelcome); 
}
this spreadsheet

Template Build Tutorial

Core Game Structure

There are three screens in the core game structure. While it may seem simple, you will find that there are many creative and engaging things you can do in your customized design.

  • Welcome Screen The welcome screen can simply welcome the visitor to the game and give some background on your game. It will display a start button to take the visitor to the first question. You can optionally include some basic metrics about the game, like how many questions await them.

  • Question Screen The question screen is the most important screen. In that it not only presents the trivia questions to the visitor, but also will display feedback on correct and incorrect answers. The question screen can also include running data; like a score, progress, or timer.

  • Thank You Screen The thank you screen will gracefully inform the visitor that they have finished the game. This screen can provide additional data, like how well they played the game, and provide a button to play it again.

Programming and Question Database

The code template is built with HTML/CSS/Javascript. The custom question database can be directly included as a Javascript object array or created in a connected Google Sheet. Creating the database in a Google Sheet is most convenient and much easier to edit.

Let's Get Building...

This tutorial simply builds the code template step by step to help you understand how it works. Go to 1. Screens as Containers.

Add Sound Effects on Answer Clicks

Let's add some simple sound effects to your trivia game when a player answers a question.

1 - Find sound effects you would like to use or make your own. Files of type .mp3 are a good choice for web apps. You can download the two sounds below as a starting point.

17KB
sound_correct.mp3
sound_correct.mp3
30KB
sound_incorrect.mp3
sound_incorrect.mp3

2 - Create a folder named sounds and place your sound files in it. Pay close attention to your files and folder structure for you app. Below is an example of what yours should look like.

  • index.html

  • style.css

  • code.js

  • sounds

    • sound_correct.mp3

    • sound_incorrect.mp3

3 - Declare variables for your sounds at the very top of your code.js file. They should be above the setup() function. These lines create variables that will represent your sound files so that you can play them at a later point in your code. Also, since we are placing them at the top of your code and not inside any function, they are called global variables. This means we can access these variables inside any other function, which we will do next.

var soundCorrect = new Audio("sounds/sound_correct.mp3");
var soundIncorrect = new Audio("sounds/sound_incorrect.mp3");

4 - Place the code shown below inside your onClickedAnswer( ) function to play the sounds at the appropriate time. Notice how we are combining the text and sound feedback in our if/else statements inside the code brackets { }. Your text feedback will likely be different. So adjust as needed.

  if (isCorrect) {
    $("#feedback").html(`Way to go!`).show();
    soundCorrect.play();
  }
  else {
    $("#feedback").html(`Better luck next time.`).show();
    soundIncorrect.play();
  }

That's it. Your game should now play your sound effects when a player answers a question.

If you are using a longer sound file, like a song, you will want to know about the following two features.

pause( ) - This method will pause your sound. For example, soundCorrect.pause( );

currentTime - This property can be used to reset the sound to the beginning. For example, soundCorrect.currentTime = 0;

Custom Feedback Text for Individual Questions

This is an example of how you can provide special feedback for each trivia question after the player answers. For example, you may want to provide more information on that question's topic whether they answered correctly or not.

1 - Add a "feedback" column to your question spreadsheet (our database) like shown below, and add custom feedback text for each question.

2 - Next, you want to use the trivia property trivia.currentQuestion.feedback to place the text in the HTML element having id="feedback". Notice how this is done in lines 2 and 3 below. Make the same changes within your onClickedAnswer function in your JavaScript.

That's it. Try it out.

JavaScript
function onClickedAnswer(isCorrect) {
  if (isCorrect) $("#feedback").html(trivia.currentQuestion.feedback).show();
  else $("#feedback").html(trivia.currentQuestion.feedback).show();
  $("#correctAnswer").addClass("highlight"); //highlight right answer
  setTimeout(trivia.gotoNextQuestion, 3000); //wait 3 secs...next question
}

Add "Next Question" Button

The default trivia template moves the player on to the next question after a few seconds. This example demonstrates how to add a button for the player to click that moves the game along to the next question.

Javascript Changes

First, find the onClickedAnswer( ) function. Then locate the following line of code in that function.

setTimeout(trivia.gotoNextQuestion, 3000);

The code above causes your game to wait 3 seconds before moving on to the next question. Since you will use a button instead, you can either delete this line of code or comment // it out.

Next, add the following line of code as a replacement. Notice how an HTML button is appended after your question feedback that responds to a click by running trivia.gotoNextQuestion() .

$("#feedback").append(`<br><button onclick="trivia.gotoNextQuestion();">Next Question</br>`);

That's it. It should work for you. Consider styling this button differently by assigning it a class and adding the new style in your CSS.

Style Changes with CSS

Below are some basic style changes you could use to update the look of the trivia app. With CSS, the possibilities are nearly endless. Just look at this CSS reference at w3schools. It is easy to just try things out by trial and error. Most styles have several options to consider. So, as needed, do a Google search for "CSS" followed by a simple description of a style you are interested in, and you will likely find some answers.

Backgrounds

In your style.css file try changing or adding the following background properties to different elements in your trivia game,--like the body, .screen, or button CSS selectors to see the result.

background: rgba(255,100,100);

Notice that there are many ways to define colors.

background: linear-gradient(red, yellow);
/* You need an image file in your folder for this one */
background: url("paper.gif");

Borders and Shadows

border: 1px solid rgb(50,50,50);
border-radius: 10px;
box-shadow: 3px 3px 7px red;

Fonts and Text

font-family: "Times New Roman", Times, serif;
font-size: 32px;
color: blue;
text-align: right;

Want to get a unique font? Try Google Fonts. Hint: If you find a font you like, click the "+" for the font family then click the "family selected" bar at the bottom of the page to see instructions.

Display the Total Question Count at Welcome

In this simple mod we will let the player know at the welcome screen how many questions are in the database using the trivia.totalQuestions value that automatically counts the questions for us.

1 - Modify your welcome screen HTML like on line 4 below, where the id="question-count" was added.

HTML
<!-------------- WELCOME SCREEN --------------->
<div class='screen' id='welcome-screen'>
    <h1>Welcome to our example game!</h1>
    <h4 id="question-count">You have questions waiting for you.</h4>
    <button class="start-btn">Start</button>
</div>

Now we will insert the trivia.totalQuestions value into a sentence to be placed in the element with id="question-count".

2- Add the code on line 4 below to the end of your displayWelcome() function in your JavaScript.

JavaScript
function displayWelcome() {
  $(".screen").hide();
  $("#welcome-screen").show();
  $("#question-count").html(`You have ${trivia.totalQuestions} questions waiting for you.`);
}

That's it. Try it out.