Mobile game/soft development
Transcript of Mobile game/soft development
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
Mobile game/soft development
Krzysztof Podlaski, University of Lodz, Poland
Abstract
The material covers mobile development in Apache Cordova Frame-work. It allows students to create their mobile game/applications usingHTML5, Javascript, and CSS. The basic ways of accessing capabilities ofmobile devices like GPS, accelerometer, etc., are also covered. As some-times developer needs to access data using AJAX queries, the JQuerylibrary is also introduced. The course should be taken after ’Games De-velopment in JavaScript’. Therefore, it shows how the code from theprevious course can be run on a mobile device using the Cordova frame-work.
The original version of this material can be found on project web page:http://geniusgamedev.eu/teaching.php.
Type: E-learning module, online-training, MOOC
Domain: Software development
Requirements: Basic knowledge in JavaScript programming,
Target group: Computer Science students
License
The material is distributed under Creative Commons Attribution license.
Disclaimer
The European Commission’s support for the production of this publica-tion does not constitute an endorsement of the contents, which reflect theviews only of the authors, and the Commission cannot be held responsiblefor any use which may be made of the information contained therein.
1
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
Chapter 1
Introduction to jQuery
Before we start with mobile application development let us �rst introduce avery well known and useful library jQuery. Here we will cover some basics ofjQuery library and how to use it for simple internet queries. The jQuery librarybasically can be used to do following operations:
• Manipulation of HTML/DOM elements in a web application.
• Manipulation of CSS properties/elements in a web application.
• Create/add Listeners to HTML events.
• Create simple e�ects and animations in a web application.
• Invoke and receive AJAX queries.
1.1 Include jQuery into a project
The jQuery can be included int our project in two simple ways:
• as external resource,
• as internal resource,
The di�erence is only on loading time and requirements of available internetconnectivity.
<!-- Use External jQuery from Google CDN -->
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery
.min.js">
</script>
<!-- Use External jQuery from Microsoft CDN -->
<script type="text/javascript"
1
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
2 CHAPTER 1. INTRODUCTION TO JQUERY
src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.
js">
</script>
<!-- Use Internal copy of jQuery library -->
<script type="text/javascript"
src="js/jquery-3.3.1.min.js">
</script>
It is better to add <script> tag at the end of <body> section of web page.At this moment 3.3.1 is the newest version of jQuery, however everybody canuse the version of own choose. The library �les are usually available in twoversions jquery-3.3.1.js and jquery-3.3.1.min.js, the former is bigger and is madeespecially for developers to analyse while the latter is smaller and unreadable forpeople because all unneeded space characters are omitted, therefore this versionis preferred as it requires shorter time to load and smaller bandwidth.
1.2 Selector operator
One of the most important element introduced in jQuery is selection operator $,this is an shortcut to original javascript selection methods like getElementByIdor querySelector.
1 $("#myButton") // find element with ID myButton
2 $("div") //select all <div> elements
3 $(".someClassName") //select all elements with someClassName
4 $("img.cName") //select all <img> elements with class cName
With use of selector, we can easily operate on DOM elements of our webpages. DOM - Document Object Model - an object representation of htmldocument and its elements. However, we have to remember that jQuery selectoris not exactly document.getElementById operation. By default selector wrapsall elements that �ts the pattern so it is more like the list of appropriate objectsthan a single object. That means selector has no direct access to all objectmethods. In order to get a DOM object from selector we should use directrequest of list element like in the following code:
var el = document.getElementById("some_id");
//Equivalent operation with use of jQuery selector
var el = $("#some_id")[0];
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
1.3. ADD SIMPLE ACTIONS WHEN PAGE IS LOAD 3
1.3 Add simple actions when page is load
When a selector gives an object we can bind operations to events connected withthis object. For example object "document" - that represents the web page havean event 'load'. This event is �red whenever the browser �nish loading pagewith all required additional �les.
1 <html>
2 <head>
3 </head>
4 <body>
5 <button>Button A</button>
6 <button>Button B</button>
7 <button>Button C</button>
8 <script type="text/javascript"
9 src="http://ajax.googleapis.com/ajax/libs/jquery
/3.3.1/jquery.min.js">
10 </script>
11 <script type="text/javascript">
12 $(document).ready(
13 function(){
14 $("button").click(function(){
15 $(this).hide();
16 });
17 }
18 );
19 </script>
20 </body>
21 </html>
Remark
Just for simplicity our js code is simply included inside .html �le. In thereal word it is better to save that in external .js �le and include to thepage using <script> tag. All .js �les that uses jQuery should be includedafter the jQuery library.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
4 CHAPTER 1. INTRODUCTION TO JQUERY
Code Explained
In the line 12 we can see the selector $('document') and a de�nition whatshould happen when page is 'ready' i.e. when 'load' event is �red.
$(document).ready(
Inside "ready(...)" we de�ne a new anonymous function that will be bindto 'ready' event. The function is anonymous as it is a method that willbe used in one place and no name is needed. Anonymous functions areusually de�ned like the examples below:
function() { ...} //anonymous function without parameters
function(par1, par2) { ...} //anonymous function with two
parameters par1 and par2
In this anonymous function in the line 13 we select all <button> elements,and create an action connected with 'click' event. The 'click' event willbe invoked whenever user clicks the button. In the code (line 15), weordered to hide the clicked element (button). An operation .hide comesfrom jQuery and allow to make elements invisible.
$("button").click(function(){
$(this).hide();
});
In the result when page is loaded the actions are added to all three buttonsseparately. When any of the buttons is clicked it hides.
It it obvious that if in jQuery we have hide operation, there have to be alsoa show one
1 <html>
2 <head>
3 </head>
4 <body>
5 <img src="logo.jpg" />
6 <p>
7 <button id="btn1">Hide</button>
8 <button id="btn2">Show</button>
9
10 <script type="text/javascript"
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
1.3. ADD SIMPLE ACTIONS WHEN PAGE IS LOAD 5
11 src="http://ajax.googleapis.com/ajax/libs/jquery
/3.3.1/jquery.min.js">
12 </script>
13 <script type="text/javascript">
14 $(document).ready(function(){
15 $("#btn1").click(function(){
16 $("img").hide();
17 });
18
19 $("#btn2").click(function(){
20 $("img").show();
21 });
22 });
23 </script>
24 </body>
25 </html>
Code Explained
We add anonymous function to click event for both buttons "btn1" and"btn2" in the lines 15 and 19 respectively. in both of this methods weshow or hide the element <img>.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
6 CHAPTER 1. INTRODUCTION TO JQUERY
Extercises
Starting with the webpage of the form
1 <html><head></head>
2 <body>
3 <div class="basicText">
4 <b>Gaius Julius Caesar</b> (12 or 13 July 100 BC -
15 March 44 BC), known by his nomen and
cognomen Julius Caesar, was a Roman politician,
military general, and historian who played a
critical role in the events that led to the
demise of the Roman Republic and the rise of
the Roman Empire. He is also known as an author
of Latin prose.
5 </div>
6 <button id="photoOn">Show Julius Caesar</button>
7 <br>
8 <img src="https://tinyurl.com/ycg27bgy"
9 height="150pt" class="hidden" id="photoJC"/>
10 <div class="hidden">
11 Julius Caesar Empire:<br/>
12 <img src="https://tinyurl.com/y7qwn8o9"
13 id="map" />
14 </div>
15 <hr/>
16 <button id="btn1" >Show All</button><br/>
17 <button id="btn2" class="hidden">Hide all again</button>
18
19 <script type="text/javascript"
20 src="http://ajax.googleapis.com/ajax/libs/
jquery/3.1.1/jquery.min.js">
21 </script>
22 <script type="text/javascript">
23 $(document).ready(function(){
24 $(".hidden").hide();
25 //Add content to make it work as described
26 });
27 </script>
28 </body>
29 </html>
Add the following functionalities:
• When user click on the button "Show Julius Caesar" the photo ofthe Caesar is shown
• When user click on the button "Show All" every hidden elementsare shown
• When user click on the button "Hide all again" all elements backto the original state.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
1.3. ADD SIMPLE ACTIONS WHEN PAGE IS LOAD 7
In the next example we will introduce a similar jQuery method called toggle,this operation can be used show the visible elements and hide invisible ones.
1 <html>
2 <head>
3 </head>
4 <body>
5 <button id="ch_btn">Other Stanza</button>
6 <hr/><hr/>
7 <p id="Stanza1">
8 Tyger Tyger, burning bright, <br>
9 In the forests of the night; <br>
10 What immortal hand or eye, <br>
11 Could frame thy fearful symmetry?
12 </p>
13
14 <p id="Stanza2" style="display:none">
15 In what distant deeps or skies,<br>
16 Burnt the fire of thine eyes?<br>
17 On what wings dare he aspire?<br>
18 What the hand, dare seize the fire?
19 </p>
20
21 <script type="text/javascript"
22 src="http://ajax.googleapis.com/ajax/libs/jquery
/3.3.1/jquery.min.js">
23 </script>
24 <script type="text/javascript">
25 $(document).ready(function(){
26 $("#ch_btn").click(function(){
27 $("p").toggle();
28 });
29 });
30 </script>
31
32 </body>
33 </html>
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
8 CHAPTER 1. INTRODUCTION TO JQUERY
Code Explained
After the page loads, one of the <p> elements is hidden because in line14 we set style to display:none.
<p id="Stanza2" style="display:none">
Here in the line 27 we invoke toggle method on all <p> element. Thiswill toggle elements between two states hidden and shown.
Additional jQuery actions like slideDown, slideUp, slideToggle allows similaroperations but as animated action not instant ones.
1 <html>
2 <head>
3 </head>
4
5 <body>
6 <button id="hide_btn">Hide Author info</button>
7 <button id="show_btn">Show Author info</button>
8 <button id="toggle_btn">Other Stanza</button>
9 <hr/>
10 <div id="Author">
11 William Blake (28 November 1757 - 12 August 1827) was an English
poet, painter, and printmaker. Largely unrecognised during
his lifetime, Blake is now considered a seminal figure in
the history of the poetry and visual arts of the Romantic
Age. What he called his prophetic works were said by 20th-
century critic Northrop Frye to form <i>what is in
proportion to its merits the least read body of poetry in
the English language</i>. His visual artistry led 21st-
century critic Jonathan Jones to proclaim him <i>far and
away the greatest artist Britain has ever produced</i>. In
2002, Blake was placed at number 38 in the BBC's poll of the
100 Greatest Britons. While he lived in London his entire
life, except for three years spent in Felpham, he produced a
diverse and symbolically rich ouvre, which embraced the
imagination as <i>the body of God</i> or <i>human existence
itself</i>.
12 </div>
13 <hr/>
14 <p id="Stanza1">
15 Tyger Tyger, burning bright, <br>
16 In the forests of the night; <br>
17 What immortal hand or eye, <br>
18 Could frame thy fearful symmetry?
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
1.3. ADD SIMPLE ACTIONS WHEN PAGE IS LOAD 9
19 </p>
20
21 <p id="Stanza2" style="display:none">
22 In what distant deeps or skies,<br>
23 Burnt the fire of thine eyes?<br>
24 On what wings dare he aspire?<br>
25 What the hand, dare seize the fire?
26 </p>
27
28 <script type="text/javascript"
29 src="http://ajax.googleapis.com/ajax/libs/jquery
/3.1.1/jquery.min.js">
30 </script>
31 <script type="text/javascript">
32 $(document).ready(function(){
33 $("#hide_btn").click(function(){
34 $("#Author").slideUp();
35 });
36
37 $("#show_btn").click(function(){
38 $("#Author").slideDown();
39 });
40
41
42 $("#toggle_btn").click(function(){
43 $("p").slideToggle();
44 });
45
46
47 });
48 </script>
49
50 </body>
51 </html>
Extercises
Within the last code change methods slideDown, slideUp, slideToggleinto new operations: fadeIn, fadeOut, fadeToggle.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
10 CHAPTER 1. INTRODUCTION TO JQUERY
Extercises
All of the animation operations can have additional time parameters (inmilliseconds), test how it changes the original behaviour.
.hide(300),
.slideDown(300),
.fadeOut(300)
There are also prede�ned speeds 'slow', 'fast', 'normal':
.show('fast')
1.3.1 Other actions
jQuery introduces more operations like click, these are dblclick, mouseover,mouseout. And additionally more sophisticated animation driven by changes inthe style of the element
1 <html>
2 <head>
3 </head>
4 <body>
5 <img id="tiger_img" src="https://tinyurl.com/y7ts3v7o" height="
150">
6 <hr/><hr/>
7 <div style="color: #00ff00">
8 Tyger Tyger, burning bright, <br>
9 In the forests of the night; <br>
10 What immortal hand or eye, <br>
11 Could frame thy fearful symmetry?
12 </div>
13
14 <script type="text/javascript"
15 src="http://ajax.googleapis.com/ajax/libs/jquery
/3.3.1/jquery.min.js">
16 </script>
17 <script type="text/javascript">
18 $(document).ready(function(){
19
20 $(document).ready(function(){
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
1.3. ADD SIMPLE ACTIONS WHEN PAGE IS LOAD 11
21 $("#tiger_img").mouseover(function()
{
22 $("div").animate({
23 width: "55%",
24 opacity: 0.7,
25 fontSize: "2em",
26 }, 1500);
27 });
28
29 $("#tiger_img").mouseout(function(){
30 $("div").animate({
31 fontSize: "1em",
32 }, 300);
33 });
34
35
36 });
37
38 });
39 </script>
40
41
42 </body>
43 </html>
Code Explained
As we can see during animate operation the browser create an animationbetween two styles
width: "55%",
opacity: 0.7,
fontSize: "2em",
and
fontSize: "1em",
This animation requires change of width, size of the font and opacity.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
12 CHAPTER 1. INTRODUCTION TO JQUERY
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
Chapter 2
AJAX queries using jQuery
Now let us work on AJAX requests using jQuery. The AJAX is an abbreviationfor Asynchronous Javascript And Xml. This technology allows to send (andreceive) information from external sources via asynchronous queries. Usuallythe data send back and forth is in JSON (JavaScript Object Notation) form.In most of the situations webpages using javascript operations send queries toso called REST services.
2.1 RESTful services
Nowadays most of internet services provide so called REST services. This typeof services allow us to invoke basic CRUD operations (Create, Read, Update,Delete). REST API usually allows 4 basic types of http queries GET, POST,PUT and DELETE on so called resources. These operations are usually con-nected with operations on the resources identi�ed by url. For example GET is aRead or show the resource, POST and PUT are Create or Update the resource,meaning of DELETE is obvious. There is no canonical way for distinction oftwo operations POST and PUT (i.e. every API developer de�nes when POSTor PUT should be used). I suggest to use POST as Create and PUT as Update.
2.1.1 Service implementation
Usually to build a REST client one needs a REST API - service that providessome set of REST operations. The server part can be created in most of servertechnologies starting with PHP, python, Java, ASP.Net, etc. In this tutorial wewill use very simple API created in PHP that can receive and send simple datathat contains user scores in a game.
Here we have sample documentation of our test API service:
13
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
14 CHAPTER 2. AJAX QUERIES USING JQUERY
Get selected record
URL http://geniusgamedev.eu/cordova/rest_api/rest_
srv/:id or http://geniusgamedev.eu/cordova/rest_
api/rest.php?id=:id
Method GETParameters id - id of the recordRequest Data NoneResponse Data record object:
{"data":{ "id":2, "name":"Helena", "score":128 } }
Get all records
URL http://geniusgamedev.eu/cordova/rest_api/rest_
srv or http://geniusgamedev.eu/cordova/rest_api/
rest.php
Method GETParameters NoneRequest Data NoneResponse Data record object:
{"data":{"1":{"id":1,"name":"Alan","score":35},"2":{"id":2,"name":"Helena","score":128},"3":{"id":3,"name":"Alex","score":162}}
Add a new record
URL http://geniusgamedev.eu/cordova/rest_api/rest_
srv or http://geniusgamedev.eu/cordova/rest_api/
rest.php
Method POSTParameters NoneRequest Data new record object
{ "data": { "id": 1, "name": "Jane", "score": 332 } }Response Data record object:
{"data":{ "id":12, "name":"Jane", "score":332 } }the value id is a new value created by the service
Update a record
URL http://geniusgamedev.eu/cordova/rest_api/rest_
srv/:id or http://geniusgamedev.eu/cordova/rest_
api/rest.php?id=:id
Method PUTParameters id - id of the record to updateRequest Data new record object
{ "data": { "id": 1, "name": "Jane", "score": 332 } }Response Data record object:
{"data":{ "id":3, "name":"Jane", "score":332 } }the value id is an id of updated record
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
2.1. RESTFUL SERVICES 15
Delete selected record
URL http://geniusgamedev.eu/cordova/rest_api/rest_
srv/:id or http://geniusgamedev.eu/cordova/rest_
api/rest.php?id=:id
Method DELETEParameters NoneRequest Data NoneResponse Data record object:
{"data":{"1":{"id":1,"name":"Alan","score":35},"3":{"id":3,"name":"Alex","score":162}}the rest of records after erasing the requested element
In order to test �rst two of presented operations we can open in the browserone of these two addresses: http://geniusgamedev.eu/cordova/rest_api/
rest_srv http://geniusgamedev.eu/cordova/rest_api/rest_srv/2. In or-der to test POST, PUT and DELETE we need either use soluctions like Rest-Client browser plugin (like Advanced REST client for Chrome) or write a specialhtml/js code.
2.1.2 Prepare page for our rest client
At �rst let us create base for our web rest client.
1 <html>
2 <head>
3 </head>
4 <body>
5 <table id="result_tbl">
6 <tr><th>Id</th><th>Name</th><th>Score</th></tr>
7 </table>
8 <hr>
9 <p>
10 <button id="getOne_btn" >Get One Record</button>
11 <input type="text" id="rid" maxlength="3" size="3"><br>
12 <button id="getAll_btn" >Get All Records</button><br>
13 <hr><hr>
14 <p>
15 <div >
16 <table>
17 <tr><td>Id:</td><td><input type="text" id="nid"></td></tr>
18 <tr><td>Name: </td><td><input type="text" id="name"></td></tr>
19 <tr><td>Score: </td><td><input type="text" id="score"></td></tr>
20 </table>
21 <button id="post_btn" >Insert New Record</button>
22 <button id="update_btn" >Update Old Record</button>
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
16 CHAPTER 2. AJAX QUERIES USING JQUERY
23 </div>
24
25
26 <script type="text/javascript"
27 src="http://ajax.googleapis.com/ajax/libs/jquery
/3.3.1/jquery.min.js">
28 </script>
29 <script type="text/javascript" src="code1.js">
30 </script>
31 </body>
32 </html>
and starting js �le
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 $(document).ready(function(){
3
4 $("#getOne_btn").click(function(){
5 getOneRecord();
6 });
7
8 $("#getAll_btn").click(function(){
9 getAllRecords();
10 });
11
12 $("#post_btn").click(function(){
13 postRecord();
14 });
15
16 $("#update_btn").click(function(){
17 putRecord();
18 });
19 });
20
21 function getOneRecord(){
22 // TODO
23 }
24
25 function getAllRecords(){
26 // TODO
27 }
28
29 function postRecord(){
30 // TODO
31 }
32
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
2.1. RESTFUL SERVICES 17
33 function putRecord(){
34 // TODO
35 }
36
37 function deleteRecord(){
38 //TODO
39 }
Code Explained
As we can see in html �le we have a <table id="result_tbl"> whereresults obtained from service will be placed. Additionally, we have ap-propriate buttons for GET, POST and PUT operations. Now we justneed to �ll the methods getOneRecord(), getAllRecords(), postRecord(),putRecord(), deleteRecord().
Firs let us create a simple get query and show the result in alert window:
function getOneRecord(){
record_id = 1;
if ($('#rid').val()) {
record_id = $('#rid').val();
}
$.ajax({
method : "GET",
dataType: 'json',
url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/"+
record_id,
cache: false
})
.done(function (resp) {
alert(JSON.stringify(resp));
})
.fail(function (msg){
alert(JSON.stringify(msg));
});
}
When this code is inserted into code1.js and the code1.html is run in thebrowser, we observe that after clicking on the button "getOne_btn" in thereturn an alert window with the expected json appears. Changing the value ininput �eld "rid" we change what record will be obtained from the server.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
18 CHAPTER 2. AJAX QUERIES USING JQUERY
Code Explained
In the code w see an operation $.ajax - this is a shortcut for an AJAXquery to the server. This operation has an event "done" that is �redwhen server respond without errors and "fail" whenever error occurs.Any js object can be turned into a json string using JSON.stringify().Additionally we see that we are not interested in all properties of responseobject but only �eld data inside this object.
Now as we know how to obtain an information from server we should workhow to add this obtained record into table with results. For that we declare anew function add_record_to_table(record).
function getOneRecord(){
record_id = 1;
if ($('#rid').val()) {
record_id = $('#rid').val();
}
$.ajax({
method : "GET",
dataType: 'json',
url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/"+
record_id,
cache: false
})
.done(function (response) {
add_record_to_table(response.data);
})
.fail(function (msg){
alert(JSON.stringify(msg));
});
}
Now we have to create function add_record_to_table(). In that moment we
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
2.1. RESTFUL SERVICES 19
should also think how we include into our design an operation to delete elements.It will be very nice if in every row of our table we will have a DELETE buttonthat will designate record to erasure.
function add_record_to_table(data){
var table = $("#result_tbl");
var new_row = $("<tr/>");
var cell = $("<td/>");
cell.html(data.id);
cell.appendTo(new_row);
cell = $("<td/>");
cell.html(data.name);
cell.appendTo(new_row);
cell = $("<td/>");
cell.html(data.score);
cell.appendTo(new_row);
cell = $("<td/>");
var btn = $("<button/>");
btn.html("DELETE");
btn.appendTo(cell);
cell.appendTo(new_row);
new_row.appendTo(table);
btn.click(function (){
deleteRecord(data.id, new_row);
});
}
Code Explained
In order to add a new row in our table we create a new_row object anda cell for every parameter: 'id', 'name', 'score' separately, and a cell fordelete button. We append each new cell to a new_row object. Afterthat, we append the new_row object to existing table and bind a newanonymous function to created delete button. During erasure we willneed id of a record to delete from server and the row to get rid o�.
The method deleteRecord can have the form:
function deleteRecord(record_id, row_to_delete){
$.ajax({
method : "DELETE",
dataType: 'json',
url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/"+
record_id,
cache: false
})
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
20 CHAPTER 2. AJAX QUERIES USING JQUERY
.done(function (response) {
row_to_delete.remove();
})
.fail(function (msg){
alert(JSON.stringify(msg));
});
}
Code Explained
As we can see jQuery GET and DELETE operations have very similarform. The most important di�erence is the �eld 'method'. Additionally,if we want to remove element from our web page it is enough to invokemethod .remove() on selected element.
We already know how to obtain one element via GET operation, the actionto get All of them in one query is very straight forward:
function getAllRecords(){
$.ajax({
method : "GET",
dataType: 'json',
url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/",
cache: false
})
.done(function (response) {
var data = response.data;
for (let index in data){
add_record_to_table(data[index]);
}
})
.fail(function (msg){
alert(JSON.stringify(msg));
});
}
We are left only with two types of queries "POST" and "PUT", let us startwith the �rst one.
function postRecord(){
var new_element = {};
new_element.id = $("#nid").val();
new_element.name = $("#name").val();
new_element.score = $("#score").val();
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
2.1. RESTFUL SERVICES 21
var data_to_send ={};
data_to_send.data = new_element;
$.ajax({
method : "POST",
dataType: 'json',
data: JSON.stringify(data_to_send),
url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/",
cache: false
})
.done(function (response) {
add_record_to_table(response.data);
})
.fail(function (msg){
alert(JSON.stringify(msg));
});
}
Code Explained
In the code above at the beginning we have to obtain elements from theform inputs. After that we send the data to server and add a new rowfrom record obtained back. The only new element in this code is setting'data' �eld of ajax query.
The PUT ajax query is very similar to the ones we have already created.And the last piece of the code is an easy extension from previous elements. The�nal version of js �le have the form:
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 $(document).ready(function(){
3
4 $("#getOne_btn").click(function(){
5 getOneRecord();
6 });
7
8 $("#getAll_btn").click(function(){
9 getAllRecords();
10 });
11
12 $("#post_btn").click(function(){
13 postRecord();
14 });
15
16 $("#update_btn").click(function(){
17 putRecord();
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
22 CHAPTER 2. AJAX QUERIES USING JQUERY
18 });
19 });
20
21 function getOneRecord(){
22 record_id = 1;
23 if ($('#rid').val()) {
24 record_id = $('#rid').val();
25 }
26 $.ajax({
27 method : "GET",
28 dataType: 'json',
29 url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/"+
record_id,
30 cache: false
31 })
32 .done(function (response) {
33 add_record_to_table(response.data);
34 })
35 .fail(function (msg){
36 alert(JSON.stringify(msg));
37 });
38 }
39
40 function getAllRecords(){
41 $.ajax({
42 method : "GET",
43 dataType: 'json',
44 url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/",
45 cache: false
46 })
47 .done(function (response) {
48 var data = response.data;
49 for (let index in data){
50 add_record_to_table(data[index]);
51 }
52
53 //add_record_to_table(response.data);
54 })
55 .fail(function (msg){
56 alert(JSON.stringify(msg));
57 });
58 }
59
60 function postRecord(){
61 var new_element = {};
62 new_element.id = $("#nid").val();
63 new_element.name = $("#name").val();
64 new_element.score = $("#score").val();
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
2.1. RESTFUL SERVICES 23
65 var data_to_send ={};
66 data_to_send.data = new_element;
67 $.ajax({
68 method : "POST",
69 dataType: 'json',
70 data: JSON.stringify(data_to_send),
71 url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/",
72 cache: false
73 })
74 .done(function (response) {
75 add_record_to_table(response.data);
76 })
77 .fail(function (msg){
78 alert(JSON.stringify(msg));
79 });
80 }
81
82 function putRecord(){
83 var new_element = {};
84 new_element.id = $("#nid").val();
85 new_element.name = $("#name").val();
86 new_element.score = $("#score").val();
87 var data_to_send ={};
88 data_to_send.data = new_element;
89 $.ajax({
90 method : "PUT",
91 dataType: 'json',
92 data: JSON.stringify(data_to_send),
93 url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/"+
new_element.id,
94 cache: false
95 })
96 .done(function (response) {
97 add_record_to_table(response.data);
98 })
99 .fail(function (msg){
100 alert(JSON.stringify(msg));
101 });
102 }
103
104 function deleteRecord(record_id, row_to_delete){
105 $.ajax({
106 method : "DELETE",
107 dataType: 'json',
108 url: "http://geniusgamedev.eu/cordova/rest_api/rest_srv/"+
record_id,
109 cache: false
110 })
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
24 CHAPTER 2. AJAX QUERIES USING JQUERY
111 .done(function (response) {
112 row_to_delete.remove();
113 })
114 .fail(function (msg){
115 alert(JSON.stringify(msg));
116 });
117 }
118
119 function add_record_to_table(data){
120 var table = $("#result_tbl");
121 var new_row = $("<tr/>");
122 var cell = $("<td/>");
123 cell.html(data.id);
124 cell.appendTo(new_row);
125 cell = $("<td/>");
126 cell.html(data.name);
127 cell.appendTo(new_row);
128 cell = $("<td/>");
129 cell.html(data.score);
130 cell.appendTo(new_row);
131 cell = $("<td/>");
132 var btn = $("<button/>");
133 btn.html("DELETE");
134 btn.appendTo(cell);
135 cell.appendTo(new_row);
136 new_row.appendTo(table);
137 btn.click(function (){
138 deleteRecord(data.id, new_row);
139 });
140 }
Extercises
Please try to make the web page work more e�ciently, at the momentif you click 'Get All Records' twice in the table we have doubled everyrecord. Additionally when downloading records one by one, the recordsin the table are not sorted by any means and can repeat. When asking ofa non existing record we obtain error - as we do not check if reply fromthe server is not null.
2.1.3 Server code
The php is not a part of this course, however we have used an exemplary RESTserver. In order to run appended scripts one have to install WWW server.This examples were tested on Apache server on linux machine and XAMPPinstallation on Windows 10. The server contains only two �les: score.php -
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
2.1. RESTFUL SERVICES 25
connected to database CRUD operations and rest.php - operates on http RESTrequests.
/* Author: Krzysztof Podlaski, University of Lodz */
<?php
function get_all_results()
{
$db = new SQLite3('db/score.db');
$q = $db->query('SELECT * FROM scores');
$results = array();
while ($el = $q->fetchArray(SQLITE3_ASSOC)){
$results[$el['id']] = $el;
}
$db->close();
return $results;
}
function get_result($id)
{
$db = new SQLite3('db/score.db');
$q = $db->prepare('SELECT * FROM scores WHERE id = :id;');
$q->bindValue(':id', $id);
$row = $q->execute();
$result = $row->fetchArray(SQLITE3_ASSOC);
$q->close();
$db->close();
return $result;
}
function post_result($result)
{
$db = new SQLite3('db/score.db', SQLITE3_OPEN_CREATE |
SQLITE3_OPEN_READWRITE);
$q = $db->prepare('INSERT INTO scores (name, score) VALUES
(:name,:score)');
$q->bindValue(':name', $result->name);
$q->bindValue(':score', $result->score);
$row = $q->execute();
$result->id = $db->lastInsertRowid ();
$q->close();
$db->close();
return $result;
}
function delete_result($id){
$db = new SQLite3('db/score.db', SQLITE3_OPEN_CREATE |
SQLITE3_OPEN_READWRITE);
$q = $db->prepare('DELETE FROM scores WHERE id = :id;');
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
26 CHAPTER 2. AJAX QUERIES USING JQUERY
$q->bindValue(':id', $id);
$row = $q->execute();
$q->close();
$db->close();
return get_all_results();
}
function put_result($result)
{
$test = get_result($result->id);
if ($test){
$db = new SQLite3('db/score.db',
SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
$q = $db->prepare('UPDATE scores SET name= :name ,
score= :score WHERE id=:id');
$q->bindValue(':name', $result->name);
$q->bindValue(':score', $result->score);
$q->bindValue(':id', $result->id);
$row = $q->execute();
}
else {
$db = new SQLite3('db/score.db',
SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
$q = $db->prepare('INSERT INTO scores (name, score
) VALUES (:name,:score)');
$q->bindValue(':name', $result->name);
$q->bindValue(':score', $result->score);
$row = $q->execute();
$result->id = $db->lastInsertRowid ();
}
$q->close();
$db->close();
return $result;
}
/* Author: Krzysztof Podlaski, University of Lodz */
<?php
header("Content-Type:application/json");
require "score.php";
header('Access-Control-Allow-Origin: *');
switch( $_SERVER['REQUEST_METHOD'] ){
case "GET" : get_request(); break;
case "POST" : post_request(); break;
case "PUT" : put_request(); break;
case "DELETE" : delete_request(); break;
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
2.1. RESTFUL SERVICES 27
default: send("def");
}
function get_request(){
if(!empty($_GET['id']))
{
$id=$_GET['id'];
$element = get_result($id);
if(empty($element))
{
send(NULL);
}
else
{
send($element);
}
}
else {
$element = get_all_results();
send($element);
}
}
function post_request(){
$obj = json_decode(file_get_contents("php://input"));
$o =post_result($obj->data);
send($o);
}
function put_request(){
$obj = json_decode(file_get_contents("php://input"));
$o =put_result($obj->data);
send($o);
}
function delete_request(){
if (isset($_GET['id'])){
$list = delete_result($_GET['id']);
send($list);
}
else {
send(null);
}
}
function send($data)
{
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
28 CHAPTER 2. AJAX QUERIES USING JQUERY
header("HTTP/1.1 ".$st);
$resp['data']=$data;
$json = json_encode($resp);
echo $json;
}
Additionally in order to make this examples run we have to add .htaccess�le with the following content:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^rest_srv$ rest.php [NC,L]
RewriteRule ^rest_srv/([0-9a-zA-Z_-]*)$ rest.php?id=$1 [NC,L]
These �les allow simple REST operations using SQLite database http://
geniusgamedev.eu/cordova/rest_api/db/score.db
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
Chapter 3
Apache Cordova
The Apache Cordova is one of the best known technologies to create moderncross-platform mobile applications. This framework allows to create applica-tions using standard HTML5 technology stack in order to build mobile apps forAndroid and iOS mobile devices. It is required from developer to have basiccompetencies in classical technologies like html, css and javascript.
In order to begin work with Cordova environment we have to install Node.jsapplication. This will require administrator privileges on the system. TheNode.js environment contains npm - nodejs packet manager that allow to installnew packages/application into our system. Using npm we can easily installCordova by writing in command line:
$> npm install -g cordova
This -g switch will install cordova for all users, if someone wants to installCordova only for active user have to omit -g parameter.
Now we are ready to create �rst Cordova app, for that let us create a newdirectory somewhere in the system and go into this folder.
$> mkdir CordovaApps
$> cd CordovaApps
Now we should invoke command:
$> cordova create FirstCordovaApp
This will create a folder with prepared template of Cordova application. Theprepared folder contains a few subfolders the most important from the point of
29
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
30 CHAPTER 3. APACHE CORDOVA
view of game developer is www. The rest of subfolders we can treat as internalCordova folder and let them be.
Just for start we can try to run the project, �rst we have to add a platform(i.e. the platform we would like to use as deployment machine). In Cordovawe have many platforms to choose in this course we will use only Browser for�rst level debugging, and Android or iOS for second level debugging and �naldeployment.
$> cd FirstCordovaApp
$> cordova platform add browser
And run the created simple starting project
$> cordova run browser
We should see some information in the terminal and our default browsershould open an address http://localhost:8000/index.html. We will see sim-ple page with Cordova logo and a text: device is ready.
Now let us look what is a content of www folder and what lines in the codemakes the browser to show this screen ??.
We can see speci�c folders for css, img and js �les respectively and one �leindex.html.
When we open index.html �le we will notice the main two parts containedin <head> and <body> tags. At the moment let us ignore <head> part asthere is not too many interesting elements and focus on <body>
<body>
<div class="app">
<h1>Apache Cordova</h1>
<div id="deviceready" class="blink">
<p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p>
</div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
W can notice a few things:
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
31
Code Explained
• The JavaScript �les are added at the end of the <body> part. Thisis connected with the order of loading elements in html, and as .js�les can operate on html elements it is better to �rst build theseelements before start actions programmed in .js �les.
• We should remember that cordova.js has to be always the �rst script
• All elements of the web page are contained in one <divclass="app"> element
• There is one <div> element with id = "deviceready"
• One <p> element has class listening while the other received
Let us now look into js/index.js �le
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 /* based partially on Apache Cordova default app */
3 var app = {
4 initialize: function() {
5 document.addEventListener('deviceready', this.
onDeviceReady.bind(this), false);
6 },
7
8 onDeviceReady: function() {
9 this.receivedEvent('deviceready');
10 },
11
12 receivedEvent: function(id) {
13 var parentElement = document.getElementById(id);
14 var listeningElement = parentElement.querySelector('.
listening');
15 var receivedElement = parentElement.querySelector('.
received');
16
17 listeningElement.setAttribute('style', 'display:none;');
18 receivedElement.setAttribute('style', 'display:block;');
19
20 console.log('Received Event: ' + id);
21 }
22 };
23
24 app.initialize();
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
32 CHAPTER 3. APACHE CORDOVA
Code Explained
How it works: when the page is �nally loaded the Cordova environment�re an event 'deviceready', this implies that bind method onDeviceReadyis invoked. In the result the method receivedEvent is started with ap-propriate value of parameter id. In this method the elements with class"listening" becomes invisible while the ones with "received" becomes vis-ible.Explanation line by line:
line 5: As we can see in the line 3 the method onDeviceReady is bind tothe event 'deviceready', this.onDeviceReady is just an reference tothe method onDeviceReady of the object app, the second this ref-erence in .bind(this), means that when the method will be invokedwhen event 'ondeviceready' is �red the app (this) object will be bindas owner of event handler. The binding of owner of event handleris important, wrong binding can lead to errors in the aplication.
line 9: Run method receivedEvent with parameter id = 'deviceready'
line 13: Find in the html document the element with id = 'deviceready',store it as parentElement
line 14: Find all child nodes of parentElement with class "listening",store them as listeningElement
line 15: Find all child nodes of parentElement with class "received",store them as receivingElement
line 17: Set style of the elements in listeningElement to display:none,i.e. hide if it is visible on the screen
line 18: Set style of the elements in receivedElement to display:block,i.e. show if it is not visible on the screen
line 20: Print a debugging information to JavaScript console.
line 24: The function initialize of the object app is invoked whenjavascript is loaded.
As was mentioned Cordova environment uses a special event 'deviceready'.By default Cordova has more specially de�ned events, some of them works forall platforms some only for Android (see https://cordova.apache.org/docs/en/latest/cordova/events/events.html):
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
33
'deviceready': The deviceready event �res when Cordova is fullyloaded.
'pause': The pause event �res when the native platform putsthe application into the background.
'resume': The resume event �res when the native platform pullsthe application out from the background.
'backbutton': The event �res when the user presses the back button.'menubutton': The event �res when the user presses the menu but-
ton.'searchbutton': The event �res when the user presses the search but-
ton on Android.'volumedownbutton': The event �res when the user presses the volume
down button.'volumeupbutton': The event �res when the user presses the volume up
button.It should be noted that Cordova prefers SPA architecture (Single Page Ap-
plications) i.e. there is only one url address, all changes of the interface are donewithin one javascript �le and using ajax queries.
Remark
If someone do not want to use command line and nodejs environment,there is always a possibility to use Cordova within Visual Studio environ-ment https://visualstudio.microsoft.com/vs/features/cordova/.However this can lead to duplicate android sdk environment as VisualStudio prefers to use everything internal.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
34 CHAPTER 3. APACHE CORDOVA
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
Chapter 4
Testing and deployment
The testing and deployment of Cordova application is not a sophisticated task.At �rst we can always use a browser platform. In this way we can easily testmost of the applications, and using chrome and its developer tools we can testmost functionalities of our application. When the developer thinks about moresophisticated issues he/she can always use ripple simulator. For that we justneed to install the simulator using npm:
$> npm install -g cordova-simulate
and after that we need to run inside the project folder the command:
$> cordova platform add android
$> simulate android
or for iOS simulation
$> cordova platform add ios
$> simulate ios
In that case in the browser opens two pages, one for our application and innext tab the control panel of the emulator, here we can set all properties of thesimulated environment.
35
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
36 CHAPTER 4. TESTING AND DEPLOYMENT
When developer need to test on real device, the application have to be buildfor appropriate platform. For android the commands are:
$> cordova platform add android
$> cordova build android
Remark
This operation require to con�gure android SDK (android studio)
The exemplary output can look like this:
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
37
Android Studio project detected
ANDROID_HOME=D:\Programowanie\Narzedzia\Android\sdk
JAVA_HOME=C:\Program Files\Java\jdk1.8.0
studio
:wrapper
BUILD SUCCESSFUL
Total time: 34.033 secs
Subproject Path: CordovaLib
Subproject Path: app
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons
could not be reused, use --status for details
Download https://maven.google.com/com/android/tools/build/gradle
/3.0.1/gradle-3.0.1.pom
Download https://maven.google.com/com/android/tools/build/gradle-
core/3.0.1/gradle-core-3.0.1.pom
Download https://maven.google.com/com/android/databinding/
compilerCommon/3.0.1/compilerCommon-3.0.1.pom
Download https://maven.google.com/com/android/tools/build/gradle-
api/3.0.1/gradle-api-3.0.1.pom
Download https://maven.google.com/com/android/tools/build/builder
/3.0.1/builder-3.0.1.pom
Download https://maven.google.com/com/android/tools/lint/lint
/26.0.1/lint-26.0.1.pom
Download https://maven.google.com/com/android/tools/external/org-
jetbrains/uast/26.0.1/uast-26.0.1.pom
Download https://maven.google.com/com/android/tools/build/
transform-api/2.0.0-deprecated-use-gradle-api/transform-api
-2.0.0-deprecated-use-gradle-api.pom
Download https://maven.google.com/com/android/tools/sdk-common
/26.0.1/sdk-common-26.0.1.pom
Download https://maven.google.com/com/android/tools/build/manifest
-merger/26.0.1/manifest-merger-26.0.1.pom
Download https://maven.google.com/com/android/tools/build/builder-
test-api/3.0.1/builder-test-api-3.0.1.pom
Download https://maven.google.com/com/android/tools/sdklib/26.0.1/
sdklib-26.0.1.pom
Download https://maven.google.com/com/android/tools/build/builder-
model/3.0.1/builder-model-3.0.1.pom
Download https://maven.google.com/com/android/tools/ddms/ddmlib
/26.0.1/ddmlib-26.0.1.pom
Download https://maven.google.com/com/android/tools/common/26.0.1/
common-26.0.1.pom
Download https://maven.google.com/com/android/tools/analytics-
library/protos/26.0.1/protos-26.0.1.pom
Download https://maven.google.com/com/android/tools/analytics-
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
38 CHAPTER 4. TESTING AND DEPLOYMENT
library/shared/26.0.1/shared-26.0.1.pom
Download https://maven.google.com/com/android/tools/analytics-
library/tracker/26.0.1/tracker-26.0.1.pom
Download https://maven.google.com/com/android/tools/build/apksig
/3.0.1/apksig-3.0.1.pom
Download https://maven.google.com/com/android/tools/lint/lint-
checks/26.0.1/lint-checks-26.0.1.pom
Download https://maven.google.com/com/android/databinding/
baseLibrary/3.0.1/baseLibrary-3.0.1.pom
Download https://maven.google.com/com/android/tools/dvlib/26.0.1/
dvlib-26.0.1.pom
Download https://maven.google.com/com/android/tools/layoutlib/
layoutlib-api/26.0.1/layoutlib-api-26.0.1.pom
Download https://maven.google.com/com/android/tools/repository
/26.0.1/repository-26.0.1.pom
Download https://maven.google.com/com/android/tools/lint/lint-api
/26.0.1/lint-api-26.0.1.pom
Download https://maven.google.com/com/android/tools/external/com-
intellij/intellij-core/26.0.1/intellij-core-26.0.1.pom
Download https://maven.google.com/com/android/tools/annotations
/26.0.1/annotations-26.0.1.pom
Download https://maven.google.com/com/android/tools/build/gradle-
api/3.0.1/gradle-api-3.0.1.jar
Download https://maven.google.com/com/android/tools/lint/lint
/26.0.1/lint-26.0.1.jar
Download https://maven.google.com/com/android/tools/external/org-
jetbrains/uast/26.0.1/uast-26.0.1.jar
Download https://maven.google.com/com/android/tools/build/gradle
/3.0.1/gradle-3.0.1.jar
Download https://maven.google.com/com/android/tools/lint/lint-api
/26.0.1/lint-api-26.0.1.jar
Download https://maven.google.com/com/android/tools/lint/lint-
checks/26.0.1/lint-checks-26.0.1.jar
Download https://maven.google.com/com/android/tools/build/gradle-
core/3.0.1/gradle-core-3.0.1.jar
Download https://maven.google.com/com/android/tools/build/builder
/3.0.1/builder-3.0.1.jar
Download https://maven.google.com/com/android/databinding/
compilerCommon/3.0.1/compilerCommon-3.0.1.jar
Download https://maven.google.com/com/android/tools/build/manifest
-merger/26.0.1/manifest-merger-26.0.1.jar
Download https://maven.google.com/com/android/tools/repository
/26.0.1/repository-26.0.1.jar
Download https://maven.google.com/com/android/tools/sdk-common
/26.0.1/sdk-common-26.0.1.jar
Download https://maven.google.com/com/android/tools/sdklib/26.0.1/
sdklib-26.0.1.jar
Download https://maven.google.com/com/android/tools/build/
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
39
transform-api/2.0.0-deprecated-use-gradle-api/transform-api
-2.0.0-deprecated-use-gradle-api.jar
Download https://maven.google.com/com/android/tools/analytics-
library/tracker/26.0.1/tracker-26.0.1.jar
Download https://maven.google.com/com/android/tools/analytics-
library/shared/26.0.1/shared-26.0.1.jar
Download https://maven.google.com/com/android/tools/analytics-
library/protos/26.0.1/protos-26.0.1.jar
Download https://maven.google.com/com/android/tools/build/builder-
model/3.0.1/builder-model-3.0.1.jar
Download https://maven.google.com/com/android/tools/build/builder-
test-api/3.0.1/builder-test-api-3.0.1.jar
Download https://maven.google.com/com/android/tools/layoutlib/
layoutlib-api/26.0.1/layoutlib-api-26.0.1.jar
Download https://maven.google.com/com/android/tools/ddms/ddmlib
/26.0.1/ddmlib-26.0.1.jar
Download https://maven.google.com/com/android/tools/dvlib/26.0.1/
dvlib-26.0.1.jar
Download https://maven.google.com/com/android/tools/annotations
/26.0.1/annotations-26.0.1.jar
Download https://maven.google.com/com/android/tools/build/apksig
/3.0.1/apksig-3.0.1.jar
Download https://maven.google.com/com/android/tools/common/26.0.1/
common-26.0.1.jar
Download https://maven.google.com/com/android/databinding/
baseLibrary/3.0.1/baseLibrary-3.0.1.jar
Download https://maven.google.com/com/android/tools/external/com-
intellij/intellij-core/26.0.1/intellij-core-26.0.1.jar
publishNonDefault is deprecated and has no effect anymore. All
variants are now published.
Checking the license for package Android SDK Platform 27 in D:\
Programowanie\Narzedzia\Android\sdk\licenses
License for package Android SDK Platform 27 accepted.
Preparing "Install Android SDK Platform 27 (revision: 3)".
"Install Android SDK Platform 27 (revision: 3)" ready.
Installing Android SDK Platform 27 in D:\Programowanie\Narzedzia\
Android\sdk\platforms\android-27
"Install Android SDK Platform 27 (revision: 3)" complete.
"Install Android SDK Platform 27 (revision: 3)" finished.
The Task.leftShift(Closure) method has been deprecated and is
scheduled to be removed in Gradle 5.0. Please use Task.doLast(
Action) instead.
at build_us1j1jtvs47krihhqf05ak23.run(D:\Users\Krzysztof
Podlaski\Documents\Uniwerek\GENIUS\didactic_courses\
Cordova_mobile_games\code\UIExamples\platforms\android
\app\build.gradle:148)
:CordovaLib:preBuild UP-TO-DATE
:CordovaLib:preDebugBuild UP-TO-DATE
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
40 CHAPTER 4. TESTING AND DEPLOYMENT
:CordovaLib:compileDebugAidl
:CordovaLib:compileDebugRenderscript
:CordovaLib:checkDebugManifest
:CordovaLib:generateDebugBuildConfig
:CordovaLib:prepareLintJar
:CordovaLib:generateDebugResValues
:CordovaLib:generateDebugResources
:CordovaLib:packageDebugResources
:CordovaLib:platformAttrExtractor
:CordovaLib:processDebugManifest
:CordovaLib:javaPreCompileDebug
:CordovaLib:processDebugJavaRes NO-SOURCE
:app:preBuild UP-TO-DATE
:app:preDebugBuild
:app:compileDebugAidl
:CordovaLib:packageDebugRenderscript NO-SOURCE
:app:compileDebugRenderscript
:app:checkDebugManifest
:app:generateDebugBuildConfig
:app:prepareLintJar
:app:generateDebugResValues
:app:generateDebugResources
:app:mergeDebugResources
:app:createDebugCompatibleScreenManifests
:app:processDebugManifest
:app:splitsDiscoveryTaskDebug
:app:compileDebugNdk NO-SOURCE
:CordovaLib:mergeDebugShaders
:CordovaLib:compileDebugShaders
:CordovaLib:generateDebugAssets
:CordovaLib:mergeDebugAssets
:app:mergeDebugShaders
:app:compileDebugShaders
:app:generateDebugAssets
:app:mergeDebugAssets
:CordovaLib:compileDebugNdk NO-SOURCE
:CordovaLib:mergeDebugJniLibFolders
:CordovaLib:transformNativeLibsWithMergeJniLibsForDebug
:CordovaLib:transformNativeLibsWithStripDebugSymbolForDebug
:CordovaLib:transformNativeLibsWithIntermediateJniLibsForDebug
:app:mergeDebugJniLibFolders
:app:processDebugJavaRes NO-SOURCE
:app:validateSigningDebug
:CordovaLib:processDebugResources
:CordovaLib:generateDebugSources
:CordovaLib:compileDebugJavaWithJavacNote: Some input files use or
override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
41
:CordovaLib:
transformClassesAndResourcesWithPrepareIntermediateJarsForDebug
:app:processDebugResources
:app:generateDebugSources
:app:javaPreCompileDebug
:app:compileDebugJavaWithJavac
:app:compileDebugSources
:app:transformClassesWithStackFramesFixerForDebug
:app:transformClassesWithDesugarForDebug
:app:transformClassesWithDexBuilderForDebug
:app:transformDexArchiveWithExternalLibsDexMergerForDebug
:app:transformDexArchiveWithDexMergerForDebug
:app:transformNativeLibsWithMergeJniLibsForDebug
:app:transformNativeLibsWithStripDebugSymbolForDebug
:app:transformResourcesWithMergeJavaResForDebug
:app:packageDebug
:app:assembleDebug
:app:cdvBuildDebug
BUILD SUCCESSFUL in 3m 26s
48 actionable tasks: 48 executed
Built the following apk(s):
D:\Users\Krzysztof Podlaski\Documents\Uniwerek\GENIUS\
didactic_courses\Cordova_mobile_games\code\UIExamples\
platforms\android\app\build\outputs\apk\debug\app-
debug.apk
After a rather long output we should see the information that our apk �lewas created:
BUILD SUCCESSFUL in 3m 26s
48 actionable tasks: 48 executed
Built the following apk(s): D:\Users\Krzysztof Podlaski\Documents\
Uniwerek\GENIUS\didactic_courses\Cordova_mobile_games\code\
UIExamples\platforms\android\app\build\outputs\apk\debug\app-
debug.apk
The resulting .apk �le can be moved to android device and run there, or runin any simulator like (SDK simulator, bluestack etc.).
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
42 CHAPTER 4. TESTING AND DEPLOYMENT
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
Chapter 5
Cordova and JavaScript
games
You have already learned about JavaScript games in browser and Cordova envi-ronment. Cordova allows to run html/css and js code on mobile devices. In thismodule we will cover how to use the basic game code from previous moduleswithin Cordova environment. In this module we will take one of Canvas basicJavaScript game and run this inside Cordova. As the starting point we take theMaze Game example. This example contains a few �les: maze_game.html, anda set of js, css and png �les. At the start let's create basic Cordova project (aswas described in previous section). After that combine cordova index.html �lewith maze_game.html. Beginning with <head> section of both �les we jointhem into one code:
<head>
<meta http-equiv="Content-Security-Policy" content="default
-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval';
style-src 'self' 'unsafe-inline'; media-src *; img-src 'self'
data: content:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
<title>GENIUS worked example</title>
<link rel="shortcut icon" type="image/png" href="images/
genius_icon.png"/>
<link href="css/game.css" rel="stylesheet" type="text/css"
/>
</head>
We move all links to javaScript �les to the end of <body> section. Now let
43
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
44 CHAPTER 5. CORDOVA AND JAVASCRIPT GAMES
us integrate both <body> sections.
<body>
<div class="app">
<div id="gameContainer">
<canvas id="gameCanvas" tabindex="1"></canvas>
<p>Use the arrow keys to change the direction that the
skeleton walks.</p>
</div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script src="js/CanvasGame.js" type="text/javascript"></script
>
<script src="js/GameObject.js" type="text/javascript"></script
>
<script src="js/index.js" type="text/javascript"></script>
<script src="js/MazeCanvasGame.js" type="text/javascript"></
script>
<script src="js/StaticImage.js" type="text/javascript"></
script>
<script src="js/Skeleton.js" type="text/javascript"></script>
<script src="js/MazeSkeleton.js" type="text/javascript"></
script>
<script src="js/StaticText.js" type="text/javascript"></script
>
<script src="js/maze_game.js" type="text/javascript"></script>
</body>
We have two js/index.js �les, one from Cordova core, the second from Canvasgame example, these two have to be integrated. As the Canvas game �le is muchmore complicated and already have Cordova in mind, we can just replace theCordova js/index.js �le with the one from Canvas game. We have to copy therest of .js and img �les from browser game version without any changes.
Now we have to decide how we can move the robot. In the original version thekeyboard arrows are used, while on mobile devices this is not acceptable methodof control. The simplest approach would be to add four appropriate buttons tothe game. For that we add four buttons UP, DOWN, LEFT, RIGHT just underthe <canvas>. The �nal .html �le will have the form:
1 <!DOCTYPE html>
2 <html>
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
45
3 <head>
4 <meta http-equiv="Content-Security-Policy" content="
default-src 'self' data: gap: https://ssl.gstatic.com '
unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *;
img-src 'self' data: content:;">
5 <meta name="format-detection" content="telephone=no">
6 <meta name="msapplication-tap-highlight" content="no">
7 <meta name="viewport" content="user-scalable=no, initial-
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
8 <title>GENIUS worked example</title>
9 <link rel="shortcut icon" type="image/png" href="images/
genius_icon.png"/>
10 <link href="css/game.css" rel="stylesheet" type="text/css"
/>
11 </head>
12 <body>
13 <div class="app">
14 <div id="gameContainer">
15 <canvas id="gameCanvas" tabindex="1"
></canvas>
16 <table>
17 <tr>
18 <td></td>
19 <td><button id="up_btn" >&
uarr;</button></td>
20 <td></td>
21 </tr>
22 <tr>
23 <td><button id="left_btn" >&
larr;</button></td>
24 <td><button id="down_btn" >&
darr;</button></td>
25 <td><button id="right_btn" >&
rarr;</button></td>
26 </tr>
27 </table>
28 </div>
29 </div>
30 <script type="text/javascript" src="cordova.js"></
script>
31 <script src="js/CanvasGame.js" type="text/
javascript"></script>
32 <script src="js/GameObject.js" type="text/
javascript"></script>
33 <script src="js/index.js" type="text/javascript">
</script>
34 <script src="js/maze_game.js" type="text/
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
46 CHAPTER 5. CORDOVA AND JAVASCRIPT GAMES
javascript"></script>
35 <script src="js/MazeCanvasGame.js" type="text/
javascript"></script>
36 <script src="js/StaticImage.js" type="text/
javascript"></script>
37 <script src="js/Skeleton.js" type="text/javascript
"></script>
38 <script src="js/MazeSkeleton.js" type="text/
javascript"></script>
39 <script src="js/StaticText.js" type="text/
javascript"></script>
40 </body>
41 </html>
In original Canvas game the code connected with moving the robot wasinside the �le: js/maze_game.js:
/* If they are needed, then include any game-specific mouse and
keyboard listeners */
document.addEventListener('keydown', function (e)
{
if (e.keyCode === 37) // left
{
gameObjects[SKELETON].setDirection(LEFT);
}
else if (e.keyCode === 38) // up
{
gameObjects[SKELETON].setDirection(UP);
}
else if (e.keyCode === 39) // right
{
gameObjects[SKELETON].setDirection(RIGHT);
}
else if (e.keyCode === 40) // down
{
gameObjects[SKELETON].setDirection(DOWN);
}
});
We have to replace this code that uses arrows with the code that use createdbuttons to control the robot movement:
document.getElementById("up_btn").addEventListener('click',
function (e){
gameObjects[SKELETON].setDirection(UP);
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
47
});
document.getElementById("down_btn").addEventListener('click',
function (e){
gameObjects[SKELETON].setDirection(DOWN);
});
document.getElementById("left_btn").addEventListener('click',
function (e){
gameObjects[SKELETON].setDirection(LEFT);
});
document.getElementById("right_btn").addEventListener('click',
function (e){
gameObjects[SKELETON].setDirection(RIGHT);
});
After all this operations we have obtained the Cordova version of chosenCanvas game.
Extercises
The buttons with arrows do not �t to the graphic style of the game, addsome images of arrows and use them for control instead of the buttons.Change the size of the background in order to have arrows above imagegreen background.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
48 CHAPTER 5. CORDOVA AND JAVASCRIPT GAMES
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
Chapter 6
Device capabilities
The Cordova environment allows to create a mobile applications using html5technology stack. However it is obvious that capabilities of the mobile device(smartphone, tablet) are not the same as the browser. In the Cordova all speci�cfunctionalities of the device are solved as plugins to the platform. For examplein order to use camera functionality inside our game we have to add appropriateplugin to our project and then with additional js objects/methods we can controlthe camera build in the device. In this course we will cover how to use: camera,accelerometer/giroscope, gps. The information about actual plugins can befound in Cordova documentation https://cordova.apache.org/plugins/.
6.1 Camera
As was mentioned in order to use a build in camera we have to add appropriateplugin. This plugin add to the cordova environment appropriate objects/meth-ods that allow control of the camera via javascript operations Cordova cameraplugin. In order to add a plugin we have to invoke the following shell commandinside the project folder
$> cordova plugin add cordova-plugin-camera
The camera will be visible as a special js object navigator.camera, this objectwill be initiated just before 'deviceready' event is �red. Suppose, we would likejust to take a picture and show it on the screen of the phone.
Our html �le will be very simple:
1 <!DOCTYPE html>
2 <html>
3 <head>
49
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
50 CHAPTER 6. DEVICE CAPABILITIES
4 <meta http-equiv="Content-Security-Policy"
5 content="default-src 'self' data: gap:
https://ssl.gstatic.com https://ajax.
googleapis.com 'unsafe-eval'; style-src
'self' 'unsafe-inline'; media-src *;
img-src 'self' data: content:;">
6 <meta name="format-detection" content="telephone=no">
7 <meta name="msapplication-tap-highlight" content="no">
8 <meta name="viewport" content="user-scalable=no, initial-
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
9 <link rel="stylesheet" type="text/css" href="css/index.css
">
10 <title>Camera App</title>
11 </head>
12 <body>
13 <div class="app">
14 <h1>Camera in Apache Cordova</h1>
15 <div>
16 <img id="taken_photo">
17 </div>
18 <button id="take_photo_btn" >Take a photo
</button>
19 </div>
20 <script type="text/javascript" src="cordova.js"></script>
21 <script type="text/javascript" src="https://ajax.
googleapis.com/ajax/libs/jquery/3.3.1/jquery.
min.js"></script>
22
23 <script type="text/javascript" src="js/index.js"></script>
24 </body>
25 </html>
The js �le have the form:
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 /* based on basic Apache Cordova app */
3 var app = {
4
5 initialize: function() {
6 document.addEventListener('deviceready', this.
onDeviceReady.bind(this), false);
7 },
8
9 onDeviceReady: function() {
10 $("#take_photo_btn").click( function(){
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
6.1. CAMERA 51
11 camera_options = {
12 destinationType: Camera.
DestinationType.FILE_URI
,
13 quality: 75,
14 sourceType: Camera.
PictureSourceType.
PHOTOLIBRARY,
15 saveToPhotoAlbum: true,
16 popoverOptions: new
CameraPopoverOptions
(300, 300, 100, 100,
Camera.
PopoverArrowDirection.
ARROW_ANY)
17 };
18 navigator.camera.getPicture(app.onSuccess,
app.onFail, camera_options);
19 });
20 },
21
22 onSuccess: function(imageData) {
23 var image = $("#taken_photo")[0];//document.
getElementById("taken_photo");
24 image.src = "data:image/jpeg;base64," + imageData;
25 },
26
27 onFail: function (msg) {
28 console.log("ERRORR");
29 console.log(JSON.stringify(msg));
30 },
31
32 };
33
34 app.initialize();
Code Explained
The js �le needs a little of explanation. The object camera_options (line11) de�nes the properties of the camera, for details see plugin documen-tation. In order to take a photo one has to use method getPicture ofnavigator.camera (line 18) with appropriate callback functions for suc-cess and failure events.In the method onSuccess one can notice the strange value of image.src,this value is just a jpeg image encoded to base64 string representation.(line 24).
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
52 CHAPTER 6. DEVICE CAPABILITIES
6.1.1 QRCode in Cordova
In many of contextual games a player is required to prove his achievementor position in external game context. This operation can be ful�lled via gpscoordinates, or scanning nfc tag, qrcode. As we know how to take a picture, wecan now use camera for scanning QRCode. There are many solutions that canhelp us decode QRCode into text, in this course we will use https://github.com/LazarSoft/jsqrcode. This is a pure javascript library and works even ino�ine mode. In order to use Javascript QRCode scanner we need to download.js �les from repository and include them to our project. For sake of readabilitywe store them in the folder www/js/qrdecoder/ of our Cordova project and addlines below into index.html.
<script type="text/javascript" src="js/qrdecoder/grid.js"></script
>
<script type="text/javascript" src="js/qrdecoder/version.js"></
script>
<script type="text/javascript" src="js/qrdecoder/detector.js"></
script>
<script type="text/javascript" src="js/qrdecoder/formatinf.js"></
script>
<script type="text/javascript" src="js/qrdecoder/errorlevel.js"></
script>
<script type="text/javascript" src="js/qrdecoder/bitmat.js"></
script>
<script type="text/javascript" src="js/qrdecoder/datablock.js"></
script>
<script type="text/javascript" src="js/qrdecoder/bmparser.js"></
script>
<script type="text/javascript" src="js/qrdecoder/datamask.js"></
script>
<script type="text/javascript" src="js/qrdecoder/rsdecoder.js"></
script>
<script type="text/javascript" src="js/qrdecoder/gf256poly.js"></
script>
<script type="text/javascript" src="js/qrdecoder/gf256.js"></
script>
<script type="text/javascript" src="js/qrdecoder/decoder.js"></
script>
<script type="text/javascript" src="js/qrdecoder/qrcode.js"></
script>
<script type="text/javascript" src="js/qrdecoder/findpat.js"></
script>
<script type="text/javascript" src="js/qrdecoder/alignpat.js"></
script>
<script type="text/javascript" src="js/qrdecoder/databr.js"></
script>
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
6.2. ACCELEROMETER 53
After that we change onSuccess method in our index.js into:
onSuccess: function(imageData) {
var image = $("#taken_photo")[0];//document.
getElementById("taken_photo");
image.src = "data:image/jpeg;base64," + imageData;
qrcode.callback = function(decodedData) {
console.log(JSON.stringify(decodedData));
}
var _qr1 = qrcode.decode(image.src);
}
Code Explained
In the code we have only two new elements:
• start decode operation qrcode.decode(image.src)
• de�nition of an anonymous callback function what to do withdecoding result, in the example we just print the response onjavascript console. As usual this method will be invoked when de-coding process ends.
Remark
For testing purposes we need to create a QRCode with some information.There are many free solutions in the Internet, you need to �nd one usingpreferred search engine.
6.2 Accelerometer
In some of the games developers prefer to use accelerometer or gyroscope ascontrol mechanism. In previous versions of Cordova one needs to install device-motion plugin. However, lately the general Device Motion and Orientation APIhas been implemented in all of the most important mobile platform and there-fore, the Cordova plugin is depreciated. As is suggested we will use mentionedAPI.
As usual we will start from basic Cordova project and add accelerometercapabilities. In simple example, we will place the ball in the center of the screenand move it using Motion/Orientration capability.
The Motion and Orientation API provides two types of event deviceorien-tation and devicemotion, which of these two are available depend on the real
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
54 CHAPTER 6. DEVICE CAPABILITIES
device. In this example we will use only orientation - as this can be emulatein developer tools of chrome browser https://developers.google.com/web/tools/chrome-devtools/device-mode/#orientation. The starting .html �lewill have the form:
1 <!DOCTYPE html>
2 <!--
3 Licensed to the Apache Software Foundation (ASF) under one
4 or more contributor license agreements. See the NOTICE file
5 distributed with this work for additional information
6 regarding copyright ownership. The ASF licenses this file
7 to you under the Apache License, Version 2.0 (the
8 "License"); you may not use this file except in compliance
9 with the License. You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing,
14 software distributed under the License is distributed on an
15 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 KIND, either express or implied. See the License for the
17 specific language governing permissions and limitations
18 under the License.
19 -->
20 <html>
21 <head>
22 <!--
23 Customize this policy to fit your own app's needs. For
more guidance, see:
24 https://github.com/apache/cordova-plugin-whitelist/
blob/master/README.md#content-security-policy
25 Some notes:
26 * gap: is required only on iOS (when using UIWebView)
and is needed for JS->native communication
27 * https://ssl.gstatic.com is required only on Android
and is needed for TalkBack to function properly
28 * Disables use of inline scripts in order to mitigate
risk of XSS vulnerabilities. To change this:
29 * Enable inline JS: add 'unsafe-inline' to default
-src
30 -->
31 <meta http-equiv="Content-Security-Policy" content="
default-src 'self' data: gap: https://ssl.gstatic.com
'unsafe-eval'; style-src 'self' 'unsafe-inline';
media-src *; img-src 'self' data: content:;">
32 <meta name="format-detection" content="telephone=no">
33 <meta name="msapplication-tap-highlight" content="no">
34 <meta name="viewport" content="user-scalable=no, initial-
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
6.2. ACCELEROMETER 55
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
35 <title>Accelerometer App</title>
36 </head>
37 <body>
38 <div class="app">
39 <div id="ball_container" width="300" height="300">
40 <img id="ball_img" src="img/ball.png
" width="30" height="30" style="
position:absolute; left:10; top
:10">
41 </div>
42 </div>
43 <script type="text/javascript" src="cordova.js"></script>
44 <script type="text/javascript" src="js/Ball.js"></script>
45 <script type="text/javascript" src="js/index.js"></script>
46 </body>
47 </html>
Code Explained
The html �le is simple, the one extra element is the <imgid="ball_img"> object for our moving ball. JavaScript code is dividedinto two parts, Ball.js, and index.js.
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 class Ball{
3
4 constructor (x,y, vx, vy, maxX, maxY, ball_img){
5 this.vx=vx;
6 this.vy=vy;
7 this.x=x;
8 this.y=y;
9 this.maxX = maxX;
10 this.maxY = maxY;
11 this.ball_img=ball_img;
12 }
13
14 startAnimation(){
15 setInterval(this.animation.bind(this), 10);
16 }
17
18 animation(){
19 this.x+=this.vx;
20 this.y+=this.vy;
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
56 CHAPTER 6. DEVICE CAPABILITIES
21 this.ball_img.style.left=this.x+"px";
22 this.ball_img.style.top=this.y+"px";
23 if (this.x<0 || this.x>this.maxX) this.vx*=-1;
24 if (this.y<0 || this.y>this.maxY) this.vy*=-1;
25 }
26 }
Code Explained
The class Ball contains logic of moving ball. The ball needs positioncoordinates (x,y) and velocity vector (vx,vy). As the ball will move insideclosed area the values of maxX and maxY are needed. Additionally, themovement of this virtual ball need to be connected to the movement ofball image on the screen. The ball_img represents DOM img object. Allthis information will be provided via constructor (lines 4-12). MethodstartAnimation will start in�nite loop of our scene animation. During ananimation frame we update position using velocity (lines 19, 20), set thenew position to bal_img object (lines 21, 22) and bouncing the ball fromimaginary borders (lines 23, 24).
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 /* based on basic Apache Cordova app */
3 var app = {
4
5 initialize: function() {
6 document.addEventListener('deviceready', this.
onDeviceReady.bind(this), false);
7 },
8
9 onDeviceReady: function() {
10 /* Start motion api */
11 window.addEventListener("deviceorientation", this.
handleOrientation.bind(this), true)
12 window.addEventListener("devicemotion", this.
handleMotion.bind(this), true);
13 var ball_img = document.getElementById("ball_img")
;
14 this.ball = new Ball(30,30,1,1, 300, 300, ball_img
);
15 this.ball.startAnimation();
16 },
17
18 handleOrientation: function (event) {
19 console.log("Alpha :"+ event.alpha);
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
6.3. GEOLOCATION 57
20 console.log("Beta: "+event.beta);
21 console.log("Gamma:"+event.gamma);
22 console.log("Absolute:"+event.absolute);
23 this.ball.vx = event.alpha/5+1;
24 this.ball.vy = -event.gamma/5;
25 },
26
27 handleMotion: function (event) {
28 console.log("Interval :"+ event.interval);
29 console.log("Rotation Rate: "+event.rotationRate);
30 console.log("Acceleration:"+event.acceleration);
31 console.log("Acceleration with G:"+event.
accelerationIncludingGravity);
32 },
33 };
34
35 app.initialize();
Code Explained
In the main .js �le we initiate listeners for Orientation and Motion events(lines 11 and 12) and create Ball object with appropriate parameter val-ues. At the end of onDeviceReady method we start ball animation (line15).Whenever the device change orientation the handleOrientation method isinvoked, inside we change ball velocity vx, vy according to the orientationparameters alpha, beta (lines 23, 24). If the device support Motion APIthe method handleMotion will be invoked with device movement.
Extercises
Please use the example maze game created in 5 and add the orientationstyle of control to the game.
6.3 Geolocation
As usual in order to have geolocation functionality we have to add appropriateplugin by running in the project folder the shell command:
$> cordova plugin add cordova-plugin-geolocation
This plugin adds to our Cordova environment three methods: getCurrent-Position, watchPosition, clearWatch of the navigator.geolocation object (see
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
58 CHAPTER 6. DEVICE CAPABILITIES
documentation). The �rst method is used for one time check of the location ofthe device. The second one can be use to start semi-continuous watching, thewatching invoke an event whenever the position changes. The last method stopsthe watching activity.
As usual let us start with basic Cordova project with simple html:
1 <!DOCTYPE html>
2 <!--
3 Licensed to the Apache Software Foundation (ASF) under one
4 or more contributor license agreements. See the NOTICE file
5 distributed with this work for additional information
6 regarding copyright ownership. The ASF licenses this file
7 to you under the Apache License, Version 2.0 (the
8 "License"); you may not use this file except in compliance
9 with the License. You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing,
14 software distributed under the License is distributed on an
15 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 KIND, either express or implied. See the License for the
17 specific language governing permissions and limitations
18 under the License.
19 -->
20 <html>
21 <head>
22 <!--
23 Customize this policy to fit your own app's needs. For
more guidance, see:
24 https://github.com/apache/cordova-plugin-whitelist/
blob/master/README.md#content-security-policy
25 Some notes:
26 * gap: is required only on iOS (when using UIWebView)
and is needed for JS->native communication
27 * https://ssl.gstatic.com is required only on Android
and is needed for TalkBack to function properly
28 * Disables use of inline scripts in order to mitigate
risk of XSS vulnerabilities. To change this:
29 * Enable inline JS: add 'unsafe-inline' to default
-src
30 -->
31 <meta http-equiv="Content-Security-Policy" content="
default-src 'self' data: gap: https://ssl.gstatic.com
https://ajax.googleapis.com 'unsafe-eval'; style-src
'self' 'unsafe-inline'; media-src *; img-src 'self'
data: content:;">
32 <meta name="format-detection" content="telephone=no">
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
6.3. GEOLOCATION 59
33 <meta name="msapplication-tap-highlight" content="no">
34 <meta name="viewport" content="user-scalable=no, initial-
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
35 <link rel="stylesheet" type="text/css" href="css/index.css
">
36 <title>Geo App</title>
37 </head>
38 <body>
39 <div class="app">
40 <table>
41 <tr><td>Latitude:</td><td><input
type="text" id="lat_in"></td></
tr>
42 <tr><td>Longitude:</td><td><input
type="text" id="lon_in"></td></
tr>
43 </table>
44 </div>
45 <script type="text/javascript" src="cordova.js"></script>
46 <script type="text/javascript" src="https://ajax.
googleapis.com/ajax/libs/jquery/3.3.1/jquery.
min.js"></script>
47 <script type="text/javascript" src="js/index.js"></script>
48 </body>
49 </html>
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 /* based on basic Apache Cordova app */
3
4 var app = {
5 initialize: function() {
6 document.addEventListener('deviceready', this.
onDeviceReady.bind(this), false);
7 },
8
9 onDeviceReady: function() {
10 //Obtain the actual location
11 var location_options = { enableHighAccuracy: true
};
12 console.log("Start");
13 navigator.geolocation.getCurrentPosition (this.
onPositionSuccess, this.onPositionError,
location_options);
14 setTimeout(function(){
15 console.log("Start watching");
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
60 CHAPTER 6. DEVICE CAPABILITIES
16 app.watch = navigator.geolocation.
watchPosition(app.onPositionSuccess,
app.onPositionError, location_options);
17 }, 1000); //after 1 second
18 setTimeout(function(){
19 console.log("Stop watching");
20 navigator.geolocation.clearWatch(app.watch)
;
21 }, 60000); //after 60 seconds
22 },
23
24 onPositionSuccess : function (position) {
25 _lat = position.coords.latitude;
26 _lon = position.coords.longitude;
27 console.log(_lat+" "+_lon);
28 $("#lat_in").val(_lat);
29 $("#lon_in").val(_lon);
30 },
31
32 onPositionError: function(msg){
33 console.log(JSON.stringify(msg));
34 }
35
36 };
37
38 app.initialize();
Code Explained
The .html is very simple and no explanations are needed. In the .js �lewe should notice the object that contains options for position detectionlocation_options. In line 13 the one time location query is invoked, laterin lines 15-17 the position watching is starting (with 1 second timeout).Watching activity should stop after 60 seconds (lines 18-22). Wheneverthe location is obtained onPositionSuccess method is invoked. Here weobtain position and show it to the user.
Extercises
In the Cordova documentation of Geolocation reader can �nd a few ex-amples of its usage (Weather forecast, Google Maps with location, �ndpoi or pictures nearby. Please try them yourself.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
Chapter 7
Mobile Game Interface
The mobile game interface is one of the most important elements of mobile gamedesign. The user uses the interface to interact with the game, to control his/heravatar. The design of the interface alow user to �awlessly operate and use thegame or in the worst case will make the player angry and in result abandon ourgame. Therefore, the interface should be design with great care. At �rst weshould think:
• who is our player, why he/she plays the game?
• how and maybe where he/he will play the game?
• what approach will be comfortable to the user?
• what type/size of device is used to play?
Gamer Stance First take into account a person that plays the games withappropriate care. Then the player will probably take the "Gamer Stance".
The player keep the phone in landscape position with two thumbs near thebottom corners of the screen. We can easily see that a small part of the screen is
61
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
62 CHAPTER 7. MOBILE GAME INTERFACE
easily accessible (Red area), a little bigger area that can be stil accessed (Orangearea) and the rest of the screen very hard for interaction.
Casual or tablet player The player keeps the device in one hand and usesthe secund one to operate on the screen. The hole area of the screen is accessible,but the user cannot touch instantly two distant places.
Subway player The player plays for short time usually in rush. Keeps thephone in one hand, probably in portrait orientation, controlling it with thumbof this hand. This type of player has minimal reach and the control area is verysmall, additionally multitouch control method is unacceptable.
This three types of players demand totally di�erent interface for the game.There is no solution that will �t to any two types of the player. During thedesign stage, the developing team has to decide what type of player they expect.Moreover when we think about contextual games it is possible that the externalcontext will prefer one of these types of interaction for example if player hasto run/move with the phone, we have a subway type player, no sophisticatedinteraction is possible during movement.
Let us now cover some basic methods of interaction and their implementationin Cordova.
7.1 Tap, sigle touch
This method of interaction have been used in this course all the time. All typesof buttons, clickable images represents this simplest control method. Howeverfor real fast interaction it is suggested to use touch events instead of click events.The reason is that mobile devices have to spend some time (around 300 mil-liseconds) to translate native touch event to a click one.
7.2 Drag, continuous touch
The mobile devices natively support touch events: touchstart, touchend, touch-cancel, touchmove. As for default touch support multitouch, it tracks more thanone �nger separately. The simple example below presents how touches can beused for simple drawing application.
As usual starting with html �le:
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="Content-Security-Policy" content="
default-src 'self' data: gap: https://ssl.gstatic.com '
unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *;
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
7.2. DRAG, CONTINUOUS TOUCH 63
img-src 'self' data: content:;">
5 <meta name="format-detection" content="telephone=no">
6 <meta name="msapplication-tap-highlight" content="no">
7 <meta name="viewport" content="user-scalable=no, initial-
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
8 <title>Touch and Drag</title>
9 </head>
10 <body>
11 <div class="app">
12 <canvas id="drawing_canva" width="300" height="300"
style="border:1px solid blue;">
13 </canvas>
14 <div >
15 <img id="ball_img" src="img/ball.png
" width="40" />
16 <div>
17 </div>
18 <script type="text/javascript" src="cordova.js"></script>
19 <script type="text/javascript" src="js/index.js"></script>
20 </body>
21 </html>
Now we will build a index.js �le. First we have to register event listeners forall touch events.
var app = {
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady
.bind(this), false);
},
onDeviceReady: function() {
var canva = document.getElementById("drawing_canva");
canva.addEventListener("touchstart", this.
onTouchStart.bind(this), false);
canva.addEventListener("touchend", this.onTouchEnd.
bind(this), false);
canva.addEventListener("touchmove", this.onTouchMove
.bind(this), false);
this.lastTouch = {x:null, y:null};
this.colors = ['#aaaaaa', '#ffaaff', '#01ffe3'];
this.color = 0;
},
We de�ne three �elds that will be used later:
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
64 CHAPTER 7. MOBILE GAME INTERFACE
lastTouch - represents coordinates of last registered touch, at this stage x, andy are null as no touch have been initiated yet,
colors - table of colors that will be used, the idea is to change color with thestart of every new touch,
color - the index of actual color to be used when drawing.
Now the operations connected to speci�c touch events. Let us start withtouchstart:
onTouchStart: function(event){
event.preventDefault();
console.log("TouchStart");
var touches = event.changedTouches;
this.color++;
if (this.color== this.colors.length) this.color=0;
this.drawBall(touches[0].pageX, touches[0].pageY);
},
Code Explained
The �rst line event.preventDefault is a very important one, we do notwant the device to process the event further, this could for example resultin �ring a click event. Next, we obtain the information about all touchesvia event.changedTouches, every touch have the properties pageX, pageYthat contains coordinates of touched place.
The drawing of a ball uses a known canvas drawing:
drawBall: function(x, y){
console.log("drawing: ["+x+","+y+"]");
this.lastTouch.x=x;
this.lastTouch.y=y;
var el = document.getElementById("drawing_canva");
var ctx = el.getContext("2d");
ctx.beginPath();
ctx.arc(x, y, 4, 0, 2 * Math.PI, false);
ctx.fillStyle = this.colors[this.color];
ctx.fill();
},
Code Explained
Here we record the new x, y as the lastTouch coordinates and draw acircle on this position.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
7.2. DRAG, CONTINUOUS TOUCH 65
As we would like to continue drawing while the touch event continues, wedo that in touchmove event handler:
onTouchMove: function(event){
event.preventDefault();
console.log("TouchMove");
var touches = event.changedTouches;
this.moveBall(touches[0].pageX, touches[0].pageY);
},
moveBall: function(x, y){
console.log("drawing: ["+x+","+y+"]");
var el = document.getElementById("drawing_canva");
var ctx = el.getContext("2d");
ctx.beginPath();
ctx.moveTo(this.lastTouch.x, this.lastTouch.y);
ctx.lineTo(x, y);
ctx.lineWidth = 4;
ctx.strokeStyle = this.colors[this.color];
ctx.stroke();
this.lastTouch.x=x;
this.lastTouch.y=y;
}
Code Explained
The drawing when �nger is moving, is done using ctx.moveTo andctx.lineTo methods, after the end of operation we reset the lastTouchcoordinates.
Extercises
If we comment the last two lines, the drawing method will be totallydi�erent, however, this can be a suggestion how to implement virtualjoystick controller.
Running this exiting code we will see that when touches start we draw acircle, after that the lines that follow the movement are drawn. The �nal resultis not symmetric as we can easily see the ball at the beginning of the line andnothing at its end. To repair this we add appropriate touchend handler:
onTouchEnd: function(event){
event.preventDefault();
console.log("TouchEnd");
var touches = event.changedTouches;
this.drawBall(touches[0].pageX, touches[0].pageY);
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
66 CHAPTER 7. MOBILE GAME INTERFACE
},
In the presented example we have skipped touchcancel event as not applica-ble.
7.3 Virtual Joy
One of the nicest control method is virtual joystick. We can distinguish twobasic vjoy concepts: stationary vjoy - always on the same place, and dynamicalone - appears with touchstart. At �rst let us cover the stationary one. In thisexample we will use the ball code from accelerator case.
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="Content-Security-Policy" content="
default-src 'self' data: gap: https://ssl.gstatic.com '
unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *;
img-src 'self' data: content:;">
5 <meta name="format-detection" content="telephone=no">
6 <meta name="msapplication-tap-highlight" content="no">
7 <meta name="viewport" content="user-scalable=no, initial-
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
8 <title>Stationary VJoy App</title>
9 </head>
10 <body>
11 <div class="app">
12 <div id="ball_container" width="300" height="300" >
13 <img id="ball_img" src="img/ball.png
" width="30" height="30" style="
position:absolute; left:10; top
:10">
14 </div>
15 <canvas id="vjoy_canvas" style="position:
absolute; top:250px; left: 8px;" width=
"51" height="51" ></canvas>
16 </div>
17 <script type="text/javascript" src="cordova.js"></script>
18 <script type="text/javascript" src="js/Ball.js"></
script>
19 <script type="text/javascript" src="js/VJoy.js"></
script>
20 <script type="text/javascript" src="js/code2.js"></script>
21 </body>
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
7.3. VIRTUAL JOY 67
22 </html>
In the html we can notice additional canvas element for our virtual joy, thiscontroller will be placed within the area that the ball is moving.
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 class Ball{
3
4 constructor (x,y, vx, vy, maxX, maxY, ball_img){
5 this.vx=vx;
6 this.vy=vy;
7 this.x=x;
8 this.y=y;
9 this.maxX = maxX;
10 this.maxY = maxY;
11 this.ball_img=ball_img;
12 }
13
14 startAnimation(){
15 setInterval(this.animation.bind(this), 10);
16 }
17
18 animation(){
19 this.x+=this.vx;
20 this.y+=this.vy;
21 this.ball_img.style.left=this.x+"px";
22 this.ball_img.style.top=this.y+"px";
23 if (this.x<0 || this.x>this.maxX) this.vx*=-1;
24 if (this.y<0 || this.y>this.maxY) this.vy*=-1;
25 }
26 }
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 /* based on basic Apache Cordova app */
3 var app = {
4
5 initialize: function() {
6 document.addEventListener('deviceready', this.
onDeviceReady.bind(this), false);
7 },
8
9 onDeviceReady: function() {
10 var canvas = document.getElementById("vjoy_canvas"
);
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
68 CHAPTER 7. MOBILE GAME INTERFACE
11 var scale = 10;
12 var ball_img = document.getElementById("ball_img")
;
13 var ball = new Ball(30,30,1,1, 300, 300, ball_img)
;
14 this.VJoy = new VJoy(canvas, ball, scale);
15 canvas.addEventListener("touchstart", this.VJoy.
update.bind(this.VJoy), false);
16 canvas.addEventListener("touchmove", this.VJoy.
update.bind(this.VJoy), false);
17 ball.startAnimation();
18 },
19 };
20
21 app.initialize();
Code Explained
All the javascript code that is connected to ball animation is left un-changed. You can notice that the method update of the object VJoyhandles both events touchstart and touchmove. As expected object VJoyrepresents the logic for our virtual Joy.
Now we can discuss the code for our virtual joy:
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 class VJoy {
3
4 constructor(canvas, ball, scale){
5 this.canvas = canvas;
6 this.ball=ball;
7 this.scale=scale;
8 this.actualPosition = {x:0, y:0};
9 this.positionOffset = {x:parseInt(this.canvas.
style.left), y:parseInt(this.canvas.style.top)
};
10 this.drawVJoy();
11 }
12
13 update(event){
14 var touch = event.changedTouches[0];
15 this.actualPosition.x=touch.clientX - this.
positionOffset.x - this.canvas.width/2;
16 this.actualPosition.y=touch.clientY - this.
positionOffset.y - this.canvas.height/2;
17 this.ball.vx = this.actualPosition.x/this.scale;
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
7.3. VIRTUAL JOY 69
18 this.ball.vy = this.actualPosition.y/this.scale;
19 this.drawVJoy();
20 }
21
22 drawVJoy(){
23 var ctx = this.canvas.getContext("2d");
24 ctx.clearRect(0,0,this.canvas.width, this.canvas.
height);
25 //Draw small circle in the middle
26 ctx.beginPath();
27 ctx.arc(this.canvas.width/2, this.canvas.height/2,
1, 0, 2 * Math.PI, false);
28 ctx.fillStyle = '#000000';
29 ctx.fill();
30 //Draw big circle
31 ctx.beginPath();
32 ctx.arc(this.canvas.width/2, this.canvas.height/2,
this.canvas.width/2-2, 0, 2 * Math.PI, false)
;
33 ctx.strokeStyle = '#aaaaaa';
34 ctx.lineWidth = 2;
35 ctx.stroke();
36 if (this.actualPosition.x && this.actualPosition.y
){
37 //Draw position pointer
38 var _x = this.actualPosition.x + this.
canvas.width/2;
39 var _y = this.actualPosition.y + this.
canvas.height/2;
40 ctx.beginPath();
41 ctx.moveTo(this.canvas.width/2, this.canvas
.height/2);
42 ctx.lineTo(_x, _y);
43 ctx.strokeStyle = '#0505ff';
44 ctx.stroke();
45 }
46 }
47 }
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
70 CHAPTER 7. MOBILE GAME INTERFACE
Code Explained
The VJoy object needs information about wrapping canvas, the ball thatis to be controlled and scale all that is provided during construction. Theobject have the �elds scale, actualPosition and positionO�set. Actualposition will represent a position of user touch and position o�set storescoordinates of left top corner of wrapping, the meaning of scale propertywill be discussed later.All the interface drawing is done in drawVJoy methods. The controlinterface consist of two circles, one in the middle is used to show thecenter, and the bigger one bounds the area. When player touches thecontrol area an additional blue line will show the movement direction ofthe ball. At the start of the game when there is no actual position noblue line is shown.The method update connects the control interface with touches and move-ment of the ball. We have to take into account that relative position oftouch to the middle point of the interface should be used for steering theball movement. That is why actualPosition is connected to positionO�setand half of wrapping canvas width (lines 15-16). Additionally we do notwant the size of control interface (canvas width) to have a linear impacton ball velocity, for that reason a scale property was used (lines 17-18).After setting the velocity and actual position the vjoy is drawn (line 19).
7.3.1 Dynamic VJoy
This time we would like our virtual Joy to appear at the place of touchstart andoperate only via moving the �nger. There is no many changes we have to add.First we crate a new class �le DynamicVJov.js.
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 class DynamicVJoy extends VJoy{
3 constructor(canvas, ball, scale){
4 super(canvas,ball,scale);
5 }
6
7 touchStart(event){
8 var touch = event.changedTouches[0];
9 this.canvas.style.left = (touch.clientX-this.
canvas.width/2)+"px";
10 this.canvas.style.top = (touch.clientY-this.canvas
.height/2)+"px";
11 this.canvas.style.display="block";
12 this.positionOffset = {x:parseInt(this.canvas.
style.left), y:parseInt(this.canvas.style.top)
};
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
7.3. VIRTUAL JOY 71
13 super.update(event);
14 }
15
16 touchEnd(event){
17 this.canvas.style.display="none";
18 }
19 }
Code Explained
The class contains a two new methods touchStart and touchEnd. The�rst one sets the new position of interface wrapping canvas, shows thiswrapping canvas and uses known from previous example VJoy class im-plementation of update method. The touchEnd method just hide thewrapping canvas.
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 /* based on basic Apache Cordova app */
3 var app = {
4
5 initialize: function() {
6 document.addEventListener('deviceready', this.
onDeviceReady.bind(this), false);
7 },
8
9 onDeviceReady: function() {
10 this.vjoy_canvas = document.getElementById("
vjoy_canvas");
11 var scale = 10;
12 var ball_img = document.getElementById("ball_img")
;
13 var ball = new Ball(30,30,1,1, 300, 300, ball_img)
;
14 this.VJoy = new DynamicVJoy(this.vjoy_canvas, ball
, scale);
15 document.addEventListener("touchstart",this.VJoy.
touchStart.bind(this.VJoy), false);
16 document.addEventListener("touchmove", this.VJoy.
update.bind(this.VJoy), false);
17 document.addEventListener("touchend", this.VJoy.
touchEnd.bind(this.VJoy), false);
18 ball.startAnimation();
19 },
20
21
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
72 CHAPTER 7. MOBILE GAME INTERFACE
22 };
23
24 app.initialize();
Code Explained
The main js �le di�ers by creation of VJoy �eld (line 14) the new classDynamicVJoy is used instead of VJoy. There are also a new bindings ofhandler for touchstart and touchend events. Both handlers uses methodsof the new derived class DynamicVJoy.
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="Content-Security-Policy" content="
default-src 'self' data: gap: https://ssl.gstatic.com '
unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *;
img-src 'self' data: content:;">
5 <meta name="format-detection" content="telephone=no">
6 <meta name="msapplication-tap-highlight" content="no">
7 <meta name="viewport" content="user-scalable=no, initial-
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
8 <title>Stationary VJoy App</title>
9 </head>
10 <body>
11 <div class="app">
12 <div id="ball_container" width="300" height="300" >
13 <img id="ball_img" src="img/ball.png
" width="30" height="30" style="
position:absolute; left:10; top
:10">
14 </div>
15 <canvas id="vjoy_canvas" style="position:
absolute; top:250px; left: 8px; display
:none" width="51" height="51" ></canvas
>
16 </div>
17 <script type="text/javascript" src="cordova.js"></script>
18 <script type="text/javascript" src="js/Ball.js"></
script>
19 <script type="text/javascript" src="js/VJoy.js"></
script>
20 <script type="text/javascript" src="js/DynamicVJoy
.js"></script>
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
7.4. CATAPULT TYPE CONTROL 73
21 <script type="text/javascript" src="js/code3.js"></script>
22 </body>
23 </html>
Code Explained
In the html �le we have only few changes, the �rst one is to makevjoy_canvas invisible at the start (display:none). Additionally in line20 we add a new �le DynamicVJoy.js and in next line a new main .js �leis included.
7.4 Catapult type control
We all know the game angry birds, In that game the control used something likea catapult mechanics, player using continous touch de�ne the velocity vector ofbird and a end of touch event the movement of the bird starts. In our examplewe will use balls and existing DynamicVJoy, when player touch a ball the VYoywill appear, when player stop touching the ball will start move with appropriatevelocity.
Let's start with html �le:
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="Content-Security-Policy" content="
default-src 'self' data: gap: https://ssl.gstatic.com '
unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *;
img-src 'self' data: content:;">
5 <meta name="format-detection" content="telephone=no">
6 <meta name="msapplication-tap-highlight" content="no">
7 <meta name="viewport" content="user-scalable=no, initial-
scale=1, maximum-scale=1, minimum-scale=1, width=
device-width">
8 <title>Stationary VJoy App</title>
9 </head>
10 <body>
11 <div class="app">
12 <div id="ball_container" width="300" height="300" >
13 <img id="ball1_img" src="img/ball.
png" width="30" height="30"
style="position:absolute; left
:10; top:10">
14 <img id="ball2_img" src="img/ball.
png" width="30" height="30"
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
74 CHAPTER 7. MOBILE GAME INTERFACE
style="position:absolute; left
:10; top:10">
15 </div>
16 <canvas id="vjoy_canvas" style="position:
absolute; top:250px; left: 8px; display
:none" width="51" height="51" ></canvas
>
17 </div>
18 <script type="text/javascript" src="cordova.js"></script>
19 <script type="text/javascript" src="js/Ball.js"></
script>
20 <script type="text/javascript" src="js/VJoy.js"></
script>
21 <script type="text/javascript" src="js/DynamicVJoy
.js"></script>
22 <script type="text/javascript" src="js/
CatapultDVJoy.js"></script>
23 <script type="text/javascript" src="js/code4.js"></script>
24 </body>
25 </html>
As we see there are two balls. The �les Ball.js, VJoy.js and DynamicVJoy.jsare exactly the same as in the last example, we have only two new �les code4.jsand CatapultDVJoy.js.
Now look deeper into the main code4.js �le:
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 /* based on basic Apache Cordova app */
3 var app = {
4
5 initialize: function() {
6 document.addEventListener('deviceready', this.
onDeviceReady.bind(this), false);
7 },
8
9 onDeviceReady: function() {
10 this.vjoy_canvas = document.getElementById("
vjoy_canvas");
11 var scale = 10;
12 this.VJoy = new CatapultDVJoy(this.vjoy_canvas,
scale);
13
14 var ball_img = document.getElementById("ball1_img"
);
15 var ball1 = new Ball(30,30,0.1,0.1, 300, 300,
ball_img);
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
7.4. CATAPULT TYPE CONTROL 75
16 ball_img.logic_ball=ball1;
17 ball_img.addEventListener("touchstart",this.VJoy.
touchStart.bind(this.VJoy), false);
18
19 ball_img = document.getElementById("ball2_img");
20 var ball2 = new Ball(180,30,1,-1, 300, 300,
ball_img);
21 ball_img.logic_ball=ball2;
22 ball1.startAnimation();
23
24 ball_img.addEventListener("touchstart",this.VJoy.
touchStart.bind(this.VJoy), false);
25 ball2.startAnimation();
26
27 document.addEventListener("touchmove", this.VJoy.
update.bind(this.VJoy), false);
28 document.addEventListener("touchend", this.VJoy.
touchEnd.bind(this.VJoy), false);
29 },
30
31
32 };
33
34 app.initialize();
Code Explained
In the starting method onDeviceReady we can see initialisation of twoBall objects (ball1 line 15, and ball2 line 20). We have to remember wehave two objects that represent our ball
• DOM object connected to html element <img> referenced by vari-able ball_img (lines 14, 19) - we can call it visual representative ofthe real ball.
• Ball objects referenced by variables ball1, ball2 (lines 15, 20) - wecan call it logical representative of the real ball.
The Ball object already has reference to appropriate DOM one, howeverwhile the user will touch the DOM element, the touch event object couldhave access only to visual representative of our ball. Remembering thatjavascript is a prototype-based language i.e. at any moment we can add anew �eld/method to existing object. We add a new reference logical_ballto a visual ball representative (line 16, 21).We can see that each ball have a event listener for touchstart, the rest oflisteners are connected to the document object.
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
76 CHAPTER 7. MOBILE GAME INTERFACE
Finally we will analyze the CatapultDVJoy.js:
1 /* Author: Krzysztof Podlaski, University of Lodz */
2 class CatapultDVJoy extends DynamicVJoy{
3 constructor(canvas, scale){
4 super(canvas,null,scale);
5 }
6
7 touchStart(event){
8 console.log("Touch Start");
9 var touch = event.changedTouches[0];
10 this.ball = touch.target.logic_ball;
11 this.canvas.style.left = (touch.clientX-this.
canvas.width/2)+"px";
12 this.canvas.style.top = (touch.clientY-this.canvas
.height/2)+"px";
13 this.canvas.style.display="block";
14 this.positionOffset = {x:parseInt(this.canvas.
style.left), y:parseInt(this.canvas.style.top)
};
15 console.log(touch);
16 console.log(this);
17 this.update(event);
18 }
19
20 update(event){
21 console.log(this);
22 console.log("Ball P: "+this.ball.x +" "+this.ball.
y);
23 console.log("Ball V: "+this.ball.vx +" "+this.ball
.vy);
24 var touch = event.changedTouches[0];
25 this.actualPosition.x=touch.clientX - this.
positionOffset.x - this.canvas.width/2;
26 this.actualPosition.y=touch.clientY - this.
positionOffset.y - this.canvas.height/2;
27 this.drawVJoy();
28 }
29
30 touchEnd(event){
31 console.log("TouchStop");
32 this.canvas.style.display="none";
33 this.ball.vx = -this.actualPosition.x/this.scale;
34 this.ball.vy = -this.actualPosition.y/this.scale;
35 }
36 }
GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development
Project N°: 2017-1-PL01-KA203-038669
7.4. CATAPULT TYPE CONTROL 77
Code Explained
As a VJoy appears after touchstart event we have to �nd what objectwas touched (using touch.target line 10), and get a reference to a properBall object this.ball = touch.target.logic_ball.The method update is almost the same as in VJoy, class, except here wedo not change value of velocity of the controlled ball.In the method touchEnd we hide our VJoj interface and set the appro-priate velocity of controlled ball (lines 33, 34).
Extercises
As we can see when the player touch one of the balls the VJoy interfaceappears at its position, however the ball is still moving away from theVJoy. We could solve that by stopping the time (freezing the game) orstopping the ball. The latter is equivalent to setting velocity of the ballto (0,0) at the moment of the �rst touch. Please make the appropriatechanges to the project.Additionally, the big circle in the VJoy interface is not needed, Pleaserepair that too.