EXTEND YOUR APP!

JANUARY 25, 2015
LEARN TO CODE
STNMAST2008
IN
MAKE YOUR
OWN APP:
PART TWO
1
EXTEND YOUR APP!
You’ll need a mixture of concentration and creativity — but learning
to code is the new literacy and puts you among the 1% of the global
population tuned in to the language of the future, says Eleanor Mills
W
e all know about the
three Rs – reading, writing and
arithmetic. Well, in the 21st
century there is a new kind of
literacy we all need to get to grips
with: computer coding.
PART
TWO
13
THE POWER OF LIBRARIES
Using jQuery and CSS to change image
!
THE BRIEF
14
LOOPING
Repeating the image change
15
ADDING TOUCH
Detecting a touch input
16
OBJECT AND LOGIC
Creating player logic
17
SCORING
Is there a snap?
Last week nearly 10,000 of you
took up The Sunday Times’s
challenge to create an app; this
week we give you the final steps.
Coding is a surprising mixture
of extreme attention to detail and
creativity. Today we hope you will
discover that with your Snap That!
game. Yes, you need to follow the
instructions carefully to get the
program to work, but the Playto
Editor, powered by Decoded,
makes the coding experience
easier. What pictures you use for
the game is entirely up to you.
We’ve created versions with cats,
dogs, cakes and cars, but why not
use your favourite photographs?
It’s your app, so you choose.
That’s the point of this — to
create a nation driving technology,
rather than being passive users of
it. When we code we stand on the
shoulders of giants: we don’t have
to reinvent a geolocator, or one of
those clever drop-down calendars;
we can just import the best way of
doing it by copying and pasting.
By introducing coding into the
national curriculum, we are
leading the western world in
equipping our children with the
skills they will need. The Sunday
Times wants to empower you in
technology. By completing this
two-part series, you will join the
1% of the world that understands
the language of the future. That
has to be worth a bit of effort.
18
SINGLE WINNER
Preventing multiple snaps
19
WINNER LOGIC
Is there a winner?
PRELOADING IMAGES AND
DEBUGGING
20
Speeding up the gameplay and testing
for errors
CREATE AN APP IN A DAY
13
THE POWER
OF LIBRARIES
Welcome back. If you
missed last week’s
supplement, which
covered steps 1-12, you
can find them online at
tinyurl.com/STsnap if
you’re a subscriber, or at
learn.playto.io/snap-that/
lesson/0 outside the
paywall.
// Use jQuery to change css background
image of canvas 1 & 2
$("canvas#1").css("background-image",
url1);
$("canvas#2").css("background-image",
url2);
Now we’re going to finish
making our Snap That!
web app. Go to
thesundaytimes.co.uk/learntocode and open your project.
14
Last week we set up the format for the game, found some
pictures online, which we put in an image array, and tested
our random number generator. This week we’re going to
write the code that makes the game work and tell it to select
from our images at random every two seconds. We’ve
printed a complete list of the code for the Snap That! app on
the back cover of this section, for reference.
So, our first task is to add a CSS image background
instruction to our canvas elements from JavaScript — in
other words, to tell the game to put our pictures in the boxes.
It is called a background image because we can put text and
other items on top. This is complex stuff, but luckily for us
we can use an open source JavaScript library — or jQuery —
to help. Here’s what you do next.
1 CONNECT JQUERY LIBRARY
The phrase “standing on the shoulders of giants” is often
used of services such as jQuery. It is a library of JavaScript
code that is freely available for coders of all capabilities to
include in their programs. See panel, right, and take a look
at its website, jquery.com, if you’d like to find out more.
The code for the functions we are about to include runs to
hundreds of lines. Rather than insert it all into our script.js
file, we create a short link in our index.html file that directs
the browser to where it can find the code. It then remembers
it (until you clear the browser’s cache).
To include jQuery code we are going to use a CDN, or content
delivery network (see panel, far right). Insert the code below
in your index.html file (above where you link to script.js).
This will give us the power to use all the functions within the
jQuery library.
LOOPING
JQUERY
jQuery is a JavaScript
library for web
developers that
makes using JavaScript
quicker and easier.
jQuery provides many
easy-to-use functions
that help you to
manipulate and add
interactivity quickly to
your HTML page. When
connected to our project
it can be used to make
dynamic changes in
our code. jQuery UI is a
library that contains many
reusable components
such as date pickers,
progress bars, tooltips
and lots more.
<canvas id="2">Canvas not supported
</canvas>
3 CHANGE CANVAS BACKGROUND IMAGE FROM SCRIPT.JS
Now we have added unique IDs to our canvas elements we
can go to our script.js file and use the code below to change
their backgrounds (pretty cool, huh?).
We are using a jQuery function here called “.css” which adds
CSS to an element. The “$” is shorthand for jQuery — to save
developers from typing “jQuery”. Have a look at the preview
and you should see your images displaying. When you press
the Refresh icon, the images should change randomly.
All the rest of the code will be in the script.js file until we
reach step 20.
Let’s also add a comment (“// play function ends here”) to
the final closing { bracket. It’s easy to forget which function
these closing brackets connect to, so it is a good habit to
comment closing brackets.
// Create play function
function play() {
// Randomly change number
// Test random numbers
We’re adding these unique identifier attributes, or IDs, to
each canvas element in our index.html file so we can apply
different image backgrounds.
<p>PLAYER 2</p>
Inside our “play” function should be the variables for
num 1 & 2, img 1 & 2, url 1 & 2 and our jQuery functions to
change the canvas background image.
imgArray.length );
2 ID CANVAS ELEMENTS
// console.log("First random number is"
+num1);
IDS
The “ID” attribute can
be added to any element
to identify that element
uniquely. This allows
JavaScript or CSS to be
used to manipulate the
style, behaviour and
content of the element.
The HTML specification
states that the ID of an
element should be unique.
This means that one
element should not have
the same ID as another.
In practice, in most cases
you’ll probably get away
with using duplicate IDs.
A content delivery network
(CDN) is a network of
servers all over the
world that host files for
developers to use. In this
instance we’re using a
CDN to hold our jQuery file.
Many developers probably
want to use jQuery, so it
makes sense for us to all
link to the same file.
Also, now we’re happy our random number generator is
working properly we can “comment out” the console.log
tests — that is, we put two slashes before them to tell the
browser not to treat it as code. See “Comments” panel on
page 5.
num2 = Math.floor( Math.random() *
<script src="script.js"></script>
<p>PLAYER 1</p>
Create a new function called
“play”. Watch where this code
is added. It needs to wrap
around the code you’ve already
written that changes the image randomly.
imgArray.length );
1.11.0.min.js"></script>
</canvas><h1>PLAY SNAP THAT!</h1>
1 CREATE ‘PLAY’ FUNCTION
num1 = Math.floor( Math.random() *
<script src="//code.jquery.com/jquery-
<canvas id="1">Canvas not supported
Now we’ve got our images
displaying we need to set them
to change on a timer. To do this
we will use something called a
loop.
CONTENT
DELIVERY
NETWORK
// console.log("Second random number is"
+num2);
// Create image variables
var img1 = imgArray[ num1 ];
var img2 = imgArray[ num2 ];
// Create css value for background image
var url1 = "url("+ path + img1 +")";
var url2 = "url("+ path + img2 +")";
// Use jQuery to change css background
image of canvas 1 & 2
$("canvas#1").css("background-image",
url1);
ATTRIBUTE
Each element of an HTML
page can have a number of
“attributes”. A paragraph,
for example, might
have a style attribute,
or a link might have a
source attribute. These
are additional pieces of
information added by the
developer about a specific
element on the page.
$("canvas#2").css("background-
Watch where we add this code. It should go directly above
where we begin the “play” function.
image",url2);
// Create variables for canvasSTNMAST2008
1 & 2
var canvas1 = document.getElementById("1");
} // play function ends here
2 LOOP PLAY FUNCTION ON TIMER
To get the play function to loop we can add a “setTimeout”
function. This is another native function in JavaScript.
In the brackets that follow the function we need to add
two “arguments”. The first defines which function to run,
and the second defines how long to wait. In this case we are
running the “play” function, and setting the “delay”
argument to 2000 milliseconds — that’s two seconds,
of course, but we measure it in milliseconds. See
“Arguments” panel, right, for more information about how
this works.
Add this on the line just before your “play” function closes.
// Repeat loop every 2000 milliseconds
setTimeout(play, 2000);
} // play function ends here
3 USE H1 TO PLAY
Now that the image loop is within a function it won’t play
automatically. We need a button to trigger play, and we can
use the h1 to start the game.
We can add a load of jQuery functions to begin play and to
hide and show the h1 and paragraph elements. Watch where
this code is added. It goes above where the “play” function
begins.
var canvas2 = document.getElementById("2");
ARGUMENTS
Arguments are bits of
information that you give
a function that modify the
behaviour of the function.
If we were to think of
functions as verbs, we
could consider arguments
as adverbs. Imagine
we had a robot that
understood the function
“walk()”. We could pass an
argument to the function
to tell the function to walk
quickly like this:
walk(“quickly”);
A more realistic JavaScript
function would be the
native function alert(). The
alert() function displays a
popup in your browser with
a message. We pass the
function the message to
display like this:
alert(“Hello, world!”).
In this example, “Hello,
world!” would be the
argument.
$("h1").click(function() {
// Run play function
});
// Create play function
When you press your h1 in the “View Your App” preview, the
images should randomly cycle!
15
ADDING
TOUCH
Amazing! We’ve got our snap
game looping and displaying
random images. Now we need
to detect when a player touches
the screen.
1 CREATE VARIABLES FOR
CANVAS 1 & 2
Our canvas elements have been
labelled in our HTML as either 1
or 2. We use “document.getElementById” to find an element
in our HTML document and store the result in a new variable.
var canvas1 = document.getElementById("1");
var canvas2 = document.getElementById("2");
// Create event listeners for canvas 1 & 2
canvas1.addEventListener("touchstart",
playTouch1);
canvas2.addEventListener("touchstart",
playTouch2);
VIEW MY APP
On a desktop computer,
if you hover over “view
your app” a QR (quick
response) code should
appear. This is a visual
link to view your app,
and if you have a QR code
reader, you can scan
this image and your app
should open. If you don’t
have a QR code reader,
you should also see a
short link appear when
you hover over the “view
your app” link. You can
type this link into the
browser on your phone or
tablet and your app will
open.
playTouch1);
h1 when it has been pressed
$("p").show();
JavaScript can be used to
identify the name, or ID,
of an element on a page. It
is what’s called a “native”
function of JavaScript (one
that will work without
any external libraries or
plugins).
// Create variables for canvas 1 & 2
canvas1.addEventListener("touchstart",
// Use jQuery 'hide' function to hide
DOCUMENT.
GETELEMENTBYID
After “touchstart” we tell it what to do when a touch is
received. “playTouch1” and “playTouch2” are new functions
that we’ll create next. We could call these anything, but these
names are short and clear.
// Create event listeners for canvas 1 & 2
play();
'p's when play is started
The “addEventListener” function (see panel, below left) allows
us to detect if there is a user touch or click. In the brackets we
define when the device should react. In our case we want it to
trigger when the user first touches the screen, so on
“touchstart”, rather than “touchend” or “touchmove”.
When a touch is detected in a canvas — in other words, on
one of the pictures — it will trigger one of these functions.
Now we’re using touch we can’t test this on a PC any more, so
we can use an alert popup instead. Get “View Your App”
running on your smart phone or tablet and test the touch
events are registering.
starts play
// Use jQuery 'show' function to show
2 CREATE EVENT LISTENERS FOR CANVAS 1 & 2
3 CREATE PLAYTOUCH 1 & PLAYTOUCH 2
// Use jQuery 'click' function so h1
$("h1").hide();
// Create play function
!
canvas2.addEventListener("touchstart",
EVENT
LISTENER
An event listener is a
function that responds
to some event in your
browser.
For instance, you can add
an event listener to the
“submit” event of a form
on your page.
When the form is
submitted by the user, any
functions listening for this
event will be run before
the normal behaviour
of submitting the form
content to the server is
allowed. This is exactly
how form validation
works. In this case, the
event listener will check
the submitted details and
if any of the data is invalid
(for example, an email
address isn’t valid), the
event listener will stop the
browser from submitting
the form.
playTouch2);
// User clicks canvas1
EVENT.
PREVENTDEFAULT
function playTouch1() {
// Test touch is registered
alert("Player 1 Touch!");
Sometimes on a web
app we don’t want the
default behaviour of, say,
a mouse click to trigger
anything. The “prevent
default” function will
prevent something from
happening (usually a
new page loading), which
means that we can give
the user a smoother
experience.
}
// User clicks canvas2
function playTouch2() {
// Test touch is registered
alert("Player 2 Touch!");
}
4 PREVENT TOUCH MOVE
When you were testing your apps, you may have found that
the browser screen moved up and down. For our game we
want to fix the browser in place. So we insert another
“addEventListener” at the top of script.js. This is targeting the
Turn to page 4 Â
CREATE AN APP IN A DAY
} // play function ends here
whole document body element and prevents the default
behaviour.
// Find out if there was a snap
// Stop browser scrolling
function snapCheck() {
document.body.
addEventListener("touchmove",
function(event) {
event.preventDefault();
});
// Test if script.js is working
// alert("Hello World!");
Your game is now able to detect touch inputs! You’ll have to
test this next bit on your smartphone or tablet, as your PC
(probably) can’t detect touch. If you hover over “View Your
App”, a short URL and a QR tag will show to help you launch
your app on your device. If your game is working properly,
when you press the top canvas (player 1) or bottom canvas
(player 2) an alert should pop up!
16
OBJECTS
AND LOGIC
if (num1 == num2) {
OBJECT
An object is a good way
of storing a number of
variables. Rather than
saving the score and the ID
of one player separately,
we can save them together.
This means they will be
easier to compare when we
need to pick a winner.
Under the lines where we created our “num1” and “num2”
variables, create two “objects”. These look like the variables
created just above, but they contain multiple pieces of
information, a score and an ID.
We set their initial scores to zero and give them each a
unique ID.
// Create variables for which card to
pick randomly
var num1;
alert("SNAP!");
} else {
// Images do not match!
alert("NO SNAP!");
}
}
// User clicks canvas1
function playTouch1() {
// Test touch is registered
// alert("Player 1 Touch!");
// Run snapCheck to see if there is a
snap!
LOGIC
Logic is what we call the
decisions we make in
code. In this case we are
comparing “num1” and
“num2” and asking if
they are the same (==). If
they are, this means the
images must be the same,
an alert pops up that says
“SNAP!”
snapCheck();
}
// User clicks canvas2
function playTouch2() {
// Test touch is registered
// alert("Player 2 Touch!");
// Run snapCheck to see if there is a
}
Now when a player taps an image, our new snapCheck
function will run to see if there is a snap. Test this is working
on your smartphone or tablet. Tap “Play Snap That” and if
the images are the same you should see a popup: “SNAP!”
id: 1,
};
};
2 CREATE SNAPCHECK FUNCTION
Next, we’re going to check if a snap has been made. Create a
new function at the bottom of script.js. We can call this
anything, but snapCheck seems a good name. Inside the
function we are going to compare the two “num” variables
to see if they are the same. In JavaScript we use “==” to
compare two things. If they are the same, an alert is
triggered that will say, “SNAP!” If they are not the same, an
alert will display saying, “NO SNAP!”
Our new snapCheck function won’t change anything quite
yet, though, as we aren’t running this new function.
Return true means that
the function will stop and
record a value of “true”;
return false means the
same but that a value of
“false” will be recorded.
snapCheck();
score: 0,
id: 2,
‘RETURN TRUE’ AND
‘RETURN FALSE’
snap!
var player1 = {
score: 0,
A double plus (++) adds
one to a variable, and a
double minus (--) takes
away one from a variable.
Comment out the lines in playTouch1 and playTouch2 that
run the two alerts and add in snapCheck();
// Create object for Player 1
var player2 = {
++ AND Finally, we’re going to add in a line that will run our new
snapCheck function.
var num2;
// Create object for Player 2
+/-
3 RUN SNAPCHECK IN PLAYTOUCH FUNCTIONS
Our app is taking shape. Let’s
weave in some behaviour to
turn our app into a game. First
we need to store information
about our players. We’re going
to create an object and use this
in our game logic (see panels,
right).
1 CREATE OBJECTS FOR PLAYER 1
AND PLAYER 2
// Images match! Snap!
<SPAN>
17
SPAN
SCORING
A span is an HTML
element that we can use
to hold a word or piece
of text. Spans can be
updated dynamically – in
the case of a score, for
example.
We can now detect if there is a
snap or not. We should award
players points when they get a
snap, and let’s give them some
feedback while they play so it’s
easy to see who’s winning.
with the ID score1 and score2.
1 ADDING A SCORE SPAN
We need an area to display the
score in our HTML content.
Find the two p elements for
PLAYER 1 & 2 and add spans
<p>PLAYER 1: <span
id="score1">0</span></p>
<p>PLAYER 2: <span id="score2">0</span>
</p>
2 TELL SNAPCHECK WHICH PLAYER TOUCHED SCREEN
// User clicks canvas1
CACHED
What is "cached"?
It means that something
— usually images or
videos — is saved to a
user’s browser so that
it can be loaded more
quickly.
ERROR? DON'T PANIC
Inevitably it won't always work. If you get an error message, go back through and check every line of code.
We’ve printed the complete code for the app on the back cover. Help is also at hand at our forum — post your problem at forum.playto.io
function playTouch1() {
// Images match! Snap!
// Test touch is registered
// alert("SNAP!");
// alert("Player 1 Touch!");
// Player gains 1 point
// Run snapCheck to see if there is a
player.score++;
snap!
3
// Update player score
snapCheck(player1);
}
$("span#score"+player.id).html(player.
score);
// Highlight player won!
// User clicks canvas2
function playTouch2() {
// Test touch is registered
// alert("Player 2 Touch!");
// Run snapCheck to see if there is a
$("p#player"+player.id).
#
snap!
snapCheck(player2);
}
When we call “snapCheck” from within “playTouch1” and
“playTouch2” we can be clear which player has touched the
screen. Add “player1” and “player2” as an argument between
the brackets that follow “snapCheck”.
3 ADD A PLAYER ARGUMENT TO SNAPCHECK
Now in our “snapCheck” function we can use our player
object as an argument to give that player a point.
First, add an argument into the brackets after “snapCheck”
— snapCheck(player). Then inside snapCheck it will replace
“player” with the information sent from “playTouch1” or
“playTouch2”. It will then change player1.score or player2.
score.
We use ++ to increase by 1, and -- to decrease by 1.
// Find out if there was a snap
function snapCheck(player) {
if (num1 == num2) {
// Images match! Snap!
alert("SNAP!");
// Player gains 1 point
player.score++;
} else {
// Images do not match!
alert("NO SNAP!");
// Player loses 1 point
player.score--;
}
}
STNMAST2008
css("background", "LightGreen");
} else {
// alert("NO SNAP!");
// Player loses 1 point
#
In CSS and jQuery, a hash
symbol means that you
are targeting the “ID” of
an element.
THE
CONSOLE
// Images do not match!
player.score--;
// Update player score
$("span#score"+player.id).html(player.
score);
// Highlight player lost a point
$("p#player"+player.id).
CSS
css("background", "DeepPink");
}
}
5 RESET PLAYER P BACKGROUND
CSS
CSS, THE LANGUAGE
OF DESIGN
CSS stands for cascading
style sheets. It was
developed by Hakon Wium
Lie and Bert Bos in the
early 1990s.
Fundamentally, CSS
gives developers the
ability to breathe life into
HTML – colours, borders,
backgrounds and more.
We’ll be showing you a
variety of CSS commands,
but to see an entire list
of them have a look at
the W3 Schools CSS page
at w3schools.com/css.
So when a snap is attempted, the background colour of our
player p elements will change. When a new pair of images is
shown, we need to reset our player p backgrounds to yellow.
Now the score has changed, we can display it in our page
using a jQuery “.html” function. This replaces any existing
HTML in an element with updated content. It is great when
you want to dynamically give a user new text or information.
Comment out the alerts in “snapCheck” and add in two new
jQuery functions. Remember, $ means the program is using a
jQuery function.
Finally, we use another jQuery CSS function to change the
background of our “player p” to show who won, or lost, a
point.
// Find out if there was a snap
function snapCheck(player) {
if (num1 == num2) {
1) It is a place to output
diagnostic information
like JavaScript and CSS
errors and any information
passed to the console.
2) It is an interface in
your browser where you
can execute JavaScript
commands directly.
This lets you test out
JavaScript commands
before adding them
to a script.
Add a new jQuery CSS function in the play function.
// Repeat loop every 2000 milliseconds
setTimeout(play, 2000);
// Reset player p backgrounds
$("p").css("background", "yellow");
} // play function ends here
6 ADD P PLAYER IDs IN HTML
Finally, we need to add the p paragraph IDs into our HTML so
they will change colour.
<p id="player1">PLAYER 1: <span
id="score1">0</span></p>
<p id="player2">PLAYER 2: <span
id="score2">0</span></p>
4 DISPLAY UPDATED SCORE AND HIGHLIGHT WINNER
The console displays
diagnostic information
about the web page
being displayed.
It has two purposes:
You should find that if the images are matching, the player’s
score will increase and the p background will change to green.
If not, the player will lose a point and the colour will change
to pink. The colours should reset when an image changes.
18
SINGLE WINNER
You may have noticed in your
testing that it is possible to have
more than one winner, or loser.
This is not ideal ...
1 CREATE A ‘SNAPMADE’
FUNCTION
Below your player objects,
create a new variable. Again,
we could call this new variable
Turn to page 6 Â
COMMENTS
These are essential for
any web project. One
reason you should always
try to put comments
in your work is in case
another developer picks
up the project and wants
to continue with it. In the
open-source community,
where hundreds or
thousands of people will
be working on a project,
comments allow people to
explain how they decided
to structure the code. Even
if you’re the only one who
will ever be coding your
project, if you write some
code and then come back
to it a year later you may
have forgotten why you
wrote it. Comments are
really useful for jogging
the memory.
CREATE AN APP IN A DAY
// Test touch is registered
anything, but “snapMade” is short and clear. This will allow
us to control what happens when a snap has been made, and
stop any further points being dished out.
// alert("Player 1 Touch!");
// Run snapCheck to see if there is a
// Create object for Player 2
var player2 = {
score: 0,
id: 2,
};
// Create snapMade variable
var snapMade = "NO";
2 SET SNAPMADE TO ‘YES’ IN SNAPCHECK
“snapMade” will now be set to “YES” if a player correctly
gets a snap.
BE AS CREATIVE
AS YOU LIKE
Once you understand
the principles of CSS,
you can add as many
rules for each bit of the
page as you like. What's
great too is that they're
all interchangeable, so if
you know how to change
the size of a heading, you
can change the size of a
paragraph (or anything
else you like).
// Find out if there was a snap
function snapCheck(player) {
if (num1 == num2) {
// Images match! Snap!
// alert("SNAP!");
// Player gains 1 point
player.score++;
// Update player score
$("span#score"+player.id).html(player.
score);
// Highlight player won!
$("p#player"+player.id).
css("background", "LightGreen");
// Snap Made!
snapMade = "YES";
}
3 RESET SNAPMADE IN PLAY FUNCTION
At the top of our play function, now that images are reset, we
should reset snapMade to “NO” so the game can continue.
// Create play function
function play() {
// Reset snapMade
snapMade = "NO";
// Randomly change number
num1 = Math.floor( Math.random() *
imgArray.length );
num2 = Math.floor( Math.random() *
imgArray.length );
snap!
if (snapMade == "NO") {
snapCheck(player1);
}
}
// User clicks canvas2
function playTouch2() {
// Test touch is registered
// alert("Player 2 Touch!");
// Run snapCheck to see if there is a
snap!
if (snapMade == "NO") {
RGB
snapCheck(player2);
}
IN THE PINK
There is a set number of
"word colours" that have
already been defined by
developers, but if you truly
want to customise your
design, you'll need to
pick your own.
To do this, you can go
to colorpicker.com, and
you'll see that each colour
has an R, G and B value
(standing for red, green,
blue). Just select a colour
you like, and then copy the
RGB colours to your CSS.
For example, you might
change your heading to a
lovely shade of pink:
h1 {
color: rgb(222, 38, 210);
}
If you'd like to have a bit
of transparency in your
colour, you can also give it
an "alpha" value between
0 and 1, with 0 being
completely transparent
and 1 being opaque.
h1 {
color: rgba(222, 38, 210,
0.8);
}
}
Now only one player should be able to win a point for each
image snap. Have a quick play to check it is working
properly!
19
WINNER LOGIC
It’s possible that you’ve already
had some fun playing your
snap game. We think every
game benefits from a goal — so
next we’re going to set a
winning score, and when that
target is reached we’ll display a
winner.
Finally, in our playTouch functions, before we run snapCheck
we use some logic to see if a snap has already been made. If
snapMade is equal to “NO”, the program will go on to check
if the images match. If snapMade is equal to “YES”,
snapCheck will not be run and the player cannot gain any
points.
// User clicks canvas1
function playTouch1() {
In the Playto editor, hover
over the “View Your App”
link in the top right of
the screen. This will give
you a short link that’s
perfect for sharing on your
favourite social media
sites! Why not challenge
your friends and family to
a game the next time you
see them. You could ask
your friends to share their
scores via social media
and create a leaderboard
of the speediest snappers.
1 ADD ISTHEWINNER LOGIC TO
PLAY FUNCTION
Inside your play function, add some
logic which checks if “player1” or “player2” is the winner. If
not, the play function will carry on looping the images as
before.
Watch where this code is added. The check code starts just
after the “play” function starts, and ends just before the
“play” function finishes.
// Create play function
function play() {
// Check is there is a winner??
if (isTheWinner(player1) ||
isTheWinner(player2)) {
return
} else {
// Reset snapMade
4 ADD SNAPMADE LOGIC TO PLAYTOUCH 1 & PLAYTOUCH 2
LET THE WORLD
PLAY YOUR GAME
snapMade = "NO";
.......
// Repeat loop every 2000
milliseconds
setTimeout(play, 2000);
We would like to thank
the team at Decoded for
all their help with this
project, and for creating
the Snap That! game.
Decoded, which has
offices in London,
New York and Sydney,
aims to spread “digital
enlightenment”. It runs
regular one-day courses
for those wanting to
improve their digital
skills as well as providing
online resources such as
the tutorial on which this
supplement is based. Go
to decoded.com to find
out more.
} // isTheWinner logic ends here
} // play function ends here
You’ve now finished all the JavaScript in your Snap That!
game. When you play it, there should be a set number of
wins, and when that is reached, the looping images will
stop and the h1 will change to display the winner!
20
2 CREATE ISTHEWINNER FUNCTION
Now we need to create our “isTheWinner” function. You
can put this right at the bottom of script.js. This will
receive either “player1” or “player2” when it is run from
our “play” function.
It then compares the score value with a number. We’ve set
the number of wins to 2 — you can set it to whatever you
like.
PRELOADING IMAGES
AND DEBUGGING
You may find that your images
are a little sluggish to load,
and they don’t always
display in sync. This is
because we are reloading the
background image each
time. What we can do is
preload the images first —
then the browser will be
able to call the cached
versions and run much more
smoothly.
If the player score is equal to 2, it will send a message back
to the play function that there is a winner. If the player
score is not equal to 2 it will send a message that there is
currently no winner. Our play function checks both player1
and player2. If there are no winners it will continue
looping our images.
1 ADD PRELOADING SPANS TO HTML
// Has a player won?
<canvas class="card" id="2">Canvas not
function isTheWinner() {
supported</canvas>
// If player reaches a score of 2
points they win!!
if(player.score == 2) {
// Tell play function there is a
winner!
STNMAST2008
In your HTML, just below the second canvas element, add
in some spans with unique IDs. Each span needs a unique
ID; we’ve used “preload-01” etc. You will need the same
number of spans as you have images in your game.
<span id="preload-01"></span>
<span id="preload-02"></span>
<span id="preload-03"></span>
<span id="preload-04"></span>
<span id="preload-05"></span>
return true
}
// Tell play function there is no
winner
return false
}
In your Style.css file add an instruction for each of your
new spans (we’ve done two below). Each span should be
given one of your images as its background. As we haven’t
given our spans any size they will not display in our page.
However, our CSS will now preload our images.
span#preload-01 {
3 HIDE P AND SHOW NEW H1 CONTENT
If there is a winner, we can add jQuery functions to hide
our player scores, show our h1 and change the content of
our h1 to display the winner.
Check this is working properly. You can also play around
with the target score to make it harder or easier to win!
// Has a player won?
function isTheWinner(player) {
// If player reaches a score of 5
points they win!!
if(player.score == 2) {
$("p").hide();
$("h1").html("PLAYER " + player.id
+ " WINS!");
$("h1").show();
// Tell play function there is a
winner!
return true
}
// Tell play function there is no
winner
return false
}
2 ADD BACKGROUND IMAGES TO YOUR SPANS IN CSS
background: url("http://image-url/
image1.jpg");
}
span#preload-02 {
background: url("http://image-url/
image2.jpg");
}
3 CHECK OUR IMAGES ARE PRELOADING IN NETWORK
Test out your game. The images should load much more
smoothly now.
You can also check the images are loading by using a
browser tool similar to the console from step 11. Open the
console as before, but then click on the “Network” tab to
the left of the console at the top of the console space.
When you refresh the page you should see all your images
loading in the background.
CONGRATULATIONS!
Feel free to customise your game. You can change the
colours, fonts, the number of wins required, how fast the
images cycle and add as many images as you like! I’m sure
you’ve figured this out, but if you want to play again,
simply refresh the browser.
When you’re finished, make sure you share your creation.
See the “Let the world play your game” panel on the
opposite page for ideas.
We’ve built versions of Snap That! with cats, cars, dogs and cakes.
Let your imagination run riot and tell us what you’ve come up with
Quick check: if you have
followed the instructions in
last week’s section and
these pages correctly,
the code you have written
should look as it does in the
boxes below — if you have
any problems there is a
forum waiting to help you at
forum.playto.io.
Key in your question and it
will be answered
INDEX .HTML
<!--This app was made by Harriet-->
<!DOCTYPE html>
<html>
<head>
<title>Snap That!</title>
<meta name="viewport"
content="width=device-width,
initial-scale=1.0, userscalable=no">
<link href="style.css"
rel="stylesheet">
</head>
<body>
<section>
<canvas id="1" >Canvas not
supported</canvas>
<h1>PLAY SNAP THAT!</h1>
<p id="player1"> PLAYER 1:
<span id="score1">0</span> </p>
<p id="player2">PLAYER 2:
<span id="score1">0</span></p>
<canvas id="2">Canvas not
supported</canvas>
<span id="preload-01"></span>
<span id="preload-02"></span>
<span id="preload-03"></span>
<span id="preload-04"></span>
<span id="preload-05"></span>
</section>
<script src="//code.jquery.com/
jquery-1.11.0.min.js"></script>
<script src="script.js"></script>
</body>
</html>
SCRIPT.JS
STYLE.CSS
body {
font-family:Helvetica;
text-align:center;
background:LightGrey;
}
canvas {
width:100%;
height:42%;
background-color:yellow;
border-radius:15px;
background-image:url("http://
image-url/image1.jpg");
background-size:cover;
background-position:center;
}
html, body, section {
height:100%;
}
h1 {
background:yellow;
padding:2%;
margin:2%;
border:2px solid black;
border-radius:40px;
}
p {
width:40%;
float:left;
padding:2%;
margin:2%;
border:2px solid black;
border-radius:40px;
background:yellow;
display:none;
}
span#preload-01 {
background: url(“http://image-url/
image1.jpg”);
}
span#preload-02 {
background: url(“http://image-url/
image2.jpg”);
}
span#preload-03 {
background: url(“http://image-url/
image3.jpg”);
}
span#preload-04 {
background: url(“http://image-url/
image4.jpg”);
}
span#preload-05 {
background: url(“http://image-url/
image5.jpg”);
}
// Stop browser scrolling
document.body.
addEventListener("touchmove",
function(event) {
event.preventDefault();
});
// Test if script.js is working
// alert("Hello World!");
// Define images to use
var imgArray = ["http://image-url/
image1.jpg","http://image-url/image2.
jpg","http://image-url/image3.
jpg","http://image-url/image4.
jpg","http://image-url/image5.jpg"];
// Create variables for which card to
pick randomly
var num1;
var num2;
// Create object for Player 1
var player1 = {
score: 0,
id: 1,
};
// Create object for Player 2
var player2 = {
score: 0,
id: 2,
};
// Create snapMade variable
var snapMade = "NO";
// Use h1 to play
$("h1").click(function() {
// Run play function
play();
// Use jQuery 'hide' function to
hide h1 when it has been pressed
$("h1").hide();
// Use jQuery 'show' function to
show 'p's when play is started
$("p").show();
});
// Create variables for canvas 1 & 2
var canvas1 = document.
getElementById("1");
var canvas2 = document.
getElementById("2");
// Create event listeners for canvas
1 & 2
canvas1.addEventListener("touchstart",
playTouch1);
canvas2.addEventListener("touchstart",
playTouch2);
// User clicks canvas1
function playTouch1() {
// Test touch is registered
// alert("Player 1 Touch!");
// Run snapCheck to see if there
is a snap!
if (snapMade == "NO") {
snapCheck(player1);
}
}
// User clicks canvas2
function playTouch2() {
// Test touch is registered
// alert("Player 2 Touch!");
// Run snapCheck to see if there
is a snap!
if (snapMade == "NO") {
snapCheck(player2);
}
}
// Create play function
function play() {
// Check is there is a winner??
if (isTheWinner(player1) ||
isTheWinner(player2)) {
return
} else {
// Reset snapMade
snapMade = "NO";
// Randomly change number
num1 = Math.floor( Math.random()
* imgArray.length );
num2 = Math.floor( Math.random()
* imgArray.length );
// Test random numbers
// console.log("First random
number is " +num1);
// console.log("Second random
number is "+num2);
// Create image variables
var img1 = imgArray[ num1 ];
var img2 = imgArray[ num2 ];
// Create css value for
background image
var url1 = "url("+ img1 +")";
var url2 = "url("+ img2 +")";
// Use jQuery to change css
background image of canvas 1 & 2
$("canvas#1").css("backgroundimage", url1);
$("canvas#2").css("backgroundimage", url2);
// Repeat loop every 2000
milliseconds
setTimeout(play, 2000);
// Reset player p backgrounds
$("p").css("background",
"yellow");
} // isTheWinner logic ends here
} // play function ends here
// Find out if there was a snap
function snapCheck(player) {
if (num1 == num2) {
// Images match! Snap!
// alert("SNAP!");
// Player gains 1 point
player.score++;
// Update player score
$("span#score"+player.id).
html(player.score);
// Highlight player won!
$("p#player"+player.id).
css("background", "LightGreen");
// Snap Made!
snapMade = "YES";
} else {
// Images do not match!
// alert("NO SNAP!");
// Player loses 1 point
player.score--;
// Update player score
$("span#score"+player.id).html(player.
score);
// Highlight player lost a point
$("p#player"+player.id).
css("background", "DeepPink");
}
}
// Has a player won?
function isTheWinner(player) {
// If player reaches a score of 5
points they win!!
if(player.score == 2) {
$("p").hide();
$("h1").html("PLAYER " + player.
id + " WINS!");
$("h1").show();
// Tell play function there is a
winner!
return true
}
// Tell play function there is no
winner
return false
}
TO GET STARTED GO TO
THESUNDAYTIMES.CO.UK/LEARNTOCODE