Garry Owen. - Learn To Code Learn HTML, CSS & JavaScript & Build A Website, App and Game (2022)
Garry Owen. - Learn To Code Learn HTML, CSS & JavaScript & Build A Website, App and Game (2022)
LEARN TO
CODE
Learn HTML, CSS & JavaScript
& build a website, app and game
Written by
Garry Owen
I
LEARN TO CODE HTML, CSS & JAVASCRIPT
II
LEARN TO CODE HTML, CSS & JAVASCRIPT
CONTENTS
INTRODUCTION............................................................................................................... 2
WHAT WILL YOU NEED? ............................................................................................. 2
ABOUT THE AUTHOR ................................................................................................... 2
CONVENTION USED IN THIS BOOK ............................................................................... 5
LESSON OBJECTIVE: .................................................................................................... 5
WHAT IS THE ‘HELLO, WORLD’ PROGRAM?............................................................. 5
STEP❶ - CONVENTIONS EXAMPLE ........................................................................... 5
HELLO, WORLD! .............................................................................................................. 8
LESSON OBJECTIVE: .................................................................................................... 8
WHAT IS THE ‘HELLO, WORLD’ PROGRAM?............................................................. 8
STEP❶ - CHOOSE A SUITABLE CODING EDITOR ..................................................... 8
STEP❷ - SET-UP YOUR FILE STRUCTURE ..................................................................... 8
STEP❸ - DEFINE YOUR HTML STRUCTURE ................................................................. 9
STEP❹ - EXPLORING THE USE OF CASCADING STYLE SHEETS.............................. 11
WHAT ARE CASCADING STYLE SHEETS? ................................................................. 11
STEP❺- ADD MULTI-LANGUAGE SALUTATIONS ..................................................... 14
STEP❻ - JAVASCRIPT FUNCTIONS .......................................................................... 16
WHAT IS A JAVASCRIPT FUNCTION? ...................................................................... 16
STEP❼ - ADDING IMAGES ....................................................................................... 22
FAST ACCESS WEB MENU ............................................................................................ 26
LESSON OBJECTIVE: .................................................................................................. 26
STEP❶ - INFORMATION GATHERING...................................................................... 26
STEP❷ - ARRANGING THE FILE STRUCTURE............................................................ 26
STEP❸ - DOWNLOADING AND PREPARING IMAGES .......................................... 27
STEP❹ - IMPLEMENTING THE HTML FILE STRUCTURE .............................................. 28
STEP❺ - PAGE LAYOUT DESIGN.............................................................................. 29
III
LEARN TO CODE HTML, CSS & JAVASCRIPT
IV
LEARN TO CODE HTML, CSS & JAVASCRIPT
V
LEARN TO CODE HTML, CSS & JAVASCRIPT
VI
LEARN TO CODE HTML, CSS & JAVASCRIPT
~1~
LEARN TO CODE HTML, CSS & JAVASCRIPT
INTRODUCTION
Sit back, strap yourself in and get ready for a fantastic learning
experience. This book will take you through easy-to-follow, step-by-step
lessons and give you all of the guidance you need to write your first
program with some flair, make a useful website that will give you fast
access to all of your favourite places online, make a quiz app that fits
smartly onto your mobile phone and finally make a platform game. Top-
notch!
This book is designed for you to be able to code everything and run it in a
browser, and program it locally on your PC or Mac. In fact, by design
HTML, CSS, and JavaScript can be run in any browser and coded in almost
any text editor.
Everything you need is available for free on Windows and Mac. Better
than that, what you need is built-in, if that’s the way you decide to go.
However, I would recommend using the Google Chrome browser (this is
not essential, you can use almost any browser), Visual Studio Code
(…again not essential, you can use Notepad or similar if you wish) and
lastly a hint of patience as you learn.
I have been coding in various languages for almost four decades. I work as
an IT Director and have been employed in Director level roles for almost a
decade.
~2~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, so each step here can be further broken down, but that is only
necessary if you need further clarification to understand the steps. That is
the same with computer programming and indeed any other problem
that you might face in your life.
For someone with prior knowledge, the instruction, ‘make a cup of tea’ is
more than adequate. Shy of a please and thank you of course!
You only need to break down a problem far enough for you to be able to
understand it. When you need to tackle a problem I highly recommend
this philosophy.
~3~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~4~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Each lesson is laid out in easy-to-follow steps. See the example below:-
LESSON OBJECTIVE:
Since the first “Hello, World!” program was written in 1972, it's become a
tradition amongst computer science teachers and professors to introduce
the topic of programming with this example. As a result, “Hello, World!” is
often the first program most people write. However, we are not going to
write any old ‘Hello World’ program. We’re going to do it ‘The Right Way!’
and in style.
~5~
LEARN TO CODE HTML, CSS & JAVASCRIPT
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CDN CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstra
p/3.4.1/css/bootstrap.min.css">
~6~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~7~
LEARN TO CODE HTML, CSS & JAVASCRIPT
HELLO, WORLD!
LESSON OBJECTIVE:
Since the first “Hello, World!” program was written in 1972, it's become a
tradition amongst computer science teachers and professors to introduce
the topic of programming with this example. As a result, “Hello, World!” is
often the first program most people write. However, we are not going to
write any old ‘Hello World’ program. We’re going to do it ‘The Right Way!’
and in style.
Within it, make another folder named ‘css’, a folder named ‘js’, and
finally, a folder named ‘images’. Next, open your chosen coding editor,
make a new file and save your empty file as ‘hello.html’, within your ‘hello
world’ folder.
~8~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If you have followed these steps correctly you should have the following
file structure - a folder called ‘hello world’ and one file (hello.html) and
three folders:
<html>
<head>
</head>
<body>
</body>
</html>
To tell the browser we want to display an HTML page, we begin with the
<html> opening mark-up.
Next, we have the <head>. Within the opening and closing <head> and
</head> tags we put links to external files, such as CSS and JavaScript, as
~9~
LEARN TO CODE HTML, CSS & JAVASCRIPT
well as this we can include meta data and incorporate page styles if we
desire, plus much more.
Lastly, we have the <body>. Within the <body> and </body> tags we put
the main content of the webpage.
<head>
<title>Hello</title>
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
OK, you’ll already recognise the HTML file structure. So, what else do we
have?
<title>Hello</title>
This sets the page title, which can be viewed on the page tab of your
browser.
<link rel="stylesheet" href="css/app.css">
This connects to an external style sheet, which can be found in the ‘css’
folder. The external style sheet provides a list of styling rules for your
HTML page.
NB! Your code will NOT be syntax highlighted if you are using Notepad.
Instead, it will be displayed as plain black text.
~ 10 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
You can now double click on your ‘hello.html’ file to open it in your
default browser. You’ll get a white page with the <h1> title ‘Hello, World!’
displayed in your browser’s default font. So far, it’s plain and frankly quite
dull, but we’re far from done yet though.
Next, we’ll explore the use of Cascading Style Sheets with our HTML mark-
up.
Cascading Style Sheets are used to format web pages. For example, CSS
can be used to define colour, width, height, margins, opacity, padding,
etc. There are three ways that you can implement CSS: internal, external,
and inline styles. All of these will be explained in detail through the book.
How does CSS (Cascading Style Sheets) work with our HTML mark-up?
As we said above, CSS provides a set of rules for formatting the layout and
styling of an HTML page. These rules are applied using either id, class, or
keyword selector. A CSS selector is the first part of a CSS Rule. It is a
~ 11 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
pattern of elements and other terms that tell the browser which HTML
elements should be selected to have the CSS property values inside the
rule applied to them. If that sounds like gobbledygook, don’t worry too
much right now. It will all become clear.
Now make a new file called app.css and save it in the ‘css’ folder. Then
add the following code:
html, body {
margin: 0px;
background-image: linear-gradient(to bottom right, #95d9f9, #ae4bc3);
}
h1 {
color: #1b95cd;
font-family: tahoma, sans-serif;
}
At the moment, there are only two elements on our webpage. That is the
h1 heading and the html / body of the page. If you look at the web page
now and refresh it you will see that these two elements have had styling
rules applied to them.
~ 12 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The background and font have been coloured and the font has been
changed. Let’s take a closer look.
Firstly, we can see that the margin is set to 0 pixels. This command means
all margins are set to zero. Margins can be set separately using margin-
left, margin-right, margin-top, and margin-bottom or as a combined
margin command. When used in this way, you can still set the
independent values, like so:
margin: 0px 0px 0px 0px;
Where the first 0px is for the top, the next for the right, the next for the
bottom, and the last one is for the left. (TRBL).
In other words, the frame will be rendered into the user's view tight into
the corners of the screen.
Next, we style the body element with a linear gradient. It is set to the
bottom right, which means the gradient will render from the top left of
the page to the bottom right. After the comma, we have #95d9f9,
which is a hexadecimal code for a shade of light blue and finally, we have
#ae4bc3, which is a hexadecimal code for a shade of purple.
Next, we styled the h1 tag. This means anything on the page between an
<h1> and </h1> will be styled with the rules set.
Firstly we set the font colour. Notice color is spelled in the American way
in code. The colour is set using a deeper blue with the hex code:
#1b95cd;
Colours can be set in one of three ways. One as a hexadecimal
code, as demonstrated, two as an RGB code, and third, some
colours can be set by name. For instance, red, blue, green. We’ll
be using hex codes and RGB and RGBA codes throughout this book
because they give greater control over the output.
~ 13 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Replacing the:
<h1>Hello World!</h1>
Line of code.
~ 14 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
There is only one real difference here. That is the addition of the classes
inside each of the <h1> tags. Presently they have no effect and each of
the <h1> tags is simply following the existing rules we made for the <h1>.
Next, we are going to spice things up a bit more by adding some
JavaScript. JavaScript can utilise classes, keywords, and ids in much the
same way as CSS.
~ 15 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Make a new file called app.js and save it in the ‘js’ folder. Then enter the
following code.
//Generate salutations
//t - top, l - left, c - colour, s - font-size, z - z-index, id - class
~ 16 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
We’ll need to connect this script to our template in the ‘hello.html’ file.
Edit it as follows:
Just inside the </body> tag add the following line of code:
<script src="js/app.js"></script>
//Generate salutations
//t - top, l - left, c - colour, s - font-size, z - z-index, id – class
This part of the code is comments to help you to remember the purpose
of the code if you ever revisit it. You can use the // double forward slashes
in front of any text in JS to comment out a single line, as well as /* as the
opening and */ as the ending to comment over many lines, like this:
/* Generate salutations
t - top, l - left, c - colour, s - font-size, z - z-index, id - class */
This second style of commenting can also be used in CSS for commenting
your code. This is a highly recommended practice. You should always
~ 17 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, so the first line here opens the function which we’ve named sals
and passed the parameters t, l, c, s, z, and id. That’s all done with the one
line of code.
And at the end of the function, we close it with the curly brace.
~ 18 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
So essentially this line of code is saying connect to the class given by the
id parameter.
The next line of code changes the top CSS style to a new given value in the
parameter t.
sal[0].style.top = t;
Each of the remaining lines of code inside the function’s open and close
curly braces { and } changes a specific style for the given parameter, as
our comments suggest.
t – top – How many pixels from the top of the screen
l – left – How many pixels from the left of the screen
c – colour – What colour to display the text in
s - font-size – The desired font size
z - z-index – Overlay level – 1 appears in front of 0
id – class – Our chosen class name
~ 19 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
That brings us neatly on to our set of function calls. Without calling the
function the code within it will not run. Each of our function calls does the
same thing, with exception of changing the given parameters. Let’s
examine the first function call to get a better idea.
sals();
This will call the function called sals but passes no parameters. In our
case, it would throw an error that can be viewed in your browser console,
but otherwise, it would appear to do nothing because we need to pass
our parameters for our code to do what we want to achieve.
~ 20 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
opacity: 60%; does what it says on the tin. It makes each of the
salutations slightly transparent, 60% opaque, or 40% transparent,
depending on what perspective you choose to view it from. Opacity can
also be set with decimals. 1 being equal to 100% opaque, while 0 is
invisible. Opacity can be set in increments between 0.0 and 1 with lower
values being more transparent.
position: absolute; allows the top and left parameters in our
JavaScript function to update our CSS position property. There are seven
properties for positioning in CSS. Namely, static (this is the default value),
absolute, fixed, relative, sticky, initial, and inherit. For now, all you need
to know is that position: absolute allows us to position elements on the
screen in exact locations, based on top and left coordinates.
Now refresh
your browser
and take a look
at the results.
It’s starting to
look more
interesting!
~ 21 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Our initial program said ‘Hello, World’, so let’s do something with the
world part. That’s where our images folder comes in.
https://wddtrw.co.uk/resources/learntocode/images/world.gif
Save the image into your images folder within your file structure. To do
so, go to the given link address, right-click on the spinning globe and
choose ‘Save As’, from the context menu. Then choose the images folder
within your file structure and hit the save button.
Note! If you decide to change the file name, you’ll also have to
change it in your code. It is named ‘world.gif’, so the image must
be referenced as ‘images/world.gif’. It is crucial that these
match, otherwise your image won’t display.
Next, edit your ‘hello.html’ file and add the following line of code just
below your opening <body> tag, as shown below. Then save your file.
~ 22 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
This will add a 2px or 2-pixel wide stroke (outline) around the text. This
was added to make the words stand out better from the background.
~ 23 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The globe class has been given 2 rules to follow. Firstly it has been aligned
to the centre of the page and secondly, it has a margin of 150 pixels set
from the top of the visible screen.
The globe image class has been given one rule. This has set the height of
our globe to 70vh or 70 percent of the view height.
Save the file and preview your results. If you have done everything
correctly you should see the following with a spinning animated globe in
the background of your display.
Hey, what a great start. Well done for getting this far!!
All files and images associated with this exercise can be found at:
https://wddtrw.co.uk/resources/learntocode/helloworld.zip
~ 24 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 25 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
LESSON OBJECTIVE:
The first part of any good design is information gathering. This project is
going to be personal to you, so although your result will follow the same
logic for the version in the book, yours will look a little different.
Firstly, you need to choose up to 12 websites that you visit the most
frequently. This can be any website. Take a look at my list below for some
ideas.
Santander Online banking Facebook
YouTube Amazon
AOL Email Zoom
PayPal LinkedIn
Google Maps Twitter
Next, we need to construct the file structure. For this project, it’s a little
simpler than the last. Create a new folder on your desktop called
‘website’. Open it and within it create a folder called ‘css’ and another
~ 26 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
called ‘images’. Finally, open your chosen coding editor and make a new
file. Save it as ‘web_menu.html’.
If you have followed the instructions correctly, you should have the
following file structure:
Next, for each of your chosen websites do a google search and find
suitable images to represent each of them. Choose clear images. Don’t
worry too much about the size right now because I’m going to explain
how you can edit and optimise your images.
Using the same method we used to save the ‘world.gif’ image, search
google images for suitable images and right-click, choose ‘Save As’ from
the context menu, and save each of your images into your images folder.
This time, I recommend that you change the names of the images, for the
sake of clarity and ease of use. For instance, in my case, I’ve named my
first image ‘santander.jpg’. There are many different file formats for
images, therefore, the one you’ve chosen might not be a jpeg. If that is
the case don’t worry, just name it ‘[your filename].[your extension]’. We
can just change the filenames and extensions in our code, to suit.
~ 27 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
correctly, you should have similar to the following in your images folder,
obviously aside from potential different filenames and extensions.
Notice I chose all rectangular landscape images. This will make my result
more uniform. This is a personal choice, it doesn’t really matter. All that
matters is that you have an image to represent each of your chosen
websites.
</head>
<body>
</body>
</html>
~ 28 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
At this stage, we need to think about our page layout. It is a good idea to
make a block diagram of this, to represent what you want to achieve with
your CSS. In my example, I have 10 websites, therefore I have decided on
the following page structure:
Next, we’ll update ‘website.html’ with a title, a link for the CSS file we’ll
create, and explore how we are going to implement the page structure for
our web menu.
Some of this code you have seen before in the last exercise, so you should
already be getting a little familiar and recognising various keywords and
mark-up.
~ 29 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 30 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next, we have a <div> with the class ‘wrapper’. This will be used to
enclose all of the page links into a division (a page section).
Each website link we add will have this code replicated. I have 10 web
pages, therefore I will need to reproduce this 10 times. Once for each of
my page links. You will notice that I haven’t named the class or added any
details to the href, alt title, or src tags yet. That is because for each link
that information will be different.
We have a <div> with a class. The class will be named appropriately for
each page link so that it can be used in the CSS. You will already be
familiar with this code if you’ve completed the last exercise.
Next, we have alt=””, you will notice that this is also shown within the
image tag. This is for alternative text. Or in other words, text that is shown
~ 31 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
to the user if, for some reason, the information or image cannot be
displayed. This can occur when there is a slow connection or an error with
the source file, as an example. Alt tags are also read by screen readers.
With hyperlinks, it is good practice to describe where the link directs to.
They are not strictly necessary, but it is a highly recommended best
practice and forms part of good search engine optimisation (SEO).
The title=””, similar to the alt tag, should carry relevant title information.
This is displayed when hovered with a mouse. A hyperlink and image
carrying these tags are recognised as being well-formed.
Also, we have a class=””, in our image tag. This will be used to style our
images accordingly.
Notice that the <img src="" title="" alt="" class=""> is within the
<a></a>. This can be text or, as we’ve done here, an image. It makes the
image clickable. When clicked the user will be redirected to the given URL.
Finally, we have the footer. The <footer> tag defines a footer for a
document or section.
author information
copyright information
contact information
sitemap
back to the top links
related documents
You can have several <footer> elements in one document.
~ 32 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 33 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Notice how we now have 10 divs with the class name page, 10 links, and
10 images within those links. In this example, I have chosen to style my
~ 34 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
page links the same, it can easily be changed to individual styles, if you
prefer.
Now it’s time to get to grips with our CSS. Open your chosen coding editor
and make a new file called ‘app.css’ and save it in your ‘css’ folder, within
your file structure.
Before we get into that though, let’s choose some colours. I’ve already
mentioned that using hexadecimal codes or RGB codes for colours will
give far greater options.
I particularly like the Adobe Colour Wheel Generator. Take a look, via the
link below:
https://color.adobe.com/create/color-wheel
~ 35 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 36 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If it’s not already, open ‘app.css’ and add the following code:
html, body{
margin: 0px;
}
header {
background-color: #EB8716;
color: #fff;
width: 98%;
height: 200px;
margin: 1%;
}
header h1{
text-align: center;
~ 37 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Feel free to change the colour hex codes for your own.
~ 38 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
You can see that we have used two different types of selectors here. The
first type is an element selector and the second is a class selector. There is
also a third that I should mention and that is an id selector.
An element selector uses the form - element e.g. p = style all <p>
elements
~ 39 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
You can see a simple example of this here where we have used:
header h1{
This tells the browser rules that apply only to h1 elements within the
header. This pattern is straightforward, but selectors can be joined into
many forms. We will see more selector patterns as we work through the
book. However, if you want to know more about selectors, a simple
google search will reveal a host of options.
Most of the rules are repeated, so we’ll just examine distinct rules. You
can then apply that knowledge to others too. Some of the rules, you have
also seen before. That said, let’s take a look.
background-color: #EB8716;
//CHANGES THE BACKGROUND COLOUR
color: #fff;
// CHANGES THE TEXT COLOUR
width: 98%;
// CHANGES THE WIDTH OF THE ELEMENT
height: 200px;
// CHANGES THE HEIGHT OF THE ELEMENT
margin: 1%;
// SETS ALL MARGINS OF THE ELEMENT
~ 40 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
text-align: center;
// ALIGNS THE ELEMENT TO THE CENTRE
padding: 20px;
// ADDS PADDING AROUND THE ELEMENT
display: inline-block;
// DISPLAYS THE ELEMENT ACROSS THE PAGE AND WRAPS IT AT THE EDGE OF THE
DISPLAY
It is recommended for you to experiment with these values and see the
results for yourself. That is the best way to learn.
You can rest easy in the knowledge that all of the files are available to
download, if you make a mistake you cannot resolve.
Okay, next we’re going to add the images source information, the
alternative text, titles, and image class.
Open your images folder and add all of your image information to each of
the image src=”” placeholders, one at a time, in the form:-
‘images/[image name].[extension]’
images/amazon.png images/paypal.png
images/aol.jpg images/santander.png
images/facebook.png images/twitter.png
images/googlemaps.png images/youtube.png
images/linkedin.png images/zoom.jpg
~ 41 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Fill in the alt text and title as appropriate and add ‘image_link’ as the
class.
~ 42 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
<div class="page">
<a href="" alt="" title="">
<img src="images/linkedin.png" title="LinkedIn"
alt="LinkedIn Link" class="image_link">
</a>
</div>
<div class="page">
<a href="" alt="" title="">
<img src="images/paypal.png" title="PayPal"
alt="PayPal Link" class="image_link">
</a>
</div>
<div class="page">
<a href="" alt="" title="">
<img src="images/santander.png" title="Santander"
alt="Santander Link" class="image_link">
</a>
</div>
<div class="page">
<a href="" alt="" title="">
<img src="images/twitter.png" title="Twitter"
alt="Twitter Link" class="image_link">
</a>
</div>
<div class="page">
<a href="" alt="" title="">
<img src="images/youtube.png" title="Youtube"
alt="Youtube Link" class="image_link">
</a>
</div>
<div class="page">
<a href="" alt="" title="">
<img src="images/zoom.jpg" title="Zoom" alt="Zoom
Link" class="image_link">
</a>
</div>
</div>
<footer>
<p>© Copyright Garry Owen 2022</p>
~ 43 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
</footer>
</body>
</html>
Let’s make a quick update to our CSS to address the image class we just
added.
This is to make all of your images appear uniformly the same size.
margin: 1% 0 1% 1%;
This sets the margin with a slight offset to give a kind of 3D drop shadow
effect. Remember margin settings are Top, Right, Bottom, and Left (TRBL).
I always think of the word ‘trouble’ to help remember this. So the next
time you’re having TROUBLE trying to remember the order, hey presto!!
~ 44 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
This simply means, when you hover an element, with the class of
‘image_link’ with a mouse, the rules are applied.
Looks pretty good. And if we hover over an element, what does that look
like?
~ 45 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
You can see here, we are hovering over the Facebook link.
All we have left to do now is fill in the URL information in the href=””
placeholders, fill in the alternative text, and add our titles. Let’s take one
example:
<a href="https://amazon.co.uk" alt="Visit Amazon" title="Visit Amazon">
~ 46 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If you don’t want to open your links on the same page, you
can add a target attribute to your anchor tag: target="_blank"
This will open the link in a new tab when clicked.
Amazing stuff!!
~ 47 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 48 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
<div class="page">
<a href="https://youtube.com" alt="Visit Youtube"
title="Visit Youtube">
<img src="images/youtube.png" title="Youtube"
alt="Youtube Link" class="image_link">
</a>
</div>
<div class="page">
<a href="https://zoom.us" alt="Visit Zoom" title="Visit
Zoom">
<img src="images/zoom.jpg" title="Zoom" alt="Zoom
Link" class="image_link">
</a>
</div>
</div>
<footer>
<p>© Copyright Garry Owen 2022</p>
</footer>
</body>
</html>
As was said earlier in the exercise, your version will look a little different,
have different links, and may have different colours and fonts chosen, but
the functionality should be the same.
I use a similar program to this every day with over 50 of my most visited
sites. I have so many sites that I use often, I find the tools that are built
into browsers are not as convenient. I hope you can make great use of
this going forwards, as I have.
Copy the URL for your menu and put it on your book marks
bar for fast access, whenever you need it!
~ 49 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The final result. Have a play around with it. See if you can improve it. Why
not add another row of links or add animation? Be imaginative!
All files and images associated with this exercise can be found at:
https://wddtrw/resources/learntocode/fastaccesswebmenu.zip
~ 50 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 51 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 52 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Later in this book, I will demonstrate how to deploy your projects onto a
remote server and make them publicly accessible.
https://viewbook.at/wddtrw1
LESSON OBJECTIVE:
Here goes nothing, guys! Let’s start building our next exciting project.
Firstly, let’s implement our required file structure.
~ 53 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
By now you should be getting familiar with setting up your file structure.
This time we need a new folder on your desktop called ’web app’. Within
that folder add a ‘css’ folder, an ‘images’ folder, a ‘js’ folder, and a ‘json’
folder. Finally, open your chosen coding editor and make a new file called
‘quiz_app.html’. If you have done everything correctly you should have a
folder called ‘web app’ with the following file structure:
So you’ve seen the other folders before, but what’s that ‘json’ folder?
Normally, we would use a database to allow a user to add and delete
data. For this exercise, we are going to mimic that functionality by writing
to a JSON file.
JSON-like documents are used as the data structure for a NoSQL text-
based database system, called MongoDB. If you want to learn more about
that, take a look at the link below. However, we won’t be using it here.
https://www.mongodb.com/
~ 54 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The JSON string defines 3 properties (name, age, and car) and each
property has a value. If you parse the JSON string with JavaScript, you can
access the data as an object, like this:
~ 55 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
So let’s put that all together and take a look at how we would pass our
JSON string into a JavaScript object.
<html>
<head></head>
<body>
<h2>Convert JSON string into a JavaScript object.</h2>
<div id="result"></div>
<script>
//JSON String
const person = '{"name":"Garry Owen", "age":47, "car":"BMW"}';
</script>
</body>
</html>
~ 56 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If we take a quick look we can see that we have placed our JSON string
into a constant called person. Then we have created a new JavaScript
object and parsed our JSON ‘person’ string into it and displayed the
results in our <div>, by selecting each of the key-value pairs by
referencing the key properties of our object (obj).
You should be fairly familiar with the HTML structure by now. Before we
add any trimmings, add the mark-up below to our ‘quiz_app.html’ file.
<html>
<head>
</head>
<body>
</body>
</html>
~ 57 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, so first we want to style the layout with a header, footer and
content attributes. We have a question and 4 possible multi-choice
~ 58 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
answers and prevision for a previous and next button. With that decided
let’s add some mark-up to our HTML file.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="user-scalable=no, width=device-width"
/>
<link rel="stylesheet" type="text/css" href="css/app.css">
<title>Question Time</title>
<script type="text/javascript"
src="json/questions.json"></script>
<body>
<div id="header">
<h1>Question Time<br>The Quiz App</h1>
</div>
<div class="quiz-wrapper">
<div id="quiz"></div>
</div>
<button id="previous"><p>Previous Question</p></button>
<button id="next"><p>Next Question</p></button>
<button id="submit"><p>Submit Quiz</p></button>
<div id="results"></div>
<div id="footer">
<h5>Written by Garry Owen © Copyright December 2021</h5>
</div>
<script src="js/app.js"></script>
</body>
</html>
Okay, so we’ve got our basic mark-up. Let’s examine it more closely.
Much of this mark-up you have seen before, but we have a few new tags
in there too.
The first line of code we hit inside the head is:
<meta name="viewport" content="user-scalable=no, width=device-width" />
~ 59 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
This line tells the browser that on a touch screen device the user
shouldn’t be able to zoom in and out. This is intentional so that the web
app fits nicely on a phone screen. It also set the width of the web page to
the device width. That will mean that it will fill 100% of the width of a
device. By default, the user is allowed to scale the screen, but they won’t
need to for our web app because it’ll be easy to read and navigate.
Next we have:
<link rel="stylesheet" type="text/css" href="css/app.css">
<title>Question Time</title>
You should be familiar with these two lines by now. The first connects the
external CSS file and the next gives the page its title.
This opens a new div with the id of header and adds a <h1> title within
the header.
Then, we have:
<script type="text/javascript" src="json/questions.json"></script>
~ 60 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next, we have three <button> tags. These will perform our user interaction
requirements for our quiz.
<button id="previous">Previous Question</button>
<button id="next">Next Question</button>
<button id="submit">Submit Quiz</button>
Next, we have our footer. Change the information here to reflect your
name and the correct date.
<div id="footer">
<h5>Written by Garry Owen © Copyright December 2021</h5>
</div>
Notice that we have used a <h5> tag. This will display the text as smaller
text and set the hierarchy for our search engine, as explained previously.
~ 61 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
<script src="js/app.js"></script>
</body>
This is because the order in which the code is read is paramount. HTML
loads from top to bottom. The head loads first, then the body, and then
everything inside the body. We are making sure it is read last after we have
declared our HTML tags with various classes and ids. If we put it in the head,
the JavaScript wouldn’t recognise those attributes, as they wouldn’t have
been read by the browser yet.
~ 62 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
That will keep our file much shorter. For the purpose of our web app we’ll
call all of the questions ‘data’, by declaring the name and wrapping the
whole thing in square brackets, like this:
data = [
{question: "", answers: {a: "", b: "", c: "", d: ""}, correctAnswer: ""},
{question: "", answers: {a: "", b: "", c: "", d: ""}, correctAnswer: ""},
{question: "", answers: {a: "", b: "", c: "", d: ""}, correctAnswer: ""},
{question: "", answers: {a: "", b: "", c: "", d: ""}, correctAnswer: ""},
{question: "", answers: {a: "", b: "", c: "", d: ""}, correctAnswer: ""}
];
This demonstrates how 5 questions would look. Notice that the last
question has the comma removed from the end.
I’m going to add 20. You can add as many or as few as you like.
Take your time and add your questions, as below before moving on to the
next step. Note! You can download my questions via the link at the end of
this section, if preferred.
{
question: "The Plaka is the oldest quarter of which city?",
answers: {
a: " Athens",
b: "Prague",
c: "Rome",
d: "Vienna"},
correctAnswer: "a"
},
I have laid it out here so that it is easier for you to see what I have done. Of
course, if you prefer to keep the layout like this, then that’s great too!
~ 63 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If you take a look at how our web app looks at this stage, it’s very plain and
dull. The elements are there, but it doesn’t have the look and feel of a web
app just yet.
Next, make a new file called ‘app.css’ and save it in the ‘css’ folder.
Referring back to our layout diagram and our HTML we need to style the
following elements.
~ 64 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 65 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
}
button p{
margin-top: -8px;
}
button{
font-weight: 200;
font-size: 20px;
width: 300px;
height: 50px;
padding: 20px;
cursor: pointer;
border-radius: 3px;
color: #fff;
background-image: -webkit-gradient(linear, left top, left bottom,
from(#aaa), to(#888));
margin-top: 15px;
}
button:hover{
background-image: -webkit-gradient(linear, left top, left bottom,
from(#bbb), to(#999));
}
.quiz-wrapper{
position: relative;
height: 200px;
margin: 30px 0 60px 0;
}
.rad_butn {
transform: scale(200%);
margin: 0 30px 0 -20px;
}
#results{
margin-top: 15px;
padding: 20px;
}
.slide{
position: absolute;
left: 0px;
top: 0px;
width: 100%;
~ 66 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
z-index: 1;
opacity: 0;
transition: opacity 0.5s;
}
.active-slide{
opacity: 1;
z-index: 2;
}
#footer {
position: absolute;
bottom:0;
width:100%;
height:40px;
text-shadow: 0px 1px 0px #fff;
background-image: -webkit-gradient(linear, left top, left bottom,
from(#ccc), to(#999));
}
#footer h5{
text-align: center;
margin-top: 10px;
font-size: 15px;
}
At first glance, this looks quite long and complex, but you’ll soon see
when we break it down that each element is straightforward.
Just a quick reminder, you don’t have to type all of this in. All files are
available to download. A download link is at the end of every exercise.
Before we break it down, let’s take a look at the result, so that we can
visualise our expected result so far. However, keep in mind that the result
will look a little different because we will also be manipulating our CSS
with our JavaScript code in the next section.
~ 67 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
So let’s take a look at the CSS. We’ll break this into elements, as we go.
Starting off with the <body> element rules.
body{
margin: 0; // Set all margins to 0px (TRBL)
padding: 0px; // Set padding to 0px (Space around an element’s content)
font-family: Arial; // Set font to Arial font face
font-size: 20px; //Set the font size to 20px
text-align: center; //align text to the centre
background-color: #eee; // set the background colour to off white
overflow-x: hidden; // prevent scrolling on the X axis
}
~ 68 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 69 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
}
#header h1{ //These rules only apply to <h1> elements within the header
div
text-shadow: 0px 1px 0px #fff; // text shadow - offset-x | offset-y
| blur-radius | colour
font-weight: 300; // Set font thickness to thin (900 max)
margin: 0px; // Set all margins to 0px (TRBL)
padding: 10px; // Set padding to 10px
font-size: 25px;// Set the font size to 25px
}
All of these commands you have seen above. These won’t do anything yet
but will affect the questions and answers layout. They will be used with
JavaScript in the next section. More on that later.
button p{ // This only affect elements inside the button and p tags
margin-top: -8px; //Moves button text up 8px
}
button{ // This affects all elements within the button tags
font-weight: 200; // Font thickness
font-size: 20px; // Font size in pixels
width: 300px; // Width of the buttons
height: 50px; // Height of the buttons
padding: 20px; // Padding around the elements content
~ 70 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The cursor CSS command has many settings for different purposes. See the
diagram below for details:
~ 71 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 72 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
You’re doing great! Before you move on to the next step have a well-
deserved break.
~ 73 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, so hopefully you’ve had a pleasant break and you’re now ready to
face the next part of this exercise. We’re going to tackle this in parts.
We’ll break it down into functions. Each function will perform a particular
task and together they will form the engine to allow the user to interact
with the quiz and get their results.
Open your chosen coding environment and make a new file called ‘app.js’,
and save it in the ‘js’ folder.
Let’s do a quick recap of our HTML structure for our quiz. The main three
elements we’re interested in here are:
<div id="quiz"></div>
<button id="submit"><p>Submit Quiz</p></button>
<div id="results"></div>
In our JavaScript we can select these elements and make references to
them like so:
const quizBox = document.getElementById('quiz');
const resultsBox = document.getElementById('results');
const submitButton = document.getElementById('submit');
In JavaScript, you can set variables in different ways. Each way has slightly
different properties. However, the differences are mainly focussed on the
scope of the variable. Scope refers to the visibility of variables. In other
words, which parts of a program can see or use it.
~ 74 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Block scope
Function scope
Global scope
Before 2015, JavaScript only had Global Scope and Function Scope.
JavaScript ES6 introduced two new important keywords: let and
const.
Block Scope
Function Scope
Global Scope
Next, we need to build the quiz, render the results and allow user
interaction. We can start by laying out the functions and then filling them
in as we go.
function buildQuiz(){}
function showResults(){}
buildQuiz();
~ 75 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
submitButton.addEventListener('click', showResults);
Here we have a function to build the quiz and another to show the
results. We are calling or invoking the buildQuiz function with buildQuiz(),
and when the user clicks on the submit button we are calling or invoking
the showResults function.
Okay, with that understood let’s take a look at how we are going to use
our JSON question bank. In our HTML we have included the
‘questions.json’ file. As we saw earlier we wrapped that in square
brackets and gave the whole dataset the name ‘data’. With that in mind it
is now easy to bring all of our questions into a JavaScript array, like so:
~ 76 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
In our case:
for(i=0; i < data.length; i++){
This line of code pushes the next question into our array. The loop cycles
until it reaches the end of the dataset. In our case called ‘data’.
Add the following code to your ‘app.js’ file and save it.
function buildQuiz(){}
function showResults(){}
buildQuiz();
submitButton.addEventListener('click', showResults);
~ 77 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If at any point your code doesn’t behave the way you expect, you can take
a look at your browser console and get some error information. You can
access it via menu options in your browser or, in Google Chrome, for
example, use shortcut keys ‘CTRL + Shift + I’. Below is an example of a
Google Chrome Console error relating to a Temporal Dead Zone.
Okay, now replace the function buildQuiz(){} with the following function:
function buildQuiz(){
~ 78 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
With that done, let’s take a closer look at what each line of the ‘buildQuiz’
function does.
Next, build the HTML for each question, looping through each question
like so:
myQuestions.forEach(
(currentQuestion, questionNumber) => {
//Code block to be executed here
~ 79 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Now let’s look at the code block we want to execute inside our loop. For
every question, we want to generate the correct HTML, and so our first
step is to create an array to hold the list of possible answers.
const answers = [];
Next, we’ll use a loop to fill in the possible answers for the current
question.
For each possible answer, we’ll create a radio button, which we’re
enclosing in a <label> element. This is so that users can click anywhere on
the answer text to select that answer. If the label was omitted, then the
users would have to click on the radio button itself.
However, you may recall earlier that we made our radio buttons larger.
This will improve overall usability, especially because we are designing
this with a mobile-first approach in mind.
for(letter in currentQuestion.answers){
answers.push(
`<label>
<input type="radio" name="question${questionNumber}"
value="${letter}" class="rad_butn">
${letter} :
${currentQuestion.answers[letter]}
</label>`
);
~ 80 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Once we have our list of answer buttons, we can push the question HTML
and the answer HTML onto our overall list of outputs. Let’s break it down
some more.
for(letter in currentQuestion.answers){
// Code block to execute
You’ll recognise the For Loop from before. However, this is in a slightly
different arrangement and is known as a For…In Loop.
Then, the same as with our JSON file, we need to push the current
question answers into the array.
answers.push( DATA TO PUSH INTO ARRAY );
This adds a block of data into the array. In our case, we are adding:
A radio button
The letter associated with the answer
The answer associated with that letter
~ 81 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
`<label>
<input type="radio" name="question${questionNumber}"
value="${letter}" class="rad_butn">
${letter} :
${currentQuestion.answers[letter]}
</label>`
The join expression takes our list of answers and puts them together in
one string that we can output into our answers div.
Next, we have to bring it all together and push the question and possible
answers into the output array.
output.push(
`<div class="slide">
<div class="question"> ${(questionNumber+1)}.
${currentQuestion.question} </div>
<div class="answers"> ${answers.join("")} </div>
</div>`
);
Notice here we have wrapped our output in a <div> with the class of slide.
We are using this to separate each of the questions, instead of having
them presented as a sequential list. More on that later.
Inside our slide <div></div> we first have our question, presented in its
own div with the class of question.
<div class="question"> ${(questionNumber+1)}. ${currentQuestion.question}
</div>
~ 82 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next, we grab the data from the answers array, like so:
<div class="answers"> ${answers.join("")} </div>
Now that we’ve generated the HTML for each question and answer set,
we can join it all together and show it on the page:
quizContainer.innerHTML = output.join('');
Template Literals
~ 83 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
string is enclosed with back ticks. Informally they are sometimes called
template strings.
Their use is very straightforward. After setting any variable you can use it
within a string.
let age = 37;
let text = `John is aged ${age} years old.`;
console.log(text);
//output - John is aged 37 years old
At this point, you should be able to run the quiz and see your questions
displayed.
~ 84 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Before we move on to the next step, let’s wrap our heads around arrays a
little better.
WHAT IS AN ARRAY?
The simplest way to describe it is, an array is a special variable, which can
hold more than one value. Okay, doesn’t sound too complicated, right?
So a variable can hold one value and an array can hold multiple values.
Great! So why use an array? Why not just store everything as variables?
Variables could work just fine. However, now imagine you need to use
500 values or even 1000. Our list would be very long and all of the
variable names would be difficult to remember.
An array can hold many values under a single name, and you can access
the values by referring to an index number.
For example:
const colours = ["Red", "Green", "Blue"];
~ 85 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The index always begins at 0 and for each additional value added to the
array, the index will increment by 1.
Adding items.
colours.push("Black");//Adds "Black" to the end of the array
colours.unshift("Black");//Adds "Black" to the beginning of the array
Removing items:
colours.pop();//Removes last item
colours.shift();//Removes first item
colours.splice(index, 2);//Removes item at index 2
~ 86 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Joining an array:
const myNewString = colours.join(',');
colours.toString();
There is one final point I wish to make about arrays, in our example, each
item is a string, but in an array, we can store various data types:
strings
numbers
objects
and even other arrays
We can also mix data types in a single array — we do not have to limit
ourselves to storing only numbers in one array and in others only strings.
There is much more we could look at regarding arrays, but that is beyond
the scope of this book. Hopefully now though, you should feel clearer
about arrays and their use.
~ 87 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 88 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Let’s fill in the code we need for our showResults function. Update your
function with the code below and save (CTRL + S):
function showResults(){
const answerBoxs = quizBox.querySelectorAll('.answers');
let numCorrect = 0;
myQuestions.forEach( (currentQuestion, questionNumber) => {
const answerBox = answerBoxs[questionNumber];
const selector = `input[name=question${questionNumber}]:checked`;
const userAnswer = (answerBox.querySelector(selector) || {}).value;
if(userAnswer === currentQuestion.correctAnswer){
numCorrect++;
answerBoxs[questionNumber].style.color = 'green';
}
else{
answerBoxs[questionNumber].style.color = 'red';
}
});
resultsBox.innerHTML = `${numCorrect} out of ${myQuestions.length}`;
}
As usual, let’s break it down.
function showResults(){
//Code to execute
Inside the function, our first job is grab all of the answer boxes from our
quiz:
const answerBoxs = quizBox.querySelectorAll('.answers');
~ 89 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Finally, display the results. How many correct answers out of total
questions:
resultsBox.innerHTML = `${numCorrect} out of ${myQuestions.length}`;
~ 90 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, some of this code we haven’t seen before. Let’s look a little deeper.
const answerBox = answerBoxs[questionNumber];
//Look inside the amswerBox for the current question
~ 91 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
And we applied some styles in our CSS for transitioning from one slide to
the next:
.slide{
position: absolute;
left: 0px;
top: 0px;
width: 100%;
z-index: 1;
opacity: 0;
transition: opacity 0.5s;
}
.active-slide{
opacity: 1;
z-index: 2;
}
Here we can see that the active-slide has an opacity of 1 or another way
of putting it 100% visible, while our other slides have an opacity of 0, in
other words invisible. Plus, we have stacked the active slide on top of the
other slides using the z-index command. The active slide is 2, while the
other slides are 1.
That part is pretty straight forward. Now let’s take a look at the logic that
makes it all happen.
~ 92 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Open ‘app.js’ and add the following code just after the showResults(){}
function:
function showSlide(n) {
slides[currentSlide].classList.remove('active-slide');
slides[n].classList.add('active-slide');
currentSlide = n;
if(currentSlide === 0){
previousButton.style.display = 'none';
}
else{
previousButton.style.display = 'inline-block';
}
if(currentSlide === slides.length-1){
nextButton.style.display = 'none';
submitButton.style.display = 'inline-block';
}
else{
nextButton.style.display = 'inline-block';
submitButton.style.display = 'none';
}
}
function showNextSlide() {
showSlide(currentSlide + 1);
}
function showPreviousSlide() {
showSlide(currentSlide - 1);
}
~ 93 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
showSlide(currentSlide);
submitButton.addEventListener('click', showResults);
// Add the following after this line of code
previousButton.addEventListener("click", showPreviousSlide);
nextButton.addEventListener("click", showNextSlide);
// Note! We are passing the value ‘n’ into this function. The value ‘n’
will be used to represent the value of the current slide.
slides[currentSlide].classList.remove('active-slide');
//Hide the current slide by removing the active-slide class
slides[n].classList.add('active-slide');
//Show the new slide by adding the active-slide class for slide n
currentSlide = n;
//Update the current slide number
~ 94 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
} else{
previousButton.style.display = 'inline-block';
//Otherwise, display the previous button
}
You’re doing great! Next, let’s take a look at the showNextSlide() and
showPreviousSlide() functions:
function showNextSlide() {
showSlide(currentSlide + 1);
//Increment current slide by one
}
function showPreviousSlide() {
showSlide(currentSlide - 1);
//Decrement current slide by one
}
This logic is called when we click the ‘Next Question’, and ‘Previous
Question’ buttons respectively, using the event listeners at the end of the
code.
previousButton.addEventListener("click", showPreviousSlide);
//Listen for a previosButton click. If clicked call the showPreviousSlide
function
~ 95 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
nextButton.addEventListener("click", showNextSlide);
//Listen for a nextButton click. If clicked call the showNextSlide
function
Okay, with that done your quiz should now be up and running.
~ 96 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
This mark-up is where we will display our countdown clock. Next, add the
following line of code, just inside the closing body tag </body>, ensuring it
is after the reference for our ‘app.js’ file.
<script src="js/countdown.js"></script>
This will make the necessary reference to our countdown script, in the
same way, we referenced our ‘app.js’ file.
Next, open the ‘app.css’ file and add the following code to the bottom of
the file (excluding the comments (//…)), then save the file (CTRL + S):
/* ================= COUNTDOWN TIMER =================== */
h2{
color: #333;//Set text colour
font-weight: 100;// Set font thickness
font-size: 40px;// Set font size
margin: 40px 0px 20px; // Set margins (TRBL)
}
#clockdiv{
font-family: sans-serif;//Set font face
color: #fff;//Set text colour to white
display: inline-block; // Set display property
font-weight: 100;//Set font thickness
~ 97 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Great job!
Now, make a new file called ‘countdown.js’ and save it in the ‘js’ folder.
Add the following code (minus the comments (//…)), and then save the
file (CTRL + S). Of course, you can add your own comments, but they
should be much more succinct than these fuller explanations, and the
general rule of thumb, comments should come before the code, not
afterwards.
~ 98 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
function getTimeRemaining(endtime) {
//Open function to get the remaining time with a parameter of ‘endtime’
so that we can return the result and use it outside of this function
function updateClock() {
//Open the update clock function
~ 99 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
const t = getTimeRemaining(endtime);
//Set t variable to the remaining time
if (t.total <= 0) {
clearInterval(timeinterval);
//If the total time is equal to or less than 0 reset the clock
}
}
updateClock();
//Call the updateClock function
~ 100 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
We’ve got a nice looking layout that works for a mobile phone
We have our question wrapper
We’re loading in our question bank
We are taking user input and collecting their answers
We can show results when the user submits the quiz
We have a 3-minute countdown timer
So happens when the timer hits 00 00. Well, right now, nothing at all.
Let’s make it submit the quiz and show us our results.
if (t.total <= 0) {
clearInterval(timeinterval);
◄ Add a function call here to submit the quiz
}
~ 101 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
How do we do that?
showResults();
So what are we doing here? When the timer is either less than (<) or
equal to (=) zero (0) we are clearing the timer and then showing the
results. Save your file and refresh your browser.
Ah, but it didn’t work. That’s simply because we have used an IIFE.
Sometimes an IIFE is great, other times it prevents us from accessing
variables globally, as we need to. Remove your IIFE, save the file, and run
your test again. Now you can see first-hand what an IIFE actually does.
(function(){
// put the rest of your code here
})();
Wrapped around your code. Simply remove it and save your file, then
refresh your browser.
Or we could of course still use the IIFE and copy and paste the countdown
script into our ‘app.js’ file and just have all of our logic in one longer
JavaScript file. However, when we are working with possibly hundreds of
functions, I find it better to structure your code in separate and
specifically named files. That way your code will be cleaner and easier to
bug fix. You will see exactly what I mean in our next exercise when we
start building our platform game.
~ 102 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, so when the timer runs out we no longer need the buttons. We
should remove them to prevent further user input and add a try again
option for the user. We’ll need to add another button to our
‘quiz_app.html’ file and then update our ‘countdown.js’ file. We need to
add the JavaScript logic in the same place as our function call to submit
the quiz, like this:
if (t.total <= 0) {
clearInterval(timeinterval);
showResults();
submitButton.style.display = 'none';
previousButton.style.display = 'none';
nextButton.style.display = 'none';
tryAgainButton.style.display = 'inline-block';
~ 103 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
And then open our ‘quiz_app.html’ file and add the following mark-up just
below the results <div>:
But, we don’t want to show the button unless the timer is at 00 00. So we
also need to add another condition to if (t.total <= 0) { } to be able to
apply the logic for what happens when the clock is greater than 00 00.
This is simple since we have the logic for the true condition, the false is
just an else condition, like so:
} else {
tryAgainButton.style.display = 'none';
}
This is telling the browser not to display the try again button unless the
timer is at zero - 0. This won’t work just yet though. We need to define
the button in the same way we defined the buttons in our ‘app.js’ file.
Due to TDZ, we need to define it before the function call is made to
inializeClock function, like so:
Okay, so now the quiz control buttons are removed and we are displaying
our ‘Try Again?’ button. Great so far, but the button currently has no
functionality. To make the button interactive we need to make a function
that will run a block of code to make the button reset the quiz and then
add an event listener to have JavaScript listen for a button click, which we
will use to call our function. The event listener logic we have seen before
in the ‘app.js’ file. Add the following to the bottom of the ‘countdown.js’
file:
tryAgainButton.addEventListener("click", resetQuiz);
~ 104 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
As you can see, when the button is clicked we are calling a function called
‘resetQuiz’. Great!
function resetQuiz(){
//reset quiz logic
}
Okay, so what does our reset quiz function need to do? For our purposes,
it simply needs to refresh the page, like this:
function resetQuiz(){
location.reload();
}
JavaScript has a built-in method called reload(). Reload() does the same as
the reload button in your browser.
So what about the user knowing how many questions are left? Well, if you
use the same logic as we’ve used for the final results to find the length of
the question bank, we can inform the user how many questions there are
in a variety of ways. As we need to be conscious of available screen
space, I think it will work well to dynamically update the title, depending
on the question bank length. At the moment our web app is entitled
‘Question Time – The Quiz App’. How about we update that to:
‘[number of questions] Questions – The Quiz App’. So in my case, it would
read ‘20 Questions – The Quiz App’. Sounds spot on!
~ 105 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
while <span> keeps everything on the same line. So using a <div> would
scupper our desired layout.
Open the ‘quiz_app.html’ file and update the title to reflect the following:
<div id="header">
<h1><span id="quizLength"></span> Questions<br>The Quiz App</h1>
</div>
document.getElementById('quizLength').innerHTML = data.length;
~ 106 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If you want to make the quiz easier or more difficult, try adjusting the
timer to more or less time.
I think now would be a great time for another break, before we move on
to the final part of this program. Allowing the user to add or delete
questions.
~ 107 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Finally, we want the user to be able to add new questions and delete
existing ones. Essentially to be able to edit the quiz and make it their own.
Something we haven’t used yet is HTML forms. HTML forms are the
obvious way to collect data from the user and allow us to make our data
collection more user-friendly. We know we need the following
information:
The question
Four possible answers
The correct answer represented by a, b, c or d
Once again our design falls into three areas.
~ 108 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 109 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
For your information, there are many databases available. Some of the
most used and well-known are MySQL, MariaDB, and PostgreSQL. These
all use a specially developed language to query them called Structured
Query Language (or SQL, pronounced sequel). Then there is another
database type known as NoSQL databases, such as MongoDB, ApacheDB,
and Cassandra, which utilise alternative structures and query techniques,
such as the JSON-like data structure with MongoDB or CQL with
Cassandra.
For our purposes, we will be writing our questions into our JSON file
instead, but it is important for you to know that if you wanted to create a
program like this one and deploy it on a remote server, you would need
to use other technologies to maintain security over your code and data.
Using HTML, CSS, and JavaScript any user can access all of your code, just
by hitting ‘CTRL + U’ (‘Cmd + U’ on Mac), in many browsers or using the
menu and choosing the ‘view source’ option.
That said, the logic you’ll learn by doing it this way is a very valuable
learning exercise and the same methods can be used in many of your
future projects, perhaps with the addition of server-side technologies to
better handle security aspects, etc.
~ 110 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Once again, open your chosen coding editor and make a new file called
‘add_questions.html’. Then add the following mark-up and save the file in
the ‘web_app’ directory (CTRL + S).
<html>
<head>
<title>Quiz Bank Editor</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen'
href='css/app.css'>
<script type="text/javascript" src="json/questions.json"></script>
</head>
<body>
<div id="header">
<h1>Quiz Bank<br>Add A Question: <span id="qCount"></span></h1>
</div>
<div class="quiz-wrapper">
<form id="addQuestion" onsubmit="submitForm(event)">
<label class="formLabel">Question Number:</label><br>
<label class="formLabel">Question:</label><br>
<textarea maxlength="200" cols="50" rows="5" class="formArea"
placeholder="Add your question here. Include a question mark (?) at the
end." id="q" name="q" required></textarea><br>
<label class="formLabel">Answer A:</label>
<input type="text" maxlength="100" size="100"
class="formInput" id="a" name="a" required><br>
<label class="formLabel">Answer B:</label>
<input type="text" maxlength="100" size="100"
class="formInput" id="b" name="b" required><br>
<label class="formLabel">Answer C:</label>
<input type="text" maxlength="100" size="100"
class="formInput" id="c" name="c" required><br>
<label class="formLabel">Answer D:</label>
<input type="text" maxlength="100" size="100"
class="formInput" id="d" name="d" required><br>
<label class="formLabel">Correct Answer:</label><br>
<select id="ca" name="ca" class="formSelect" required>
~ 111 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
</form>
</div>
<div id="footer">
<h5>Written by Garry Owen © Copyright December 2021</h5>
</div>
<script src='js/addquestions.js'></script>
</body>
</html>
Firstly, we’ve opened a new form element and closed it at the end of the
form structure. We have added an ID to the form so that we can
manipulate it with our JavaScript code and/or our CSS.
<label class="formLabel">Question:</label><br>
~ 112 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Each of the label elements has pretty much the same structure, shy of a
<br> here and there.
<input type="text" maxlength="" size="" class="" id=" " name="" required>
Next, I want to discuss the most common type of form input. Inside each
form input we can set various rules. Some rules are dependent on the
type of <input> we choose, while others apply to any of the available
options.
First, we need to set the input type. Here we have chosen “text”,
however, there are many input types to choose from. The number input
type allows only numbers as input, text allows text and numbers. We
won’t explore them all here, but you can see the range of options in the
list below and over the page:
INPUT TYPES
<input type="button"> <input type="password">
<input type="checkbox"> <input type="radio">
<input type="color"> <input type="range">
<input type="date"> <input type="reset">
<input type="datetime-local"> <input type="search">
<input type="email"> <input type="submit">
<input type="file"> <input type="tel">
<input type="hidden"> <input type="text">
~ 113 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 114 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 115 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
As with input types, there are also a great many HTML form attributes to
choose from, with many different uses. We will explore the ones we need
in more detail, as we progress.
Next we have <textarea></textarea> mark-up.
<textarea maxlength="200" cols="50" rows="5" class="formArea"
placeholder="Add your question here. Include a question mark (?) at the
end." id="q" name="q" required></textarea><br>
Okay, this is slightly different than a form input in that it can occupy more
than one line, and as its name suggests it has an input type of text pre-set.
~ 116 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
id="q" is an ID we can use with either our CSS or JavaScript. In this case,
it is intended for use with our JavaScript. The ‘q’ simply stands for
‘question’.
Finally, name="q", is the name of the input element and can be used to
pass data from a form as reference. Again, more on that later.
Unlike with an <input>, we close a textarea with the close </textarea> tag.
The next 4 inputs are almost identical, with the exception of changing the
values to a, b, c and d respectively:
<input type="text" maxlength="100" size="100" class="formInput" id="a"
name="a" required><br>
Next, we have size="100". That sets the size (width) of the user input
field in the number of characters.
~ 117 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Then we have name="a", this is the name of the input element and can
be used to pass data from a form as reference. We’ll see more on that
later.
Finally, we have the required attribute. Which tells the browser that
the form element MUST be completed by the user, otherwise the form
will not submit and the user will be prompted for input, like this:
We’ll bypass the <label> and look at the next input. This time we have a
different type of input, <select></select>.
<select id="ca" name="ca" class="formSelect" required>
<option value="" selected disabled> Choose </option>
<option value="a"> - A -</option>
<option value="b"> - B -</option>
<option value="c"> - C -</option>
<option value="d"> - D -</option>
</select>
The attributes the <select> carries are much the same as before, ID,
name, class and required, so I won’t go over those again.
~ 118 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Great stuff! Finally we have a <button> to submit our form and parse the
data within the form:
<button id="submit"><p>Submit Question</p></button>
~ 119 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
I think it’s that time again…. Or do I just drink too much coffee?
~ 120 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay we already have our CSS file created, so open ‘app.css’ and add the
following code to the bottom of the file:
/* =========================== FORM STYLES ======================= */
.formLabel{
color: #333;
font-size: 16px;
font-weight: bold;
width: 10%;
}
.formArea{
color: #333;
font-size: 25px;
font-weight: bold;
width: 80%;
}
.formInput{
color: #333;
font-size: 25px;
font-weight: bold;
width: 50%;
}
.formSelect{
color: #333;
font-size: 25px;
font-weight: bold;
width: 25%;
text-align: center;
}
Notice here, we have some of our rules repeated in more than one class. I
am showing you this on purpose because you should always be thinking,
how can I make my code cleaner and more optimised? This won’t only
make your code run more efficiently, but it will be easier to read.
~ 121 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next, are there any rules that apply to multiple classes (or IDs /
Keywords)?
.formArea, .formInput, .formSelect{
font-size: 25px;
}
Ensure you have optimised it as much as you can and then bring it all
together, and add the code to the end of your ‘app.css’ file.
~ 122 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
GET DATA FROM THE HTML FORM AND ADD IT TO THE JSON FILE
Let’s think about the title of this section. It has 2 parts but requires 3
steps.
~ 123 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
In the same way, we’ve tackled our JavaScript logic before, we will place
each element for what we want to achieve into JavaScript functions.
function submitForm(event){
event.preventDefault();
}
The first function is combined with some code added to the HTML form
tag. I.E. onsubmit="submitForm(event)". Together they prevent
the form from submitting in the default fashion and allow us to be able to
gather the form data in the next function.
function getMyData(){
const question = document.getElementById("qn").value +". " +
document.getElementById("q").value;
const a = document.getElementById("a").value;
const b = document.getElementById("b").value;
const c = document.getElementById("c").value;
const d = document.getElementById("d").value;
const correctAnswer = document.getElementById("ca").value;
const newData = { question, answers: { a, b, c, d }, correctAnswer }
if(question != "" && a != "" && b != "" && c != "" && d != "" &&
correctAnswer != ""){
questionBank.push(newData);
document.getElementById('qCount').innerHTML =
questionBank.length;
document.getElementById("addQuestion").reset();
}
return questionBank;
}
We are gathering the values here from our form, one by one, and then
putting them back together in the object form that we require. Each form
~ 124 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
if(question != "" && a != "" && b != "" && c != "" && d != "" &&
correctAnswer != ""){
//here we have a conditional which is only true if all form fields have a
value when the form is submitted
questionBank.push(newData);
//pushes our new question, answers and correct answer (newData) into an
array named questionBank
document.getElementById('qCount').innerHTML =
questionBank.length;
//displays the current number of questions in the bank in the <h1> title
element
document.getElementById("addQuestion").reset();
//clears the form ready for another question to be added
}
//closes the conditional
return questionBank;
//return the updated question bank, making it accessible outside of the
function
}
//Finally, we close the function
~ 125 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next, we have a function that is called when we save our question bank to
local storage. This will allow us to update the question bank and display
the newly updated question set to the user. However, to do that we’ll
need to make some small changes to our ‘app.js’ file too. For now,
though, let’s take a look at our saveMyFile function:
function saveMyFile(){
localStorage.setItem("questionBank", JSON.stringify(questionBank));
location.replace("quiz.html")
}
This function is very simple. We are setting a local storage item with the
name "questionBank" and inserting our question bank into it after
converting it to a JSON string JSON.stringify(questionBank)
The localStorage object allows you to save key/value pairs in the browser.
It stores data with no expiration date. This means the data is not deleted
when the browser is closed and will be available for future use. The
concept behind it is very simple. The syntax is as follows:
localStorage.setItem(key, value); // Store data
localStorage.getItem(key, value); //Retrieve data
localStorage.removeItem(key); //Remove data
~ 126 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
In the last part of our code we have our variable declarations and event
listeners, to listen for when our form is submitted and when the save
question bank button is clicked.
if(dataStored != ""){
//if dataStored is not empty…
~ 127 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
document.getElementById('qCount').innerHTML = questionBank.length;
//update the <h1> title tag with the current number of questions in our
question bank
addQuestionButton.addEventListener("click", getMyData);
//Listen for the submit form button and when clicked call or invoke the
getMyData() function
saveButton.addEventListener("click", saveMyFile);
//Listen for the save question bank button and when clicked call (invoke)
the saveMyFile() function
Okay, so we can now add new questions and save them to local storage.
Okay, so we already know that push() adds data to the end of an array,
and pop() will remove the last item of an array.
We have already added our new questions to the end of the array, but
unlike with adding questions, a user will not only want to be able to
remove the last one. In fact, we need to be able to remove multiple
questions. From a user’s perspective, it would be easier if all questions
were displayed on a list and they could click a tick box and have a button
with the function of removing all of the questions selected in one hit.
~ 128 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Like this:
Okay, let’s build the HTML mark-up. Make a new file called
‘remove_questions.html’ and save it in the main web app directory. Add
the following code and then save (CTRL + S).
<html>
<head>
<title>Quiz Bank Editor</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen'
href='css/app.css'>
<script type="text/javascript" src="json/questions.json"></script>
</head>
<body>
<div id="header">
<h1>Quiz Bank<br>Remove Questions</h1>
</div>
<div class="wrapper">
~ 129 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Aside from the element and attributes that you have already seen, the
main difference here is that we intend to populate the form inside our
show question div <div id="showQstn"></div> using our JavaScript
coding. Therefore, what’s left is a very simple form. The other attributes
have had their id names changed to ensure we don’t get any conflict
issues from other scripts.
~ 130 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Open the ‘app.css’ file and add the following to the bottom:
#showQstn {
text-align: left;
display: block;
margin: 0 auto 0 auto;
width: 420px;
}
#showQstn label:first-of-type{
margin-left: 10px;
}
.chk_butn {
transform: scale(200%);
margin: 10px 30px 5px -20px;
}
.wrapper{
position: relative;
margin: 30px 0 20px 0;
}
#footer2 {
position: relative;
bottom:0;
width:100%;
height:40px;
text-shadow: 0px 1px 0px #fff;
background-image: -webkit-gradient(linear, left top, left bottom,
from(#ccc), to(#999));
}
#footer2 h5{
text-align: center;
padding-top: 10px;
font-size: 15px;
}
~ 131 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, apart from a couple of rules, you have seen all of this CSS by now. In
the vein of avoiding too much repetition, I’ll explain just those
differences.
#showQstn label:first-of-type{
margin-left: 10px;
}
label:first-of-type - this sets rules only for the first label element
The rest we’ve already seen. However, note we have made another
wrapper class and another footer class. This is because existing rules
won’t work for our new HTML page. That is because the layout here is
longer (potentially much longer depending on how many questions the
user decides on) than the original structure for our question and answer
slides.
document.getElementById('quizLength').innerHTML = data.length;
~ 132 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
with this:
if(dataStored != ""){
for(i=0; i < dataStored.length; i++){
myQuestions.push(dataStored[i]);
}
document.getElementById('quizLength').innerHTML =
dataStored.length;
} else {
for(i=0; i < data.length; i++){
myQuestions.push(data[i]);
}
document.getElementById('quizLength').innerHTML = data.length;
}
This works exactly the same way as explained in the ‘addquestions.js’ file,
with the exception that we are updating the ‘quizlength’ attribute
depending on whether we are using local storage ‘dataStored’ or the
JSON file we created for our questions ‘data’, as below:
document.getElementById('quizLength').innerHTML = dataStored.length;
document.getElementById('quizLength').innerHTML = data.length;
Make a new file called ‘removequestions.js’ and save it in the ‘js’ folder,
then add the following code and save (CTRL + S).
~ 133 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
function submitRemoveForm(event){
event.preventDefault();
}
function showQuestions(){
const questionHolder = document.getElementById('showQstn');
questionToShow = [];
const newObject = localStorage.getItem("questionBank");
let dataStored = JSON.parse(newObject);
if(dataStored != ""){
for(i=0; i < dataStored.length; i++){
questionToShow.push(
`<label>
<input type="checkbox" name="${i}" value="${i}"
class="chk_butn">
${i+1}. ${dataStored[i].question.substring(0, 32)}...
</label><br>`
);
}
} else {
for(i=0; i < data.length; i++){
questionToShow.push(
`<label>
<input type="checkbox" name="${i}" value="${i}"
class="chk_butn">
${i+1}. ${data[i].question.substring(0, 32)}...
</label><br>`
);
}
}
questionHolder.innerHTML = questionToShow;
return questionToShow;
}
function removeQuestion(){
const questionHolder = document.getElementById('showQstn');
questionsToRemove = [];
let checkboxes =
document.querySelectorAll('input[type=checkbox]:checked')
for (var c = 0; c < checkboxes.length; c++) {
questionToShow[checkboxes[c].value] = "";
~ 134 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
questionBank.splice(checkboxes[c].value,1);
}
questionHolder.innerHTML = questionToShow;
}
function saveMyFile(){
localStorage.setItem("questionBank", JSON.stringify(questionBank));
location.replace("quiz.html")
}
showQuestions();
const questionBank = [];
const newObject = localStorage.getItem("questionBank");
let dataStored = JSON.parse(newObject);
if(dataStored != ""){
for(i=0; i < dataStored.length; i++){
questionBank.push(dataStored[i]);
}
} else {
for(i=0; i < data.length; i++){
questionBank.push(data[i]);
}
}
const removeButton = document.getElementById("removeQuestions");
const saveButton = document.getElementById("saveQuestions");
removeButton.addEventListener("click", removeQuestion);
saveButton.addEventListener("click", saveMyFile);
function showQuestions(){
const questionHolder = document.getElementById('showQstn');
//reference the showQstn div
~ 135 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
questionToShow = [];
//make a new empty array called questionToShow for storage of questions
and check boxes for the users view
if(dataStored != ""){
//if dataStored contains data
questionToShow.push(
//push into the questionToShow array
`<label>
<input type="checkbox" name="${i}" value="${i}"
class="chk_butn">
//pass the index number if the checkbox is ticked
</label><br>`
//wrap the input in a <label</label> to make the whole thing clickable
);
}
} else {
//otherwise….if there is no questions stored in local storage
~ 136 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
questionToShow.push(
//push each question and checkbox into the questionToShow array
`<label>
<input type="checkbox" name="${i}" value="${i}"
class="chk_butn">
//pass the index number if the checkbox is ticked
</label><br>`
//wrap the input in a <label</label> to make the whole thing clickable
);
}
}
questionHolder.innerHTML = questionToShow;
//display the questions and checkboxes in the question holder
return questionToShow;
//return questions data
}
~ 137 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
questionsToRemove = [];
//make a new empty array where we will store the index numbers of
questions we want to remove
let checkboxes =
document.querySelectorAll('input[type=checkbox]:checked');
//get all indexes from ticked check boxes and store them in a variable
called checkboxes
questionToShow[checkboxes[c].value] = "";
//remove each ticked question from display
questionBank.splice(checkboxes[c].value,1);
//remove each ticked question from the question bank
}
questionHolder.innerHTML = questionToShow;
//display the remaining questions and checkboxes in the question holder
Okay, that was fairly straightforward. Now all that’s left to do is save the
changes in local storage, set our variables, and set up our listeners to
capture any button clicks.
~ 138 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Then we call the main showQuestions() function and set the variables, like
so:
showQuestions();
//call (invoke) showQuestions function
if(dataStored != ""){
//if dataStored is not empty…
questionBank.push(dataStored[i]);
//push each question into the questionBank array
}//close for loop
} else {
//otherwise… if local storage is empty
questionBank.push(data[i]);
//push each question into the questionBank array
}//close for loop
~ 139 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Last, but not least, we reference the buttons for removing and saving
questions as well as setting up event listeners to listen for button clicks.
const removeButton = document.getElementById("removeQuestions");
const saveButton = document.getElementById("saveQuestions");
//reference button by ID and store them in appropriately named variables
removeButton.addEventListener("click", removeQuestion);
//listen for button clicks of the remove question button. When clicked
call the removeQuestion function
saveButton.addEventListener("click", saveMyFile);
//listen for button clicks of the save button. When clicked call the
saveMyFile function
Top class! Now all that’s left to do is enable navigation between the quiz
and admin functions.
For the final part of this exercise, we will need to add a little mark-up to
each of our pages and add a few new rules to our CSS file.
Open the ‘quiz_app.html’ file and add the following inside the <div
id=”header”></div> following the </h1> closing tag:
<span id="menu"></span>
<div id="menubox" style="display: none;">
<br><a href="add_question.html" alt="add questions" title="add
questions"> Add Questions </a><br><br>
<a href="remove_questions.html" alt="remove questions" title="remove
questions"> Drop Questions </a>
<span id="menudismiss"> X </span>
</div>
~ 140 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Then scroll to the bottom of the file and just inside the closing </body>
tag, add the following:
<script src='js/menu.js'></script>
<script src='js/menu.js'></script>
~ 141 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Again, scroll to the bottom of the file and just inside the closing </body>
tag, add the following:
<script src='js/menu.js'></script>
~ 142 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 143 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
#menubox #menudismiss{
position: absolute;
top: 10px;
right: 15px;
color: rgb(102, 100, 100);
}
#menubox #menudismiss:hover{
position: absolute;
top: 10px;
right: 15px;
background-color: rgba(255,255,255,0.5);
font-weight: bold;
}
As with previous additions to our style sheet, you have seen much of the
commands before, so I’ll only explore those we haven’t already covered:
#menubox a:hover
~ 144 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
background-color: rgba(255,255,255,0.5);
//finally, we have seen color and background-color
settings with named colours and hexadecimal colour
codes, but here we are using ‘r, g, b, a’ (red, green,
blue, alpha) settings. ‘r, g and b’ are all values
from 0 – 255 or black through to white, while the ‘a’
represents the alpha channel or opacity channel. The
value we have chosen 255, 255, 255, 0.5 is white in
colour with an opacity of 50%.
Make a new file called ‘menu.js’ and save it in the ‘js’ folder. Then add the
following code:
function htmlMenu(){
const menu = document.getElementById('menu');
const menudismiss = document.getElementById('menudismiss');
menu.innerHTML = '<h1>☰</h1>';
menu.addEventListener("click", displayMenu);
menudismiss.addEventListener("click", dismissMenu);
}
function displayMenu(){
const menubox = document.getElementById('menubox');
if(menubox.style.display == "block"){
menubox.style.display = "none";
} else {
menubox.style.display = "block";
}
}
function dismissMenu(){
const menubox = document.getElementById('menubox');
menubox.style.display = "none";
}
htmlMenu();
~ 145 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
function htmlMenu(){
//open htmlMenu function
menu.innerHTML = '<h1>☰</h1>';
//set the menu to a burger symbol
menu.addEventListener("click", displayMenu);
//add an event listener to check for menu clicks. If clicked open the
menu
menudismiss.addEventListener("click", dismissMenu);
//add an event listener to check for menu dismiss clicks. If clicked
close the menu
}//close function
function displayMenu(){
//open display menu function
if(menubox.style.display == "block"){
//if the menu box is display.ed…
menubox.style.display = "none";
//…remove it from display
} else {
//otherwise, if the menu isn’t displayed
~ 146 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
menubox.style.display = "block";
//display the menu
}//close conditional
}//close function
function dismissMenu(){
//open the dismiss menu function
menubox.style.display = "none";
//remove the menu from the display
htmlMenu();
//call the htmlMenu function
If you followed this exercise correctly you should now have the following
great quiz application.
~ 147 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
All files and images associated with this exercise can be found at:
https://wddtrw/resources/learntocode/quizapp.zip
~ 148 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Platform games, also called platformers, are games in which the player
controls a character that runs/walks and jumps on platforms. Some of the
famous ones are Kong, Sonic the Hedgehog, and Mario Brothers, to name
just a few.
The objective will be to collect all of the jewels while avoiding enemies
and obstacles along the way. This is a multi-part exercise that follows on
in subsequent books. However, by the end of this exercise, you will have a
fully playable platform game and will have learned many skills. That said,
without even knowing it, you have been developing many of the skills you
need while following earlier exercises in this book.
LESSON OBJECTIVE:
Design and develop a web-based platform game using HTML, CSS, and
JavaScript.
~ 149 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Here goes nothing, guys! Let’s start building our final exciting project.
Firstly, let’s implement our required file structure. This time we need
folders to accommodate different kinds of assets. Make a new project
folder called ‘game’ and save it on your desktop or another desired
location. Inside that folder, add the following file structure:
By now you should know how to create these, but in case you need a
reminder. Double click on your ‘game’ folder. Then right-click, and from
the context menu, choose new and then folder enter ‘css’ and hit enter.
Repeat this process for ‘js’, ‘music’, ‘sfx’, ‘sprites’, and ‘tilesets’. Finally,
open your chosen coding editor and create a new file and save it as
‘sorcerer.html’ within the ‘game’ folder. Job done!
~ 150 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Open the ‘sorcerer.html’ file (if it’s not already open) and add the
following mark-up:
<html>
<head>
<title>Sorcerers Mountain</title>
<link rel="stylesheet" type="text/css" href="css/app.css"/>
</head>
<body>
<div id="gameArea">
<canvas id="canvas"></canvas>
</div>
<script type="text/javascript" src="js/assets.js"></script>
<script type="text/javascript" src="js/tiles.js"></script>
<script type="text/javascript" src="js/sprites.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript" src="js/startScreen.js"></script>
<script type="text/javascript" src="js/map1.js"></script>
</body>
</html>
</html>
The vast majority of this mark-up you will already be familiar with if you
have been following the exercises throughout this book. As you can see,
at this stage, it looks quite simple. The good news is that this HTML won’t
get any more complex. We will add references to more JavaScript files as
we build our game, but that is all. Let’s take a closer look at the mark-up.
<html>
//tell the browser we are using HTML
<head>
<title>Sorcerers Mountain</title>
//Add a title to our HTML page
~ 151 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
</head>
<body>
//open the body – the main content area
<div id="gameArea">
<canvas id="canvas"></canvas>
</div>
//add a canvas element within a div. This will be used to display our
game and make necessary references for our CSS and JavaScript commands
</body>
</html>
//close the body and html tags
Create a new file called ‘app.css’ and save it in the ‘css’ folder. Then, add
the following CSS rules:
body, html {
height: 100%;
overflow:hidden;
background: #1f1f1f;
}
canvas{
~ 152 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
#gameArea{
text-align: center;
margin-top: 70px;
}
This is very simple CSS rules. All of which you have seen earlier in the
book. Let’s take a closer look:
body, html {
height: 100%;
overflow:hidden;
background: #1f1f1f;
}
//set rules for the whole html element and the body. Set height to 100%,
do not show scrollbars if the content is larger than the page, and set
the background to dark grey in colour.
canvas{
border:1px solid black;
}
//set rules for the canvas element – make a solid 1 pixel border with the
colour black
#gameArea{
text-align: center;
margin-top: 70px;
}
//set rules for the element with an ID of gameArea. Align the game area
to the centre and 70 pixels from the top of the screen.
As was already said, these are all very straightforward rule sets.
Moving on!!
~ 153 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next, create a new file called ‘assets.js’ and save it in the ‘js’ folder. Then
add the following code and save it (CTRL + S).
var canvas = document.querySelector("#canvas"),
ctx = canvas.getContext("2d"),
width = 1152,
height = 704,
player = {
screen: 15,//15 = START SCREEN
},
press_s = { width: 500, height: 40, f: 100 },
instruct = { x: 126, y: 300, w: 900, h: 57, f: 103 };
What are we doing here? The ‘assets.js’ file is used to set all initial values
and store them in a JSON object. Let’s take a closer look:
var canvas = document.querySelector("#canvas"),
// reference the canvas element by its ID and store it in a variable
called canvas
ctx = canvas.getContext("2d"),
// To enable canvas' 2D rendering context on the canvas element (allows
us to draw in 2D on the canvas)
width = 1152,
//set the canvas width to 1152 pixels – very important that you use a
size that is a multiple of your intended tile size. Our chosen tile size
is 64 pixels x 64 pixels (1152 pixels will accommodate 18 tiles across)
height = 704,
//set the canvas height to 704 pixels. As with the width, it must be a
multiple of your chosen tile size (704 pixels will accommodate 11 tiles
down)
~ 154 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
player = {
screen: 15,
},
//Set up a player object where we will store all start values for the
player. Here we have set the initial screen to 15 which represents the
title screen background, as we’ll see in more detail in the next section
STEP❺ - CREATE AND REFERENCE TILES FOR BUILDING OUR TILE MAPS
Create a new file called ‘tiles.js’ and save it in the ‘js’ folder.
Before we add any code to this file you’ll need to download the tile
images to the ‘tilesets’ folder from the following URL:
https://wddtrw/resources/learntocode/platformgame_building_tiles.zip
Once downloaded, unzip it and add the contents to the ‘tilesets’ folder.
To unzip the file, double click it and then select all of the contents (CTRL +
A) and copy it (CTRL + C), then open the ‘tilesets’ folder and paste (CTRL +
V).
If you have followed this correctly your ‘tilesets’ folder will now contain
the following 64 x 64 pixel tiles, plus 2 background images. You can of
~ 155 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
course choose to make your own. If you wish to do that or edit the ones
from the file to make them a little different you will need an image editor.
If you don’t have access to one I recommend Gimp, which is more than
adequate to do the job, and best of all it’s free. You can download it for
free at https://gimp.org.
We will use these tiles in our game screens using tile maps. More on that
in a bit. For now, let’s set up a JavaScript file to reference them and
enable their usage in our game.
Create a new file called ‘tiles.js’ and save it in the ‘js’ folder, then add the
following code. We will start small here, but add more tiles as we need
them, when building the game.
/* ================================
TILE KEY:
0 - blank space
1 - base block dark grey
2 - base block left - lives
3 - base block right - lives
~ 156 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Firstly, note the extensive comments. This is so that we know which index
number to use when drawing our tile maps.
const tile = [];
tile[i].src = `tilesets/building_tiles/${i}.png`;
//set the source file of the image object
~ 157 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Note, for this method to work the file names need to be sequential and in
the same format. We can also add tiles individually to our tile array using
similar coding, but specifying the index instead of using the ‘for loop’, like
so:
tile[99] = new Image();
tile[99].src = ‘tilesets/building_tiles/[FILENAME HERE]’;
Next, create a new file called ‘sprites.js’ and save it in the ‘js’ folder.
Before we add any code to this file you’ll need to download the images to
the ‘sprites’ folder from the following URL:
https://wddtrw/resources/learntocode/platformgame_title_sprites.zip
Once downloaded, unzip it and add the content to the ‘sprites’ folder. To
unzip the file, double click it and then select all of the contents (CTRL + A)
and copy it (CTRL + C), then open the ‘sprites’ folder and paste (CTRL + V).
~ 158 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
This works in the same way as to how we referenced our tiles. As with our
tiles, we will also be adding many more sprites as we get further into our
game development.
Open your chosen coding environment, if it’s not already open, and
create a new file called ‘main.js’ and save it in the ‘js’ folder. Then add the
following code and save it (CTRL + S).
canvas.width = width;
canvas.height = height;
function update() {
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = "#333";
ctx.beginPath();
~ 159 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The ‘main.js’ file will hold the code that will enable us to load different
maps based on key presses and/or the player leaving the confines of the
current game screen. We will be adding lots more logic here as we build
the game. For now, let’s take a deeper look at what we’ve done so far:
canvas.width = width;
//bring in the initial setting canvas width from our assets file
canvas.height = height;
//bring in the initial setting canvas height from our assets file
~ 160 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
});
document.body.addEventListener("keydown", function (e) {
keys[e.keyCode] = true;
});
//listen for key down events and get the relevant key code
Next, we are going to create the first script that will display some results.
Create a new file called ‘startScreen.js’ and save it in the ‘js’ folder. Now
add the following code and save it (CTRL + S).
function drawMyMap1000(){
ctx.drawImage(tile[15], 0, 0, 1152, 704);
if(keys[83]){
player.screen = 1;
}
if(keys[73]){
instruct.f = 102; instruct.x = 126, instruct.y = 25, instruct.w =
900, instruct.h = 567;
} else {
ctx.drawImage(sprite[104], 383.5, 380, 385, 24);
instruct.f = 103; instruct.x = 126, instruct.y = 200, instruct.w =
900, instruct.h = 57;
ctx.drawImage(sprite[105], 476, 435, 200, 137);
ctx.drawImage(sprite[106], 342, 275, 469, 85);
}
ctx.drawImage(sprite[instruct.f], instruct.x, instruct.y, instruct.w,
instruct.h);
ctx.drawImage(sprite[press_s.f], 326, 610, press_s.width,
press_s.height);
if (press_s.f === 100){
setTimeout(function(){ press_s.f = 101; },200);
~ 161 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
} else {
setTimeout(function(){ press_s.f = 100; },200);
}
}
Top class! Let’s take a closer look and see what’s going on:
} else {//otherwise….
~ 162 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Once this code has been saved you will now be able to view the title
screen. Open ‘sorcerer.html’ in your browser (Google Chrome
recommended). If you’ve followed the exercise correctly so far, you
should have the following result:
~ 163 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Create a new file called ‘map1.js’ and save it in the ‘js’ folder. Okay, now
add the following code, then save the file (CTRL + S).
function drawMyMap(){
ctx.drawImage(tile[16], 0, 0);
var xt = 0;
var yt = -64;
var tileMap = [];
var mapNo = 0;
tileMap[0] = [6, 6, 6, 6, 6, 6, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6];
tileMap[1] = [6, 0, 0, 0, 10, 0, 0, 11, 0, 0, 10, 0, 6, 0, 0, 0, 0, 0];
tileMap[2] = [6, 0, 0, 9, 9, 9, 9, 9, 9, 9, 8, 0, 0, 0, 0, 0, 0, 0];
tileMap[3] = [6, 0, 11, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 9, 9, 0, 6];
tileMap[4] = [6, 9, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 6];
tileMap[5] = [6, 0, 0, 0, 0, 9, 9, 0, 0, 0, 10, 0, 0, 9, 0, 9, 9, 6];
tileMap[6] = [6, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 6];
tileMap[7] = [0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 8, 9, 8, 9, 6];
tileMap[8] = [9, 9, 9, 8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 10, 0, 10, 0, 6];
tileMap[9] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3];
tileMap[10] = [13, 14, 13, 14, 13, 14, 13, 14, 13, 14, 13, 14, 13, 14,
13, 14, 13, 14];
for (mapNo=0; mapNo < 11; mapNo++){
yt+=64;
for (xt=0; xt < tileMap[mapNo].length*64; xt+=64){
if (xt > 1152){ xt = 0; }
var i = tileMap[mapNo][xt/64];
ctx.drawImage(tile[i], xt, yt);
}
}
}
~ 164 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Each of our game maps will be drawn in the same way. Let’s take a closer
look:
function drawMyMap(){
//open the draw map function
ctx.drawImage(tile[16], 0, 0);
//draw the game screen background – a stone wall
yt+=64;
//adds 64 to yt for every iteration of the for loop
~ 165 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
var i = tileMap[mapNo][xt/64];
//set the variable i to hold each tile reference
Great job! If you have followed the exercise correctly when you hold
down the ‘i’ key, you should be presented with the following user
instruction set:
…And if you hit the ‘s’ key you should be presented with your first tile
map, as shown over the page:
~ 166 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Awesome stuff!
~ 167 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
In simple terms, to make the first tile map we have populated a grid that
is 1152 pixels wide and 704 pixels tall, which is split into 64 by 64-pixel
tiles. A representation is shown below:
The rest of the tiles, row 0 to row 8 will be changed to form the game
screens. Where we want to be able to exit to allow our player into other
~ 168 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
screens we’ll need to leave gaps using tile[0]. Designing our next tile map
is a little way off though, so for now, let’s add our main player and give it
a few attributes.
First, you’ll need to download the sprite images to the ‘sprites’ folder
from the following URL:
https://wddtrw/resources/learntocode/platformgame_wizard_sprites.zip
Once downloaded, unzip it and add the content to the ‘sprites’ folder. To
unzip the file, double click it and then select all of the contents (CTRL + A)
and copy it (CTRL + C), then open the ‘sprites’ folder and paste (CTRL + V).
As with previous tiles and sprites, you’ll see that they are numbered
sequentially.
Open the ‘sprites.js’ file and add the following code to the bottom of the
file:
/* ============================
WIZARD KEY:
1 - Wizard Right Frame 1
2 - Wizard Right Frame 2
~ 169 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
This works the same as last time. With each iteration of the ‘for…loop,’ an
image is placed in the wiz = [] array with the relevant index number.
As with the other sprites and tiles, we have commented them with a key,
so that we can quickly see which index number references which sprite.
Great job!
Next, open the ‘assets.js’ file and update the player object, as below and
save the file (CTRL + S):
player = {
x: 608,
y: height – 182,
width: 35,
height: 52,
screen: 15,
start: 0,
f: 3
},
Okay, so we’ve set initial variables for our player. We have set the X
coordinate to 608 pixels across our canvas, the Y coordinate to 522 (704 –
~ 170 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
182), our player height and width to 52 pixels and 35 pixels respectively,
the screen was already set at 15 (the title screen) and finally our
animation frame number (f) to sprite number 3.
Okay, with that done, now open ‘main.js’ and add the following two
conditionals and save the file (CTRL + S):
if (player.screen === 1){ drawMyMap(); } ◄ add the following after
this line of code
if (player.screen != 15){
ctx.drawImage(wiz[player.f], player.x, player.y);
}
//if the player screen is not 15 – no longer the title screen, then draw
the player
Refresh your browser and press ‘s’. You will see that
your player is now displayed.
Now let’s add some controls to make your player move. Once again, edit
the ‘assets.js’ file and add the following highlighted attributes:
~ 171 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
player = {
x: 608,
y: height - 182,// Start height (Must be larger than tile, plus
character height
width: 35,
height: 52,
speed: 3,
velX: 0,
velY: 0,
screen: 15, //15 = START SCREEN
start: 0,
f: 3
},
press_s = { width: 500, height: 40, f: 100 },
instruct = { x: 126, y: 300, w: 900, h: 57, f: 103 },
keys = [],
gravity = 0.3,
friction = 0.8;
These initialise values for speed, velocity on the X-axis, velocity on the Y
axis, a value for gravity to allow our player to fall back to the ground after
jumping, and another for friction to dampen the players’ movement
making the player come to a stop gradually. Save the file (CTRL + S).
Next, edit the ‘main.js’ file and add the following, just after the opening
line of the update() function:
if (keys[39]) {
if (player.velX < player.speed) {
player.velX++;
player.f = 1;
}
}
if (keys[37]) {
if (player.velX > -player.speed) {
player.velX--;
player.f = 3
}
~ 172 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
}
player.velX *= friction;
player.velY += gravity;
player.x += player.velX;
Save the file (CTRL + S). Now, let’s take a closer look at the code:
if (keys[39]) {
if (player.velX < player.speed) {
player.velX++;
player.f = 1;
}
}
//if the right arrow is pressed on the keyboard move the player to the
right and set the player sprite to sprite[1] – facing right
if (keys[37]) {
if (player.velX > -player.speed) {
player.velX--;
player.f = 3
}
}
//if the left arrow is pressed on the keyboard move the player to the
left and set the player sprite to sprite[3] – facing left
player.velX *= friction;
// Set the velocity on X-axis to gradually stop by applying the friction
coefficient
player.velY += gravity;
// Set the velocity on the Y-axis to fall back to the ground by applying
the gravity coefficient
player.x += player.velX;
//move the player x position based on velocity X
Save your file (CTRL + S).
~ 173 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Now refresh your browser, press ‘s’, and try moving your player left and
right using the left and right arrows on your keyboard. Of course, you can
choose alternative keys if you wish. Just change the index number of
keys[] to match your desired key code. See the table below:
~ 174 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Although we can move our player, currently we can only move left and
right.
Before we give our player the ability to be able to jump we need to set up
collisions between the player and the environment. For instance, at the
moment the player can walk through walls. Also, if we set gravity working
right now, the player would fall straight through the floor. To be able to
jump the player must also be able to return to the ground, so we need
gravity. At the moment, although we have set the tile map so that we can
see it, nothing is solid. So next, let’s add some substance to the floor,
walls, and platforms.
Let’s first take a look at the concept of collision detection. It does involve
some calculation, but if we use circles for our example, it’s easier to grasp.
Take two circles, both with a diameter of 10 cm, therefore a radius of
5cm. If we say the centre of circle 1 is C1 and the centre of circle 2 is C2.
To be able to calculate if they have collided (overlapped) all we need to
~ 175 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
work out is if the distance between C1 and C2 is less than 10cm. See the
diagram below:
If it’s more, then the circles cannot be touching, but less means that they
have overlapped.
In order we need to:
1. calculate the size of the objects
2. find the centre of both objects
3. calculate the distance from the centre to the edge of both objects
and find the total
4. calculate the difference between the current centre measurements
compared with the total allowable distance
So our formula to detect a collision will look something like this:
let c1_middle = c1.width / 2; //5cm
let c2_middle = c2.width / 2; //5cm
let c_total = c1_middle + c2_middle;//10cm
if(((c1.x - c1_middle) - (c2.x - c2_middle)) < c_total || ((c1.y -
c1_middle) - (c2.y - c2_middle)) < c_total){
//what to do when a collision has occured
}
~ 176 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
We can of course simplify our equation further, but this is for the sake of
example. Here c1.x c1.y c2.x c2.y represent current x and y coordinates of
c1 and c2. So, we’re saying if the current x positions of c1 and c2 is less
than 10cm or the current y positions of c1 and c2 is less than 10cm, then a
collision has occurred. The good news is that we only need to set up our
collisions once. A single function will handle it all for us. It looks
complicated on the face of it, but when it’s broken down it’s much more
easily understood.
Until you can get your head around it, you can treat the function as sort of
a black box. You only need to know the inputs required to get the desired
outputs. However, mathematics plays a fundamental part in games
programming so it is better if you can get to grips with it.
Okay, let’s do it! Once again, open the ‘assets.js’ file and add the following
code to the bottom of the file and save the file (CTRL + S):
Next, create a new file called ‘collisions.js’ and save it in the ‘js’ folder.
Add the following function and then save it (CTRL + S).
~ 177 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
colDir = null;
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
var oX = hWidths - Math.abs(vX),
oY = hHeights - Math.abs(vY);
if (oX >= oY) {
if (vY > 0) {
colDir = "t";
shapeA.y += oY;
} else {
colDir = "b";
shapeA.y -= oY;
}
} else {
if (vX > 0) {
colDir = "l";
shapeA.x += oX;
} else {
colDir = "r";
shapeA.x -= oX;
}
}
}
return colDir;
}
Okay, here we are passing 2 parameters into our function, ‘shapeA’ and
‘shapeB’. We are checking for collisions in all directions between the two
shapes and returning one value called ‘colDir’. The value ‘colDir’ return is
simply ‘l’, ‘r’, ‘b’, or ‘t’, which represents the direction of any detected
collision, left, right, bottom and top respectively. Using these values we
will determine what we want to do in that instance. First, though, let’s
take a closer look at what’s going on in our colDir function:
~ 178 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 179 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
return colDir;
//return the direction of the collision
~ 180 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Arithmetic Operators
OPERATOR DESCRIPTION
+ addition
- subtraction
* multiplication
/ division
% modulus(division remainder)
++ increment
-- decrement
Assignment Operators
OPERATOR USAGE LONGHAND
= x = y x = y
+= x += y x = x + y
-= x -= y x = x – y
*= x *= y x = x * y
/= x /= y x = x / y
%= x %= y x = x % y
Comparison Operators
OPERATOR DESCRIPTION
== equal to
=== equal to value and type
!= not equal to
!== not equal to value or type
> greater than
< less than
>= greater than or equal to
<= less than or equal to
~ 181 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Logical Operators
OPERATOR DESCRIPTION
&& and
|| or
! not
Conditional Operator
variable = (condition) ? value1 : value2
Bitwise Operators
OPERATOR DESCRIPTION
& AND
| OR
~ NOT
^ XOR
<< Left Shift
>> Right Shift
~ 182 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
player.grounded = false;
// set the player to not on the ground
~ 183 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
if(player.grounded){player.velY = 0;}
//if player is on the ground set the velocity for the player in the Y
direction to 0
player.x += player.velX;
//allow the player to move the player on the X axis
player.y += player.velY;
//allow the player to move the player on the Y axis
if (player.screen != 15){
ctx.drawImage(wiz[player.f], player.x, player.y);
}
//if the player is not on the title screen draw the main character
~ 184 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Lastly, open ‘map1.js’ and add the following code to the bottom of the
file, then save it (CTRL + S):
function addBox(a,b,c,d){
boxes1.push({ x: a, y: b, width: c, height: d });
return
}
var boxes = [];
function drawBoxes1(){
// BORDER WALLS
addBox(0,577,1152,1);
addBox(0,0,64,448);
addBox(1088,192,64,384);
addBox(0,0,384,64);
addBox(576,0,576,64);
addBox(768,64,64,64);
// PLATFORMS
addBox(0,512,320,1);
addBox(768,512,64,20);
addBox(832,448,256,1);
addBox(384,448,128,1);
addBox(128,450,57,62);
addBox(576,384,192,1);
addBox(320,320,128,1);
addBox(832,320,64,1);
addBox(960,320,128,1);
addBox(64,256,192,1);
addBox(640,256,192,1);
addBox(128,192,64,64);
addBox(896,192,128,1);
addBox(192,128,512,1);
addBox(448,64,64,1);
boxesDrawn1+=1;
return boxesDrawn1;
}
~ 185 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
These functions draw the collision boxes at set coordinates. Let’s take a
closer look at how it works:
function addBox(a,b,c,d){
//open a function called addBox and allow paramters a,b,c and d
return
//return the results
}
~ 186 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Inside the drawBoxes1 function we have a bunch of function calls that add
collision boxes, like so:
addBox(0,577,1152,1);
//call / invoke the addBox function and send the necessary parameters.
X coordinate to start from, Y coordinate to start from, Width in pixels,
Height in pixels
This, in conjunction with our colDir function, has the effect of making our
platforms and walls appear solid. Note that the platforms only have a 1
pixel surface for collision detection. This is so that our main character can
pass beneath the platforms. Our main character is 52 pixels tall, and each
tile is 64 pixels tall. The actual platform is 16 pixels tall and if we take that
away from 64 we are only left with 48 pixels of available space. Therefore,
our player wouldn’t be able to pass through. See the images below.
You can see in the first image that our player isn’t able to pass beneath
the platform, while in the second image our player can pass freely.
With collisions now set up, open ‘main.js’ and just inside the main update
function opening add the following code:
if (keys[38] || keys[32]) {
// up arrow or space
if (!player.jumping && player.grounded) {
player.velY = -player.speed * 2.5;
player.jumping = true;
player.grounded = false;
}
}
~ 187 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Save the file. This enables the player to jump. Whenever you press the
spacebar or the arrow up key. Combined with the arrow left and right,
you can now navigate through the whole game screen. Try it out.
Once downloaded, unzip it and add the contents to the ‘sprites’ folder. To
unzip the file, double click it and then select all of the contents (CTRL + A)
and copy it (CTRL + C), then open the ‘sprites’ folder and paste (CTRL + V).
In the usual fashion, we’re going to add them to the sprites file. Open
‘sprites.js’ and add the following code to the bottom of the file, then save
it (CTRL + S):
~ 188 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
/* ============================
ENEMIES KEY:
200 - Ghost Frame 1
201 - Ghost Frame 2
202 - Spikes
203 - Bat Frame 1
204 - Bat Frame 2
============================== */
for(i = 200; i < 205; i++){
sprite[i] = new Image();
sprite[i].src = `sprites/${i}.png`;
}
//this adds our 5 enemy sprites to the sprites array at stated indexes
The next thing we need to do is set them up in our assets file. Open the
‘assets.js’ file. Following the closing curly brace of the player object ( }, )
add the following code, and then save the file:
~ 189 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Importantly, we don’t have to use all of these in every game screen, but
they are now declared and set up in readiness. Also note, the spike
objects don’t need speed, frame, or destination because they’re static.
Next, make a new file called ‘enemy.js’ and save it in the ‘js’ folder. Then
add the following code:
~ 190 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, as you can see, we have three functions here. The first function
draws enemies, sets their movement either on the X or Y axis as required,
animates the enemies every 200ms, and handles collisions with those
(animated and moving) enemies, the second function draws static
enemies and handles collisions with those static enemies (the spikes) and
the third function (lifeLost) gets called by the afore mentioned functions if
a collision occurs between the player and an enemy.
e.x+=e.s;
// move enemy at chosen speed from left to right
~ 191 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
e.x-=e.s;
// move enemy at chosen speed from right to left
}
}
if (xy === 2) {
// if vertical movement is chosen move on Y axis
e.y+=e.s;
// move enemy at chosen speed from top to bottom
e.y-=e.s;
// move enemy at chosen speed from bottom to top
~ 192 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
}
}
if (p.x < e.x+xos + e.w && p.x + p.width > e.x+xos && p.y < e.y+yos +
e.h && p.y + p.height > e.y+yos){ lifeLost(e, p, xos); }
//if a collision is detected call lifeLost function
}
Okay, then we have the second function, which is much simpler because it
is for static enemies.
if (p.x < e.x+xos + e.width && p.x + p.width > e.x+xos && p.y <
e.y+yos + e.h && p.y + p.height > e.y+yos){ lifeLost(e, p, xos); }
//if a collision is detected call lifeLost function
}
Much simpler, but also easier to navigate for the player. Lastly, we have
the lifeLost function.
player.lives-=1;
//decrease player lives by 1
~ 193 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
player.x = 630;
//Set player x position to 630 pixels
player.y = 522;
//set player y position to 522 pixels
if ((p.x + p.width) > e.x+xos && (p.x + p.width) < e.x+xos + e.w){
player.f = 1; }
//if the player has collided with an enemy to the left set player sprite
frame to 1
}
if (p.x < (e.x+xos + e.w) && p.x > e.x+xos){ player.f = 3; ?}
//if the player has collided with an enemy to the right set player sprite
frame to 3
}
}
Next, we need to call the enemy and enemyStatic functions just after
we’ve drawn our map. Open ‘map1.js’ and add the following function calls
just after the closing curly brace for the outer for loop ( } ), then save
(CTRL + S).
Okay, finally we need to set start positions and give the player some
feedback. Open main.js’.
~ 194 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
ctx.font="20px Arial";
ctx.fillStyle = "white";
ctx.fillText(": "+player.lives, 1090, 621);
//displays current player lives at given coordinates
Now make sure to add a reference in the ‘sorcerer.html’ file for the
‘enemy.js’ file, in the usual manner. Add the following just inside the
</body> closing body tag and save (CTRL + S):
<script type="text/javascript" src="js/enemy.js"></script>
If you’ve followed this correctly, you should now have the following:
~ 195 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
At this point, we have set some basic rules in place, but as we move on
they will need to be updated. For instance, on different game screens you
will want your player to respawn in different positions, depending on your
design, we’ll need to do something when all lives are lost and your game
is over and we’ll need to add some animation for our main character for
walking, respawning, etc.
I’m pretty sure now is a good time for a well-deserved break. Grab a drink
and relax a while, before we move on.
~ 196 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
GAME OVER
Open ‘enemy.js’ and add the following conditional to the end of the
lifeLost function:
if (player.lives === 0){
gameOver();
}
Then add the following gameOver function to the end of the file, and
save it (CTRL + S):
function gameOver(){
player.screen = 20;
ctx.drawImage(tile[16], 0, 0, 1152, 704);
ctx.drawImage(sprite[109], 250, 200, 688, 151);
}
Finally, open ‘main.js’ and add the following conditional inside the top of
the update function:
if (player.screen === 15){ drawMyMap1000();}◄ following this line
if (player.screen === 20){ gameOver();}◄ add this line
Save the file (CTRL + S). Now when player.lives === 0 you get:
~ 197 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The first thing we need to do is bring in the sprites we need. As in all cases
before, these are available for you to download via the link below:
https://wddtrw/resources/learntocode/platformgame_collectables.zip
Once downloaded, unzip it and add the contents to the ‘sprites’ folder. To
unzip the file, double click it and then select all of the contents (CTRL + A)
and copy it (CTRL + C), then open the ‘sprites’ folder and paste (CTRL + V).
~ 198 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Some of these sprites this time will also be used for the game monitor in
the next section.
In the now very familiar fashion, we’re going to add them to the sprites
file. Open ‘sprites.js’ and add the following code to the bottom of the file,
then save it (CTRL + S):
/* ============================
COLLECTABLES KEY:
300 - Chest
301 - Open Chest
302 - Key
303 - Ruby
304 - Emerald
305 - Gold Coin
306 - Lightning Bolt
307 - Star
308 - Potion
309 - Flask
310 - Broken Flask
311 - Crates Frame 1 - Whole
312 - Crates Frame 2
313 - Crates Frame 3
314 - Crates Frame 4
315 - Crates Frame 5
316 - Crates Frame 6 - Destroyed
317 - Barrel
318 - Score Card
319 - Shop
============================== */
for(i = 300; i < 320; i++){
sprite[i] = new Image();
sprite[i].src = `sprites/${i}.png`;
}
SPRITE SHEETS
It is worth noting at this point that we could and should (for the finished
game) load all of the sprites in as a single file called a sprite sheet. Sprite
~ 199 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
sheets increase the performance of your game and reduce loading and
start-up time. The game would be using a few larger images, instead of
possibly hundreds of smaller ones.
function init() {
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
}
I have kept them separate in this book to keep each section more easily
understood, as we built each part of the game. However, in the final
game, a sprite sheet will be used and we’ll update our code accordingly.
Moving on…
Make a new file called ‘collectables.js’ and save it in the ‘js’ folder and
make sure to add a reference to the file in the ‘sorcerer.html’ file, as
below and save it (CTRL + S):
Next open ‘assets.js’ and add the following two lines of code, to initialise
our coins settings. The first line declares a new coin object, sets the width
and height of our sprite, and sets the initial coin count to zero (0).
Secondly, we have a coinsCollected array with ten delimited values all set
~ 200 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
to zero. Each one of these values represents a coin. Zero (0) means not
collected and one (1) will mean collected. You’ll see shortly how we use
this to determine whether or not the coin in question should be drawn.
Okay, back to our ‘collectables.js’ file, let’s tackle drawing and collecting
coins.
Add the following code and then save the file (CTRL + S).
var coins = [];
function addCoins(mn, w, h, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6,
y6, x7, y7, x8, y8, x9, y9, x10, y10){
let xs = [x1, x2, x3, x4, x5, x6, x7, x8, x9, x10];
let ys = [y1, y2, y3, y4, y5, y6, y7, y8, y9, y10];
for(i =0; i < 10; i++){
coins[i] = { x: xs[i], y: ys[i], width: w, height: h, c: 0 };
if(player.x < coins[i].x + coins[i].width
&& player.x + player.width > coins[i].x
&& player.y < coins[i].y + coins[i].height
&& player.y + player.height > coins[i].y && coinsCollected[i] == 0){
coins[i].c +=1;
coinsCollected[i] = 1;
}
if (coins[i].c == 0 && coinsCollected[i] == 0){
ctx.drawImage(sprite[305], coins[i].x, coins[i].y, coins[i].width,
coins[i].height);
} else if (coins[i].c > 0 && coins[i].c < 2){
coin.count+=1;
player.score+=10;
}
}
~ 201 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
let xs = [x1, x2, x3, x4, x5, x6, x7, x8, x9, x10];
let ys = [y1, y2, y3, y4, y5, y6, y7, y8, y9, y10];
//separate x and y coordinate parameters into indexed arrays
coins[i].c +=1;
//add 1 to the c parameter of coins for the given index
coinsCollected[i] = 1;
//update the coinsCollected array to 1 for the given index – indicating
the coin has been collected
}
if (coins[i].c == 0 && coinsCollected[i] == 0){
~ 202 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
coin.count+=1;
//add 1 to coin count – for use with the game monitor
player.score+=10;
//add 10 to the player score – for use with the game monitor
}
}
Now, let’s make it all work. Open ‘map1.js’ and add the following function
call, immediately following the nested for loops that draw the tile map
and save the file (CTRL + S):
addCoins(coin, 49, 50, 76, 78, 76, 142, 76, 206, 140, 332, 396, 204, 460,
204, 396, 12, 716, 332, 908, 76, 600, 78)
We have a few more collectables to add to our game screen, but unlike
coins having 10, we’ll use less of the others.
~ 203 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If you have followed all of the instructions correctly so far you should
have a game screen that looks like the example below. Experiment with
the function call x and y parameters. You can place your coins anywhere
and they are all collectable, and on the collection, they add to your coin
count and score.
We could continue in the same vein and build almost identical functions
for our other collectables. As shown for the gems below:
var gems = [];
function addGems(item, w, h, x1, y1, x2, y2){
let xs = [x1, x2];
let ys = [y1, y2];
for(i =0; i < 10; i++){
gems[i] = { x: xs[i], y: ys[i], width: w, height: h, c: 0 };
if(player.x < gems[i].x + gems[i].width
&& player.x + player.width > gems[i].x
&& player.y < gems[i].y + gems[i].height
&& player.y + player.height > gems[i].y && gemsCollected[i] == 0){
gems[i].c +=1;
gemsCollected[i] = 1;
}
~ 204 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Notice how the code is almost identical, aside from the variables being
called gems instead of coins. That means we can optimise it. As much as
possible we should remove repetitive code. For instance, here we could
build one large array to hold all collectable objects. With that in mind,
let’s do a quick revisit.
Firstly, open the ‘assets.js’ file and add the following code instead of the
coin assets, then save (CTRL + S):
~ 205 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next, let’s add our function calls. Open ‘map1.js’ add the following code,
in place of the addCoins function call, then save it (CTRL + S):
//addCxs(item, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7,
x8, y8, x9, y9, x10, y10)
addCxs(coin, 76, 78, 76, 142, 76, 206, 140, 332, 396, 204, 460, 204, 396,
12, 716, 332, 908, 76, 600, 78);
addCxs(gem, 720, 74, 1040, 532);
addCxs(key, 460, 10, 1024, 345);
addCxs(star, 525, 12, 973, 76, 1037, 268);
addCxs(potion, 1041, 398, 593, 332);
addCxs(flask, 13, 463);
addCxs(bolt, 425, 384);
//Now we can add up to 10 of each item, simply by stipulating x and y
coordinates and bringing in the item object from assets
Finally, open the ‘collectables.js’ file and replace all code with the
following function, to handle all collectables, then save the file (CTRL + S):
function addCxs(item, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7,
y7, x8, y8, x9, y9, x10, y10){
let iw = item.width;
let ih = item.height;
let plw = player.width;
let plh = player.height;
~ 206 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
let xs = [];
xs[1+mn] = x1;
xs[2+mn] = x2;
xs[3+mn] = x3;
xs[4+mn] = x4;
xs[5+mn] = x5;
xs[6+mn] = x6;
xs[7+mn] = x7;
xs[8+mn] = x8;
xs[9+mn] = x9;
xs[10+mn] = x10;
let ys = [];
ys[1+mn] = y1;
ys[2+mn] = y2;
ys[3+mn] = y3;
ys[4+mn] = y4;
ys[5+mn] = y5;
ys[6+mn] = y6;
ys[7+mn] = y7;
ys[8+mn] = y8;
ys[9+mn] = y9;
ys[10+mn] = y10;
~ 207 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
In the usual fashion, let’s break it down. The logic here is the same as the
addCoins function from before, but taking into consideration which
collectable we are referencing.
function addCxs(item, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7,
y7, x8, y8, x9, y9, x10, y10){
//open the addCxs function and pass in the collectable item assets, plus
ten sets of x and y coordinates
let iw = item.width;
let ih = item.height;
let plw = player.width;
let plh = player.height;
let plx = player.x;
let ply = player.y;
// set short variable names to hold player and collectable attributes.
This will allow us to make collision calculations shorter and more easily
readable
~ 208 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
item.mn = player.screen-1;
// set the item map number to match the current player screen - 1
let mn = item.mn*30+item.fct;
//calculate mn to ensure data is held at unique array indexes. For
instance, if the player is on screen number 1 the equation would be
0 * 30 + the item factor given in assets, screen 2 would be 1 * 30 + item
factor and so on. 30 is the chosen maximum number of collectables per
game screen, based on the following:
coins x 10
gems x 2
keys x 2
potions x 2
flasks x 2
stars x 5
lightning bolts x 2
spare indexes x 5 – if we want to add more collectables
let xs = [];
xs[1+mn] = x1;
xs[2+mn] = x2;
xs[3+mn] = x3;
xs[4+mn] = x4;
xs[5+mn] = x5;
xs[6+mn] = x6;
xs[7+mn] = x7;
xs[8+mn] = x8;
xs[9+mn] = x9;
xs[mn] = x10;
//grab all X coordinates from the function parameters and add them to the
xs array at calculated indexes
let ys = [];
ys[1+mn] = y1;
ys[2+mn] = y2;
ys[3+mn] = y3;
ys[4+mn] = y4;
ys[5+mn] = y5;
ys[6+mn] = y6;
~ 209 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
ys[7+mn] = y7;
ys[8+mn] = y8;
ys[9+mn] = y9;
ys[mn] = y10;
//grab all Y coordinates from the function parameters and add them to the
ys array at calculated indexes.
if(plx < items[i+mn].x + iw && plx + plw > items[i+mn].x && ply <
items[i+mn].y + ih && ply + plh > items[i+mn].y && itemsCollected[i+mn]
== 0){
//if player has had a collision with an item that has not yet been
collected
items[i+mn].c +=1;
//set the item collected value to 1
itemsCollected[i+mn] = 1;
//update the items collected array to show the item as collected
}
if(items[i+mn].c == 0 && itemsCollected[i+mn] == 0){
//if the item has not been collected…
item.count+=1;
//add 1 to the item count – for the game monitor in the next section
~ 210 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 211 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Great! In the next section, we’ll look at generating some user feedback.
I think it’s that time again. Take a break. Have a brew and refresh your
batteries.
~ 212 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, first of all open ‘sorcerer.html’ and add the following JavaScript file
reference, just after the ‘enemy.js’ reference and save.
Next, create a new file called ‘gameMonitor.js’ and then add the code
below and save the file (CTRL + S):
function gameMonitor(){
ctx.drawImage(sprite[305], 19, 655, coin.width/1.5, coin.height/1.5);
ctx.drawImage(sprite[307], 148, 658, star.width/1.5,
star.height/1.5);
ctx.drawImage(sprite[302], 277, 656, key.width/1.5, key.height/1.5);
ctx.drawImage(sprite[304], 400, 655, gem.width/1.5, gem.height/1.5);
ctx.drawImage(sprite[303], 405, 670, gem.width, gem.height/1.5);
ctx.drawImage(sprite[308], 533, 654, potion.width/1.5,
potion.height/1.5);
ctx.drawImage(sprite[309], 660, 656, flask.width/1.5,
flask.height/1.5);
ctx.drawImage(sprite[306], 788, 660, bolt.width/1.5,
bolt.height/1.5);
ctx.drawImage(sprite[318], 896, 640, 256, 64);
ctx.drawImage(wiz[1], 1042, 594, 30, 42);
}
All we are doing here is drawing sprites to the screen in specific locations
and slightly resizing them. In order for them to get drawn, we have to call
the function. Open ‘map1.js’ and add the following function call, just
below the function calls for the collectables:
gameMonitor();
~ 213 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If you refresh your browser and press ‘s’ to start the game you will see
that we have placed sprites along the bottom of the screen to represent
the game collections, score, and lives variables, as shown below:
ctx.font="35px Arial";
ctx.fillStyle = "white";
ctx.fillText(player.score, 1000, 685); // Update Score
~ 214 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
ctx.font="20px Arial";
ctx.fillStyle = "white";
ctx.fillText(": "+coin.count, 60, 681);// Update Coin Count
ctx.fillText(": "+gem.count, 444, 681);// Update Gem Count
ctx.fillText(": "+star.count, 188, 681);// Update Star Count
ctx.fillText(": "+potion.count, 572, 681);// Update Potion Count
ctx.fillText(": "+flask.count, 700, 681);// Update Flask Count
ctx.fillText(": "+bolt.count, 828, 681);// Update Bolt Count
ctx.fillText(": "+key.count, 316, 681);// Update Key Count
ctx.fillText(": "+player.lives, 1090, 621);// Player Lives
}
//add counts to the game monitor – updated with
requestAnimationFrame(update); 60 frames per second (every 16.7 ms)
If you followed everything correctly, you should now have the following:
Top class! So we’ve built one game screen. It looks pretty cool, right? In
the next section, we’ll explore how to add lots more screens and how to
move the player from screen to screen.
~ 215 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The great news here is that we’ve done a lot of the hard work. Our game
screens will utilise much of the code we have already built.
Let’s get cracking with game screen number 2. Firstly, we need to decide
where each screen will sit in relation to each other. As we’ve already
created screen 1, let’s say screen 2 is to the left and screen 3 is to the
right, like so:
Next, open ‘sorcerer.html’ and add a reference for our second map below
the reference for map1, like so:
Now, create a new file called ‘map2.js’ and save it in the ‘js’ folder. Then
add the following code:
function drawMyMap2(){
ctx.drawImage(tile[16], 0, 0);
var xt = 0; // Tile Map X Index
var yt = -64; // Tile Map Y Index
var tileMap = [];
var mapNo = 0; // Map Index
tileMap[0] = [6, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6];
tileMap[1] = [6, 9, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6];
~ 216 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
addCxs(coin, 76, 399, 140, 399, 206, 399, 652, 79, 716, 79, 780, 79, 846,
79)
addCxs(gem, 70, 200, 76, 532);
addCxs(key, 1040, 76, 585, 525);
addCxs(star, 1037, 140, 717, 460);
addCxs(potion, 590, 461, 0, -100);
addCxs(flask, 580, 207, 0, -100);
addCxs(bolt, 457, 386, 0, -100);
gameMonitor();
~ 217 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
function addBox2(a,b,c,d){
boxes2.push({ x: a, y: b, width: c, height: d });
return
}
function drawBoxes2(){
addBox2(0,57,706,1);
addBox2(832,577,320,1);
addBox2(0,0,66,640);
addBox2(1089,0,66,384);
addBox2(192,0,960,64);
addBox2(640,386,66,256);
addBox2(640,192,256,192);
addBox2(706,386,386,64);
addBox2(1026,192,66,192);
addBox2(66,256,256,128);
addBox2(576,512,66,1);
addBox2(1024,512,128,1);
addBox2(66,512,192,1);
addBox2(449,449,66,1);
addBox2(576,386,66,1);
addBox2(386,320,66,1);
addBox2(576,256,66,1);
addBox2(66,129,320,1);
addBox2(449,192,66,1);
addBox2(66,66,66,1);
boxesDrawn2+=1;
return boxesDrawn2;
}
You should recognise all of this code. Apart from the changed parameters,
this program code is the same as for screen 1. Just as a refresher, we have
drawn the background image, then the tile map, added the collectables,
then the game monitor, the enemies, and finally, the collision boxes.
~ 218 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If you need further clarification please turn back to page 162 and
onwards, where we build ‘map1.js’. As the explanation would be virtually
identical.
The last step we need to take is a small update to ‘main.js’ to allow the
main character access to the other tile maps. For example, when the
player moves out of the left-hand side of screen one, they need to arrive
at the right-hand side of screen 2. Likewise, if the player moves out of the
right-hand side of screen 2, they need to arrive at the left-hand side of
screen 1. Open ‘main.js’ and add the following code, then save the file:
~ 219 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Add this:
if (player.screen === 2){ drawMyMap2(); }
if (player.screen === 2 && boxesDrawn2 === 0){ drawBoxes2(); }
if (player.screen === 2 && boxesDrawn2 < 2 ) {
boxes = boxes2;
if (player.entered < 1){
enemy1.x = 62; enemy1.y = 448; enemy1.dest = 0;
enemy2.x = 62; enemy2.y = 192; enemy2.dest = 0;
enemy3.y = 62; enemy3.dest = 0;
player.entered = 1;
}
}
~ 220 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
There are conditionals for every possible exit or entry point from and to
each screen. Next, we have the following code block:
boxes = boxes2;
//add collision boxes for screen 2 to the boxes variable so that the
player will interact with them
~ 221 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Now, refresh your screen, press ‘s’ to start, and navigate the player into
screen 2. If you followed everything correctly, your screen 2 tilemap
should look like this:
Now, in the same manner, you can add as many screens as you wish.
Ensure, as you design the game screens, that the entrances/exits match
across screens, as below:
Amazing job! To finish this exercise in the next section we’re going to add
some background music and sound effect (SFX).
~ 222 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
The first thing we need to do is bring in the sound files we need. As in all
cases before, these are available for you to download via the link below:
https://wddtrw/resources/learntocode/platformgame_sfx.zip
Once downloaded, unzip it and add the contents to the ‘sfx’ folder. To
unzip the file, double click it and then select all of the contents (CTRL + A)
and copy it (CTRL + C), then open the ‘sfx’ folder and paste (CTRL + V).
~ 223 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next we need to add references to two new JavaScript files that we’ll
create to handle our sound. Open ‘sorcerer.html’ and add the following
references just before the ‘tiles.js’ file reference:
<script type="text/javascript" src="js/sfx.js"></script>
<script type="text/javascript" src="js/music.js"></script>
Next, create a new file called ‘sfx.js’ and save it in your ‘js’ folder, as usual.
Then add the following code:
var sfx = [];
sfx[0] = new Audio('sfx/collectcoin.wav');
sfx[1] = new Audio('sfx/collectgem.wav');
sfx[2] = new Audio('sfx/collectstar.mp3');
sfx[3] = new Audio('sfx/collectpotion.mp3');
sfx[4] = new Audio('sfx/collectflask.mp3');
sfx[5] = new Audio('sfx/collectbolt.mp3');
sfx[6] = new Audio('sfx/collectkey.wav');
sfx[7] = new Audio('sfx/ghost_kill.mp3');
sfx[8] = new Audio('sfx/jump.mp3');
sfx[9] = new Audio('sfx/encounter.mp3');
sfx[10] = new Audio('sfx/Castle_Theme.mp3');
sfx[11] = new Audio('sfx/Main_Theme.mp3');
Here, we have created a new array called sfx. Then we have added our
sounds at chosen indexes so that we can use them in our game code with
ease.
~ 224 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Okay, now we have to add instructions to play the sound files in certain
circumstances. Let’s handle the collectables first. Open ‘collectable.js’ and
edit the following conditionals:
if(item.t == 'coins'){ player.score+=10; sfx[0].play(); }
if(item.t == 'gems'){ player.score+=50; sfx[1].play(); }
if(item.t == 'keys'){ player.score+=20; sfx[6].play(); }
if(item.t == 'potions'){ player.score+=30; sfx[3].play(); }
if(item.t == 'flasks'){ player.score+=100; player.lives+=1;
sfx[4].play(); }
if(item.t == 'stars'){ player.score+=25; sfx[2].play(); }
if(item.t == 'bolts'){ player.score+=15; sfx[5].play(); }
Add the highlighted code. This will play a different sound when you collect
a particular item.
Save the file and try it out!
Next, open ‘main.js’. Just after the opening of the main update function,
add the following two conditionals:
function update() {◄ add the following two lines of code after this
Then, inside the jump controls conditional, add the following highlighted
instruction, then save the file:
if (keys[38] || keys[32]) {
if (!player.jumping && player.grounded) {
player.velY = -player.speed * 2.5;
player.jumping = true;
player.grounded = false;
sfx[8].play();
}
}
~ 225 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
Next, create a new file called ‘music.js’, add the following code and then
save it in the ‘js’ folder:
function playMusic(m){
if(m === 1){
sfx[11].pause();
sfx[11].currentTime = 0;
sfx[10].addEventListener('ended', function(){
if(sfx[10].currentTime === sfx[10].duration - .34){
sfx[10].currentTime = 0.1;
sfx[10].play();
}}, false);
sfx[10].play();
}
if(m === 2){
sfx[10].pause();
sfx[10].currentTime = 0;
sfx[11].addEventListener('ended', function(){
if(sfx[11].currentTime === sfx[25].duration - .34){
sfx[11].currentTime = 0.1;
sfx[11].play();
}}, false);
sfx[11].play();
}
if(m === 0){
sfx[10].pause();
sfx[10].currentTime = 0;
}
}
In a nutshell, this function loops the music at the end of its duration and
changes the music when the player is either on the title/game over
screens, or alternatively, a game screen. There are a few new instructions
here that we haven’t previously explored in this book.
~ 226 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
They are currentTime, duration, pause() and play(). The play() method
starts playing the current audio, while the pause() method pauses the
audio, currentTime returns the current play time and duration returns the
duration, in other words the total length. These are inbuilt JavaScript
functions. They have the following syntax:
audioObject.play()
audioObject.pause()
audioObject.currentTime
audioObject.duration
And then add the following, just indise the opening for the gameOver
function:
if(player.lives < 1){ PlayMusic(2);}
Now we have music and sound effects. Why not try experimenting and
adding more of your own? If you don’t have the means to edit sound files
I would highly recommend Audacity, which you can download free of
charge.
~ 227 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
https://www.audacityteam.org/download/
Just download the version you require for your particular system.
STEP⓰ - CONCLUSION
We have come to the end of this exercise, but this is only the beginning of
the journey.
https://wddtrw/resources/learntocode/platformgame.zip
~ 228 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
There are some free web spaces available, but they usually come with
many restrictions. There are a few cheaper web spaces available if you
want a webspace for testing your personal projects.
You can get effective and very reasonably priced packages from the likes
of Heart Internet and Ionos 1 & 1. Packages start from only a few pounds
or dollars a month. To deploy your own code all you need is a domain
name, a hosting package, and an SSL certificate.
You can get packages from Ionos (at the time of writing this book) from
only £1 plus VAT per month for the first 6 months and then only £4 plus
VAT thereafter, which comes with a free SSL certificate. Then you can buy
a domain name for around £10 a year, but again the first year is usually
discounted to as low as £1 plus VAT.
Once you have web hosting, you can use a system called file transfer
protocol (FTP) to upload files with ease, or if dealing with development on
a more professional basis you would use a repository, such as GIT hub,
but that is beyond the scope of this book.
In the most basic of terms, when you upload a file to a web server, any
files that are within the public html folder are available for public access.
When you connect a domain name to your webspace, if you upload a file
to the public folder called index.html or index.php, for example, you do
not need to stipulate the file name.
~ 229 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 230 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
files on the server. You can upload, download, and delete files and folders
from the webserver easily in this way.
Internet services providers (ISP’s) usually provide a control panel with FTP
access, as well as there being FTP client tools available, such as WS FTP,
FileZilla, Cyberduck, etc.
If you choose to buy web hosting you must be aware of what you wish to
use it for. With some web spaces, you get a web builder with various
tools, but they are restrictive. Generally speaking the fewer restrictions,
the more technical the systems are to use. If you’re unsure, almost all
ISP’s have great customer service and or huge databases full of frequently
asked questions.
If you are new to web coding and you just want to learn more about
hosting a website or web app, I would choose regular web hosting with an
SSL certificate. Make sure the SSL certificate is included, otherwise you
may find yourself paying around £60 - £100 + per year to make your
website secure.
~ 231 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
If you are a more competent web developer, then you won’t go far wrong
with a virtual private server. A VPS Hosting simulates the experience of a
dedicated server even though you're still sharing the physical server with
other users. A VPS can be very cheap but requires more technical
proficiency. With SSH access you have more flexibility over how the server
is configured.
WHAT IS SSL?
SSL stands for Secure Sockets Layer and, in short, it's the standard
technology for keeping an internet connection secure and safeguarding
any sensitive data that is being sent between two systems, preventing
intruders from reading and/or modifying any information transferred,
including potential personal details.
WHAT IS SSH?
~ 232 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
For now, try designing some of your own game levels. See you in the next
book.
learntocode@wddtrw.co.uk
~ 233 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 234 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
For almost the same reason I fell in love with the art of computer coding, I
also found a passion for writing.
At the age of 9 years old, I had my first computer as a birthday gift and fell
in love with the art and creativity of computer coding. I found it enabled
me to create characters, game worlds, and other magical features, only
limited by the depths of my imagination.
Likewise, writing for me opened the door to the same wonderful universe
of imagination and with me sitting at the helm, the ability to navigate and
explore under my complete and unhindered control.
~ 235 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
INDEX
ABOUT THE AUTHOR ................. III, 2 92, 93, 94, 95, 96, 97, 101, 103,
ADDING IMAGES ....................III, 21 105, 108, 109, 111, 117, 120, 121,
ADDING STYLES TO THE IMAGESIV, 122, 123, 126, 128, 131, 132, 144,
43 153, 154, 155, 156, 157, 158, 159,
ANIMATED............................ 23, 190 160, 162, 163, 168, 170, 172, 176,
APP .... I, 2, 9, 11, 15, 16, 22, 29, 32, 181, 184, 186, 188, 189, 194, 198,
34, 36, 41, 43, 46, 51, 53, 56, 57, 199, 200, 204, 205, 212, 213, 215,
58, 59, 60, 61, 62, 63, 64, 73, 76, 217, 218, 219, 220, 223, 224, 225,
92, 95, 96, 101, 102, 103, 104, 228
105, 110, 120, 121, 125, 128, 130, CODING..................................... 4, 7
131, 139, 142, 147, 150, 151, 230 CODING EDITOR .......................III, 7
ARRAY .... 75, 76, 77, 78, 79, 80, 81, COLLECTABLES ............. V, 197, 198
82, 84, 85, 86, 124, 126, 127, 135, COLOUR DESIGN ...................IV, 34
136, 137, 138, 156, 157, 164, 169, COLOUR WHEEL .......................... 34
185, 188, 199, 201, 204, 207, 208, COMMENTING ............................ 16
209, 223 COMPUTER ...... 3, 4, 7, 51, 98, 229,
ARRAYS ........... 84, 85, 86, 176, 201 231, 234
ASSETS ................................... V, 153 CONST .... 55, 73, 74, 75, 76, 77, 78,
BACKGROUND...11, 12, 22, 23, 36, 79, 84, 85, 86, 88, 89, 90, 92, 93,
37, 39, 64, 65, 66, 67, 68, 70, 72, 98, 99, 103, 105, 106, 123, 124,
97, 130, 142, 143, 144, 151, 152, 126, 131, 132, 133, 134, 135, 136,
154, 155, 156, 161, 164, 217, 221 138, 139, 144, 145, 146, 156
BROWSER 2, 8, 9, 10, 11, 14, 19, 20, CONVENTION USED IN THIS BOOK
39, 51, 59, 61, 68, 77, 101, 103, .....................................................III
104, 108, 109, 117, 125, 150, 162, COUNTDOWN TIMER ...... IV, 95, 96
170, 173, 210, 213 CREATING A PLATFORM GAME .V,
BUILDING...... 36, 52, 101, 149, 154, 148
155, 156, 157 CREATING A WEB APP ..........IV, 51
CASCADING STYLE SHEETS ........ 10 CSS .................................................. 5
CASCADING STYLE SHEETS ....III, 10 CSS ...I, V, 2, 5, 8, 10, 14, 15, 16, 18,
CODE ... 2, 5, 6, 8, 9, 11, 12, 13, 15, 20, 28, 30, 34, 36, 38, 43, 59, 66,
16, 17, 18, 19, 20, 21, 22, 26, 28, 67, 70, 90, 91, 107, 108, 109, 111,
29, 30, 32, 36, 43, 54, 58, 61, 64, 112, 113, 116, 117, 118, 120, 131,
66, 75, 76, 77, 79, 82, 88, 89, 90, 139, 148, 151, 152
~ 236 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
~ 237 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
IMPLEMENTING THE HTML MARGIN . 11, 12, 22, 23, 36, 37, 39,
STRUCTURE ......................... IV, 56 43, 64, 65, 66, 67, 69, 70, 71, 72,
INSTRUCTIONS ....26, 154, 161, 203, 96, 130, 131, 142, 143, 152
224, 225 MUSIC ....................................VI, 222
INTRODUCTION ......................... 2, 4 MY OTHER PUBLICATIONS ...VI, 233
INTRODUCTION ............................. III NAVIGATION ........ V, 139, 142, 144
JAVASCRIPT ...I, 2, 8, 14, 15, 16, 20, NOTEPAD ........................... 2, 4, 7, 9
53, 54, 55, 56, 57, 59, 61, 66, 69, NUMBERS 54, 82, 86, 112, 115, 137,
71, 73, 74, 75, 77, 82, 95, 98, 101, 164, 213
102, 103, 104, 105, 107, 108, 109, OBJECTS 54, 86, 175, 188, 189, 204
111, 113, 116, 117, 123, 126, 129, OPACITY 10, 20, 44, 66, 71, 91, 144
138, 148, 150, 151, 154, 155, 212, OPERATOR ............ V, 179, 180, 181
223, 226 OVERFLOW ..... 64, 67, 68, 151, 152
JAVASCRIPT ... III, IV, V, 15, 73, 131, PADDING 10, 37, 40, 64, 65, 67, 68,
132, 144, 158 69, 71, 97, 130, 142
JSON .. IV, 53, 54, 55, 56, 57, 59, 61, PAGE LAYOUT DESIGN .......... III, 28
75, 80, 107, 109, 122, 125, 126, PC ..................................... 2, 52, 229
132, 133, 134, 135, 136, 137, 138, PIXEL ..... 22, 97, 143, 152, 155, 164,
153 167, 186, 220
JSON FILE ............... IV, 53, 61, 122 PLATFORM GAMEV, 148, 150, 151,
LESSONS ......................................... 2 153
LET13, 16, 21, 24, 29, 34, 36, 39, 50, POINTER.................................. 65, 69
52, 54, 55, 56, 57, 58, 66, 67, 74, POSITION 20, 65, 66, 70, 71, 79, 82,
75, 78, 79, 83, 84, 88, 89, 91, 93, 84, 91, 130, 142, 143, 172, 183,
94, 104, 111, 125, 126, 128, 129, 190, 191, 193, 201, 216, 220
132, 133, 134, 135, 136, 137, 138, PROGRAMMING . 3, 4, 5, 7, 52, 53,
144, 149, 155, 159, 163, 168, 170, 107, 176
172, 174, 175, 176, 177, 199, 200, PROGRAMMING ENVIRONMENT
201, 202, 203, 204, 205, 206, 207, ................................................... 52
208, 215, 219, 226 REFERENCE ................... V, 154, 157
LINK . 5, 9, 21, 28, 29, 30, 31, 32, 34, RESULTS ... 20, 23, 40, 52, 55, 56, 57,
41, 42, 43, 44, 45, 46, 47, 48, 52, 58, 60, 63, 65, 70, 71, 73, 74, 75,
53, 58, 59, 62, 66, 110, 128, 150, 76, 89, 95, 98, 100, 101, 103, 104,
151, 187, 197, 222, 227 160, 185
LOCAL STORAGE .... IV, V, 125, 131 RGB ......................................... 12, 34
LOCATION 104, 125, 134, 137, 149 RULES .. 9, 10, 11, 12, 14, 20, 23, 39,
MAC .....................2, 8, 52, 109, 229 44, 67, 68, 69, 111, 112, 116, 117,
~ 238 ~
LEARN TO CODE HTML, CSS & JAVASCRIPT
120, 121, 131, 139, 142, 143, 151, VARIABLE 18, 54, 73, 74, 77, 78, 83,
152, 183, 195 84, 90, 98, 124, 126, 135, 136,
SAVE . 8, 11, 21, 23, 26, 93, 96, 101, 137, 138, 145, 146, 153, 156, 164,
111, 122, 129, 171, 172, 187, 196, 176, 181, 182, 201, 207, 220
215, 223, 224, 226 VISUAL STUDIO CODE........... 2, 4, 7
SEARCH . 26, 31, 39, 51, 59, 60, 112 WEB SERVER .................................. VI
SELECTOR PATTERN ..................... 43 WELL-FORMED HYPERLINKS ..IV, 45
SFX ........................ VI, 149, 221, 222 WELL-FORMED IMAGE ELEMENTS
SOUND .................................. VI, 222 ..............................................IV, 40
SPRITE OBJECTS .................... V, 157 WHAT IS A JSON FILE? ...........IV, 53
SPRITE SHEETS ........................ V, 198 WHAT IS A WEB APP AND HOW IS
SSH ......................................... VI, 231 IT DIFFERENT FROM A WEBSITE?
SSL ......................... VI, 228, 230, 231 ..............................................IV, 51
STRING .... 54, 55, 56, 81, 82, 83, 86, WHAT IS AN ARRAY? .............IV, 84
116, 125, 179, 205 WHERE TO GO FROM HERE VI, 232
STRINGS ............................ 54, 82, 86 WHY USE JSON? .....................IV, 54
STYLESHEET . 5, 9, 29, 32, 41, 46, 58, WIDTH ... 5, 6, 10, 36, 37, 39, 43, 58,
59, 110, 128, 150, 151 59, 65, 66, 68, 69, 71, 91, 97, 110,
SYNTAX ........................................... 5 115, 116, 120, 121, 122, 128, 130,
SYNTAX HIGHLIGHTING ................ 5 131, 142, 143, 153, 154, 158, 159,
TARGET ......................................... 46 160, 162, 169, 170, 171, 175, 176,
TILE MAPS ...................... V, 154, 167 178, 181, 183, 184, 185, 189, 190,
TILES ....................................... V, 154 192, 193, 199, 200, 201, 202, 203,
TITLE SCREEN ......................... V, 160 204, 205, 206, 207, 209, 212, 217
TRANSITION ...................... 66, 71, 91 WINDOWS .................................. 2, 8
URL .. 5, 30, 31, 40, 45, 48, 114, 154, WORD WRAPPED. ......................... 6
157, 168 Z-INDEX .. 15, 16, 18, 66, 71, 91, 142
USER ADMINISTRATION
FUNCTIONS ........................ IV, 107
~ 239 ~