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 using HTML5, Javascript, and CSS. The basic ways of accessing capabilities of mobile devices like GPS, accelerometer, etc., are also covered. As some- times developer needs to access data using AJAX queries, the JQuery library is also introduced. The course should be taken after ’Games De- velopment in JavaScript’. Therefore, it shows how the code from the previous 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 the views only of the authors, and the Commission cannot be held responsible for 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 a very well known and useful library jQuery. Here we will cover some basics of jQuery library and how to use it for simple internet queries. The jQuery library basically 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 eects 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 dierence is only on loading time and requirements of available internet connectivity.

It is better to add

11

20

21

Remark Just for simplicity our js code is simply included inside .html le. In the real word it is better to save that in external .js le and include to the page using

13

24

25

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 we show or hide the element .

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

2

3

4 Gaius Julius Caesar (12 or 13 July 100BC- 15 March 44BC), known by his nomen and cognomen Julius Caesar, wasa Roman politician, military general, and historian who playeda 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

6

7

8

9 height="150pt" class="hidden" id="photoJC"/>

10

15


16

17

18

19

22

28

29

Add the following functionalities: When user click on the button "Show Julius Caesar" the photo of • the Caesar is shown When user click on the button "Show All" every hidden elements • are shown When user click on the button "Hide all again" all elements back • to 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

2

3

4

5

6



7

8 Tyger Tyger, burning bright,

9 In the forests of the night;

10 What immortal hand or eye,

11 Could frame thy fearful symmetry?

12

13

14

15 In what distant deeps or skies,

16 Burnt the fire of thine eyes?

17 On what wings dare he aspire?

18 What the hand, dare seize the fire?

19

20

21

24

31

32

33

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

elements is hidden because in line 14 we set style to display:none.

Here in the line 27 we invoke toggle method on all

element. This will toggle elements between two states hidden and shown.

Additional jQuery actions like slideDown, slideUp, slideToggle allows similar operations but as animated action not instant ones.

1

2

3

4

5

6

7

8

9


10

11 William Blake (28 November 1757 - 12 August 1827) was an English poet, painter, and printmaker. Largely unrecognised during his lifetime, Blake is now considereda 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 formwhat is in proportion to its merits the least read body of poetry in the English language. His visual artistry led 21st- century critic Jonathan Jones to proclaim himfar and away the greatest artist Britain has ever produced. 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 produceda diverse and symbolically rich ouvre, which embraced the imagination asthe body of God orhuman existence itself.

12

13


14

15 Tyger Tyger, burning bright,

16 In the forests of the night;

17 What immortal hand or eye,

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

20

21

22 In what distant deeps or skies,

23 Burnt the fire of thine eyes?

24 On what wings dare he aspire?

25 What the hand, dare seize the fire?

26

27

28

31

49

50

51

Extercises Within the last code change methods slideDown, slideUp, slideToggle into 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 (in milliseconds), test how it changes the original behaviour.

.hide(300), .slideDown(300), .fadeOut(300)

There are also predened 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 in the style of the element

1

2

3

4

5

6



7

8 Tyger Tyger, burning bright,

9 In the forests of the night;

10 What immortal hand or eye,

11 Could frame thy fearful symmetry?

12

13

14

17

40

41

42

43

Code Explained As we can see during animate operation the browser create an animation between 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 abbreviation for Asynchronous Javascript And Xml. This technology allows to send (and receive) information from external sources via asynchronous queries. Usually the data send back and forth is in JSON (JavaScript Object Notation) form. In most of the situations webpages using javascript operations send queries to so called REST services.

2.1 RESTful services

