Build Chrome Dino Quiz Game From Scratch With Speech Recognition Using JavaScript
You all must be aware of the Chrome Dinosaur Game, also known as T-Rex Game and Dino Runner, a built-in browser game in the Google Chrome web browser, accessed when offline on Google Chrome or by typing chrome://dino
in the address bar. But if you have never played, then it is your lucky day.
In this post, you will learn how to build the Dino Runner game from scratch and reform it into a Quiz Game that uses Voice Recognition with Web Speech API.
Let’s get started.
HTML Layout: The HTML layout defines the element structure that would be shown on the page. It includes:
Header: This section is placed at the top of the web-page and is used for the following:
- Title: It displays the title of the game, when the game is loaded for the first time or reloaded.
- Question Board:It shows the questions for the quiz.
- Answer Board: It shows the answer to the current question of which the player gave an incorrect answer.
Game: This section is where the whole game will be executed. It includes :
- Score Board: This block will display the score player has reached.
- Game Status: This block is displayed when the game has started or when the game is over.
- Dino: This block shows the player image and sets the player position in the game.
- Cactus: This block shows the obstacles(cactus) and sets the obstacle’s position.
- Ground: This block displays the ground and sets its position in the game.
- Speech Bubble: This block shows the speech results, which the player will speak through the microphone.
CSS Styling: CSS is used to style the different portions in HTML and make it more visually appealing.
- The CSS Stylesheet is inserted under the
<head>
tag named as index.css. - The game title Dino Quiz, a paragraph element
<p>
created through JavaScriptcreateElement()
function, has class attributestripe-text
. Pseudo-element::after
and::before
are used to provide text styling and text shadow respectively. - The Speech Bubble is a div element with the class attribute
oval-thought
that provides a bubble-shaped styling to the element. Its child element,<p>
, text node is updated from the player’s speech result as it speaks in the microphone. - Google-Fonts are used to give an arcade look to the game by using “Press Start 2P” font-family to display the player’s scores.
-webkit
vendor prefix is used in both CSS and JavaScript to provide support for experimental features such as Web Speech API which is currently supported by Chrome and Edge desktop browsers.
JavaScript: The heavy lifting behind the scenes is done by JavaScript, such as manipulating DOM elements, integrating Web Speech API, Animation, and much more. The JavaScript code is defined in the Game.js file, inserted in the HTML file just before the </body>
tag using <script></script>
tags, loading the HTML code first.
Let’s understand the code step by step:
Step 1: Display start screen
Game Status:
- The
gameStatus
object defined has two accessor properties,gameOver
andgameReset
, manipulated by setter method and obtained by getter methods.
- The
gameOver
flag is set totrue
when the game is over orfalse
otherwise. - The
gameReset
flag is set totrue
when the player wants to play again.
Display Title and Start/Reload Message:
- The
initialText()
method displays the title Dino Quiz in the Header section as a new paragraph element, and the message Press space to start will be at the bottom of the player character at the starting of the game. - However, both the texts are only displayed when the
getResetGame()
method returnsfalse
, which tells that the game is not over; if it is true, then the Press space to reload message is only displayed, asking the player to restart the game.
Step 2: Construct Player profile and functionality
Player Image:
- In the
drawDino()
method, canvas element with class attribute dino is selected; it will act as our player character and perform actions such as jumping and running. - A dinosaur image is drawn on the selected canvas using
drawImage()
method that takes nine arguments which are as follows:
image
— An element to draw into the context.sx
— The x-axis coordinate of the top left corner of the sub-rectangle of the source image to draw into the destination context.sy
— The y-axis coordinate of the top left corner of the sub-rectangle of the source image to draw into the destination context.sWidth
— The width of the sub-rectangle of the source image to draw into the destination context. If not specified, the entire rectangle from the coordinates specified by sx and sy to the bottom-right corner of the image is used.sHeight
— The height of the sub-rectangle of the source image to draw into the destination context.dx
— The x-axis coordinate in the destination canvas at which to place the top-left corner of the source image.dy
— The y-axis coordinate in the destination canvas at which to place the top-left corner of the source image.dWidth
— The width to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in width when drawn.dHeight
— The height to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in height when drawn.
Player Position:
- The
dinoPosition
object tells if the player character was on the ground or not, i.e., jump action was made or not. - If
onground
property is true, then the player character will be on the ground otherwise a jump action has been initiated.
Player Animation:
- Run- In the
dinoRun()
method, thesetInterval()
method usesdrawDino()
method to redraw the image of the character on the player canvas after a defined interval, in this case, 100 milliseconds, giving a sense that the character is running. The animation is stopped either when the game is over or when the player character is off the ground. - Jump- In the
jumpDino()
method twosetInterval()
method are used to create a jump effect-
- First
setInterval()
method reduces the Y-axis coordinates of the player canvas up to 100px. - Second
setInterval()
method increase the Y-axis coordinated of the player canvas up to 200px. - Both the methods perform the task at a defined interval, one after another.
Step 3: Obstacle in the game
- Generating obstacles: The
createElement()
method creates obstacles dynamically in the game. The obstacles are created based on the condition that the player has dodged the last obstacle. - Moving obstacle: The
obctacleSpeed
variable, which is in milliseconds (thousandths of a second), tells the delay in between executions of the specifiedsetInterval()
method, the obstacles position keeps on changing until the it has reached at position 0 or when the game is over, theremove()
method removes the obstacle element from the DOM. - Setting Conditions: Based on the distance between the obstacle and the player position, separate condition statements are executed.
- Set Game Over: When the user gives the incorrect answer to the question asked,
getflagVal()
getter method returns false and minimum distance between the player and obstacle has reached thetoJump()
method returnstrue
, thus game status isfalse
andgameOver()
method is called. - Jump Player: When the user gives the correct answer to the question asked,
getflagVal()
getter method returns false and minimum distance between the player and obstacle has reached thetoJump()
method returnstrue
, thus triggering thejumpDino()
method making the player jump. - Other Methods: Other methods such as
setQuestion()
,setHideBubble()
,setflagVal()
are called when a suitable condition is triggered.
Step 4: Game background
- The
groundMove()
method provides an moving background effect, it renders the canvas element and redraws the ground image on the canvas after a set time interval. - Image is drawn on the canvas twice at an appropriate distance from each other, shifted to left by a multiple of 2 each time; multiple of 2 here represents the speed at which the image is shifted. Thus, a higher value means higher speed.
Step 5: Quiz question(s) and answer(s)
Question Object: The question(s) for the quiz are an array of objects; each object has three properties.
- ID: It is the question number, starting from 1.
- Question: It has the question for the quiz.
- Answer: It has the answer to the question.
Setting question and Getting answer:
- The
quizQuestionAnswer
object sets the question on the Question Board block using the setter method and answers the respective question using the getter method. It also checks for the index value which represents the questions array index; if it exceeds the total number of questions, it returnsfalse
. - The
setQuestion()
setter method calls theCactus()
method to initiate obstacle generation. - The static
String.fromCodePoint()
method is used to insert emoji in the HTML code, this method returns a string created by using the specified sequence of code points.
Step 6: Speech Recognition
Integrating Web Speech API:
- The Web Speech API has two parts: Speech Synthesis (Text-to-Speech) and Speech Recognition (Asynchronous Speech Recognition.) We will be using Speech Recognition to get input from the user through a microphone.
- On some browsers, like Chrome, using Speech Recognition on a web page involves a server-based recognition engine. Your audio is sent to a web service for recognition processing, so it won’t work offline.
Two events get triggered in our case.
- result event- It is triggered when a word or phrase is positively recognized. It compares user speech results with the answer to the current question.
- Results matched- The score is incremented by 100, the user speech results are displayed using the
speechBubble
object setter methodsetBubbleResult()
andanswerMatchresult
object setter methodsetflagVal
is set totrue
. - Results not matched- The user speech results are displayed using the
speechBubble
object setter methodsetBubbleResult()
andanswerMatchresult
object setter methodsetflagVal
is set tofalse
.
- end event- It is triggered when the speech recognition service has disconnected. It starts the speech recognition service again to maintain a continuous flow of speech for the user.
Displaying Speech Results:
- The
speechBubble
object withsetBubbleResult()
setter method gets called when the result event of theSpeechRecognition
is triggered to display the user speech results. - The
setHideBubble()
setter method is to hide the speech bubble.
Set Result flag:
- The
answerMatchresult
object usessetflagVal()
setter method to set the object’s flag property totrue
when the user speech result matches the related question’s answer. - The
getflagVal()
getter method is used to return theflag
.
Step 7: Score Board
The scoreBoard object keeps track of the user’s current score.
- The
setScoreBoard()
setter method, which initializes the scoreboard result to 0. - The
setScore()
setter method gets called when the user has successfully dodged an obstacle, and the score gets incremented by 100 each time.
Diamond emoji (HTML-code 💎
) is displayed with <span>
tag and “Press Start 2P” Google font is used to display the score which gives an arcade look to the game.
Step 8: Bringing it all together
Initialize Game:
- The
initGame()
method gets called when the HTML document has fully loaded. It renders the opening screen that the user first encounters. It displays the title of the game and listens for a Space-keypress event to launch the game. It also checks for the game reset condition and shows the results accordingly. - Player score is set to 0 and the
scoreboard
andspeechBubble
display are set to hidden. - When the
gameStatus.getResetGame
istrue
the game is reloaded and this action is performed by reloading the current browser window on which the game is executing. Thus all the variables and constant values are reset automatically.
Start Game:
- The
startGame()
method executesSpeech()
method which initiates the Web Speech API,dinoRun()
method is called to initialize player character in the game,groundMove()
method is called to render the game’s background. - The
quizQuestionAnswer
object’s setter methodsetQuestion()
is called which takes a question object as an argument to initialize the questions for the quiz, Thescoreboard
display is set to visible here.
Game Over:
- The
gameOver()
method gets executed when thegameReset
property of thegameStatus
object isfalse
, i.e., when the player has collided with the obstacle. - It displays the correct answer for the corresponding question and dispatched the reload event.
Reload Game:
- The
gameReloadEvent
is a custom event listener triggered by thegameOver()
method; it sets thegameOver
andgameReset
flag tofalse
andtrue
, respectively, and calls theinitGame()
method.
Congratulations! You made it through. I hope you had fun and have learnt something new today. As we have coded our way out, it’s time to run the game. By now, you must have created three files, namely
- HTML file
- CSS style-sheet
- JavaScript fileoceanhero.today
Before we execute the HTML file, we have to set up a local server. One of the easiest ways to do this for our purposes is to use Python’s SimpleHTTPServer
or http.server
, depending on the version of Python installed. If you have no clue what I am talking about, then follow the links below-
Launching Dino Quiz:
- Open a command prompt and change the current directory path to the path where you have stored the files for the Dino Quiz game using
cd
command. - Type the command on the terminal below to start a local server
# If Python version returned above is 3.Xpython3 -m http.server# On windows, try "python" instead of "python3", or "py -3"# If Python version returned above is 2.Xpython -m SimpleHTTPServer
- For accessing the local server you need to visit
http://localhost:8000/
, Port8000
is default. - The game will launch, or you will see a directory listing in the web browser, open the HTML file you have created for the game to launch.
Demonstration:
- You might see lag in the video below, it’s due to the screen recording software, and no such lag issue was experienced in actual.
Resources:
- The image used in the project is available on the Chromium Open Source Project. The link is given below-
offline-image