Nowadays most of internet services provide so called REST services. This type of 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 identied by url. For example GET is a Read 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 of two operations POST and PUT (i.e. every API developer denes when POST or 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 provides some set of REST operations. The server part can be created in most of server technologies starting with PHP, python, , ASP.Net, etc. In this tutorial we will use very simple API created in PHP that can receive and send simple data that 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.?id=:id Method GET Parameters id - id of the record Request Data None Response 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 GET Parameters None Request Data None Response 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 POST Parameters None Request 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 PUT Parameters id - id of the record to update Request 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 DELETE Parameters None Request Data None Response 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 browser one 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 special html/js code.

2.1.2 Prepare page for our rest client At rst let us create base for our web rest client.

1

2

3

4

5

6

7

IdNameScore

8


9

10

11

12

13



14

15

16

17

18

19

20

Id:
Name:
Score:

21

22

GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development Project N°: 2017-1-PL01-KA203-038669

16 CHAPTER 2. AJAX QUERIES USING JQUERY

23

24

25

26

29

31

32

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

where results obtained from service will be placed. Additionally, we have ap- propriate buttons for GET, POST and PUT operations. Now we just need 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 the browser, we observe that after clicking on the button "getOne_btn" in the return an alert window with the expected json appears. Changing the value in input 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 AJAX query to the server. This operation has an event "done" that is red when 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 response object but only eld data inside this object.

Now as we know how to obtain an information from server we should work how to add this obtained record into table with results. For that we declare a new 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 button that will designate record to erasure.

function add_record_to_table(data){ var table=$("#result_tbl"); var new_row=$("

"); var cell=$("");

122 var cell=$("

"); cell.html(data.id); cell.appendTo(new_row); cell=$(""); cell.html(data.name); cell.appendTo(new_row); cell=$(""); cell.html(data.score); cell.appendTo(new_row); cell=$(""); var btn=$("
");

123 cell.html(data.id);

124 cell.appendTo(new_row);

125 cell=$("

");

126 cell.html(data.name);

127 cell.appendTo(new_row);

128 cell=$("

");

129 cell.html(data.score);

130 cell.appendTo(new_row);

131 cell=$("

");

132 var btn=$("

19

20

21

22

23

24

25

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 (line 11) denes the properties of the camera, for details see plugin documen- tation. In order to take a photo one has to use method getPicture of navigator.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 achievement or position in external game context. This operation can be fullled via gps coordinates, or scanning nfc tag, qrcode. As we know how to take a picture, we can now use camera for scanning QRCode. There are many solutions that can help 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 in o 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 readability we store them in the folder www/js/qrdecoder/ of our Cordova project and add lines below into index.html.

44

45

46

47

Code Explained The html le is simple, the one extra element is the object for our moving ball. JavaScript code is divided into 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 position coordinates (x,y) and velocity vector (vx,vy). As the ball will move inside closed area the values of maxX and maxY are needed. Additionally, the movement of this virtual ball need to be connected to the movement of ball image on the screen. The ball_img represents DOM img object. All this information will be provided via constructor (lines 4-12). Method startAnimation will start innite loop of our scene animation. During an animation frame we update position using velocity (lines 19, 20), set the new position to bal_img object (lines 21, 22) and bouncing the ball from imaginary 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 (line 15). Whenever the device change orientation the handleOrientation method is invoked, inside we change ball velocity vx, vy according to the orientation parameters alpha, beta (lines 23, 24). If the device support Motion API the method handleMotion will be invoked with device movement.

Extercises Please use the example maze game created in 5 and add the orientation style of control to the game.

6.3 Geolocation

As usual in order to have geolocation functionality we have to add appropriate plugin 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 of the device. The second one can be use to start semi-continuous watching, the watching invoke an event whenever the position changes. The last method stops the watching activity. As usual let us start with basic Cordova project with simple html:

1

2

20

21

22

31

32

GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development Project N°: 2017-1-PL01-KA203-038669

6.3. GEOLOCATION 59

33

34

35

36 Geo App

37

38

39

40

41

42

43

Latitude:
Longitude:

44

45

46

47

48

49

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);//after1 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 le we should notice the object that contains options for position detection location_options. In line 13 the one time location query is invoked, later in lines 15-17 the position watching is starting (with 1 second timeout). Watching activity should stop after 60 seconds (lines 18-22). Whenever the location is obtained onPositionSuccess method is invoked. Here we obtain 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, nd poi 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 game design. The user uses the interface to interact with the game, to control his/her avatar. The design of the interface alow user to awlessly operate and use the game or in the worst case will make the player angry and in result abandon our game. Therefore, the interface should be design with great care. At rst we should 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 with appropriate care. Then the player will probably take the "Gamer Stance".

The player keep the phone in landscape position with two thumbs near the bottom 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 (Orange area) and the rest of the screen very hard for interaction.

Casual or tablet player The player keeps the device in one hand and uses the 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 the phone in one hand, probably in portrait orientation, controlling it with thumb of this hand. This type of player has minimal reach and the control area is very small, additionally multitouch control method is unacceptable. This three types of players demand totally dierent interface for the game. There is no solution that will t to any two types of the player. During the design 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 external context will prefer one of these types of interaction for example if player has to run/move with the phone, we have a subway type player, no sophisticated interaction is possible during movement. Let us now cover some basic methods of interaction and their implementation in Cordova.

7.1 Tap, sigle touch

This method of interaction have been used in this course all the time. All types of buttons, clickable images represents this simplest control method. However for 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 than one nger separately. The simple example below presents how touches can be used for simple drawing application. As usual starting with html le:

1

2

3

4

5

6

7

8 Touch and Drag

9

10

11

12

13

14

15

16

17

18

19

20

21

Now we will build a index.js le. First we have to register event listeners for all 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 dene 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, and y are null as no touch have been initiated yet, colors - table of colors that will be used, the idea is to change color with the start of every new touch, color - the index of actual color to be used when drawing. Now the operations connected to specic touch events. Let us start with touchstart:

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 not want the device to process the event further, this could for example result in ring a click event. Next, we obtain the information about all touches via event.changedTouches, every touch have the properties pageX, pageY that 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 a circle 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, we do 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 and ctx.lineTo methods, after the end of operation we reset the lastTouch coordinates.

Extercises If we comment the last two lines, the drawing method will be totally dierent, however, this can be a suggestion how to implement virtual joystick controller.

Running this exiting code we will see that when touches start we draw a circle, after that the lines that follow the movement are drawn. The nal result is not symmetric as we can easily see the ball at the beginning of the line and nothing 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 two basic vjoy concepts: stationary vjoy - always on the same place, and dynamical one - appears with touchstart. At rst let us cover the stationary one. In this example we will use the ball code from accelerator case.

1

2

3

4

5

6

7

8 Stationary VJoy App

9

10

11

12

13

14

15

16

17

18

21

GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development Project N°: 2017-1-PL01-KA203-038669

7.3. VIRTUAL JOY 67

22

In the html we can notice additional canvas element for our virtual joy, this controller 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 VJoy handles both events touchstart and touchmove. As expected object VJoy represents 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 that is to be controlled and scale all that is provided during construction. The object have the elds scale, actualPosition and positionOset. Actual position will represent a position of user touch and position oset stores coordinates of left top corner of wrapping, the meaning of scale property will be discussed later. All the interface drawing is done in drawVJoy methods. The control interface consist of two circles, one in the middle is used to show the center, and the bigger one bounds the area. When player touches the control area an additional blue line will show the movement direction of the ball. At the start of the game when there is no actual position no blue 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 of touch to the middle point of the interface should be used for steering the ball movement. That is why actualPosition is connected to positionOset and half of wrapping canvas width (lines 15-16). Additionally we do not want the size of control interface (canvas width) to have a linear impact on 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 and operate 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 this wrapping canvas and uses known from previous example VJoy class im- plementation of update method. The touchEnd method just hide the wrapping 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 diers by creation of VJoy eld (line 14) the new class DynamicVJoy is used instead of VJoy. There are also a new bindings of handler for touchstart and touchend events. Both handlers uses methods of the new derived class DynamicVJoy.

1

2

3

4

5

6

7

8 Stationary VJoy App

9

10

11

12

13

14

15

16

17

18

GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development Project N°: 2017-1-PL01-KA203-038669

7.4. CATAPULT TYPE CONTROL 73

21

22

23

Code Explained In the html le we have only few changes, the rst one is to make vjoy_canvas invisible at the start (display:none). Additionally in line 20 we add a new le DynamicVJoy.js and in next line a new main .js le is included.

7.4 Catapult type control

We all know the game angry birds, In that game the control used something like a catapult mechanics, player using continous touch dene the velocity vector of bird and a end of touch event the movement of the bird starts. In our example we will use balls and existing DynamicVJoy, when player touch a ball the VYoy will appear, when player stop touching the ball will start move with appropriate velocity. Let's start with html le:

1

2

3

4

5

6

7

8 Stationary VJoy App

9

10

11

12

13

14

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

16

17

18

19

22

23

24

25

As we see there are two balls. The les Ball.js, VJoy.js and DynamicVJoy.js are exactly the same as in the last example, we have only two new les code4.js and 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 two Ball objects (ball1 line 15, and ball2 line 20). We have to remember we have two objects that represent our ball DOM object connected to html element referenced by vari- • able ball_img (lines 14, 19) - we can call it visual representative of the real ball. Ball objects referenced by variables ball1, ball2 (lines 15, 20) - we • can call it logical representative of the real ball. The Ball object already has reference to appropriate DOM one, however while the user will touch the DOM element, the touch event object could have access only to visual representative of our ball. Remembering that javascript is a prototype-based language i.e. at any moment we can add a new eld/method to existing object. We add a new reference logical_ball to a visual ball representative (line 16, 21). We can see that each ball have a event listener for touchstart, the rest of listeners 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 object was touched (using touch.target line 10), and get a reference to a proper Ball object this.ball = touch.target.logic_ball. The method update is almost the same as in VJoy, class, except here we do 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 interface appears at its position, however the ball is still moving away from the VJoy. We could solve that by stopping the time (freezing the game) or stopping the ball. The latter is equivalent to setting velocity of the ball to (0,0) at the moment of the rst touch. Please make the appropriate changes to the project. Additionally, the big circle in the VJoy interface is not needed, Please repair that too.

GENIUS – Innovative Interdisciplinary Contextual Education Using Games Development Project N°: 2017-1-PL01-KA203-038669