-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathreport.html
More file actions
1375 lines (982 loc) · 88.3 KB
/
Copy pathreport.html
File metadata and controls
1375 lines (982 loc) · 88.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Making Freewee Report</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="making-freewee">Making Freewee</h1>
<blockquote>
<p><strong><em>Group 9, The Magical Programming Machine</em></strong> <br>
Christabella, Jiuqi, Nigel, Rong Ying </p>
</blockquote>
<p>Freewee is a multiplayer, realtime HTML5 web app built with Node.js, Socket.io, and Phaser.</p>
<p><div class="toc">
<ul>
<li><a href="#making-freewee">Making Freewee</a><ul>
<li><a href="#game-concept">Game Concept</a></li>
<li><a href="#game-components">Game Components</a><ul>
<li><a href="#game-lobby">Game Lobby</a></li>
<li><a href="#run-sumo-run">Run Sumo Run!</a></li>
<li><a href="#save-our-planet">Save Our Planet!</a></li>
<li><a href="#sumos-can-charm-snakes-too">Sumos Can Charm Snakes Too!</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#system-requirements">System Requirements</a><ul>
<li><a href="#user-requirements">User Requirements</a></li>
<li><a href="#functional-and-non-functional-requirements">Functional and Non-Functional Requirements</a></li>
<li><a href="#use-cases-and-use-case-diagrams">Use Cases and Use Case Diagrams</a><ul>
<li><a href="#1-join-game">1. Join Game</a></li>
<li><a href="#2-main-menu">2. Main Menu</a></li>
<li><a href="#3-game-start-general">3. Game Start - General</a></li>
<li><a href="#4-increase-running-speed-run-sumo-run">4. Increase Running Speed - Run Sumo Run!</a></li>
<li><a href="#5-cross-finish-line-run-sumo-run">5. Cross Finish Line - Run Sumo Run!</a></li>
<li><a href="#6-decrease-hp-save-our-planet">6. Decrease HP - Save Our Planet!</a></li>
<li><a href="#7-game-over-save-our-planet">7. Game Over - Save Our Planet!</a></li>
<li><a href="#8-play-flute-sumos-can-charm-snakes-too">8. Play Flute - Sumos Can Charm Snakes Too!</a></li>
<li><a href="#9-game-over-sumos-can-charm-snakes-too">9. Game Over - Sumos Can Charm Snakes Too!</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#system-design">System Design</a><ul>
<li><a href="#sequence-diagram">Sequence Diagram</a></li>
<li><a href="#nodejs-app-architecture">Node.js App Architecture</a><ul>
<li><a href="#synchronizer-class-diagram">Synchronizer Class Diagram</a></li>
</ul>
</li>
<li><a href="#realtime-communication">Realtime Communication</a><ul>
<li><a href="#websocket-api">WebSocket API</a></li>
<li><a href="#socketio-library">Socket.io Library</a></li>
<li><a href="#evaluation-of-sockets">Evaluation of Sockets</a></li>
</ul>
</li>
<li><a href="#game-implementation">Game Implementation</a><ul>
<li><a href="#phaserio">Phaser.io</a></li>
<li><a href="#state-diagram">State Diagram</a><ul>
<li><a href="#initial-state">Initial State</a></li>
<li><a href="#lobby-state">Lobby State</a></li>
<li><a href="#boot-state">Boot State</a></li>
<li><a href="#preload-state">Preload State</a></li>
<li><a href="#menu-state">Menu State</a></li>
<li><a href="#game-state">Game State</a></li>
<li><a href="#game-over-state">Game Over State</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#client-side-device-sensors">Client-Side Device Sensors</a><ul>
<li><a href="#deviceorientationevent">DeviceOrientationEvent</a></li>
<li><a href="#devicemotionevent">DeviceMotionEvent</a></li>
<li><a href="#getusermedia">getUserMedia</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#code-structure">Code Structure</a><ul>
<li><a href="#file-structure">File Structure</a><ul>
<li><a href="#the-freewee-module">The freewee module</a><ul>
<li><ul>
<li><a href="#class-diagram">Class Diagram</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#the-synchronizer-module">The synchronizer module</a><ul>
<li><ul>
<li><a href="#class-diagram-1">Class Diagram</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#phaserio-game-logic">Phaser.io Game Logic</a><ul>
<li><a href="#main-functions">Main Functions</a></li>
<li><a href="#class-diagram-2">Class Diagram</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#system-testing">System Testing</a><ul>
<li><a href="#unit-testing-in-mocha">Unit Testing in Mocha</a><ul>
<li><a href="#webserver-tests">Webserver Tests</a></li>
<li><a href="#socket-communication-tests">Socket Communication Tests</a></li>
</ul>
</li>
<li><a href="#play-testing">Play Testing</a><ul>
<li><a href="#ngrok-and-its-issues">Ngrok and its issues</a><ul>
<li><a href="#intermittent-disconnects">Intermittent Disconnects</a></li>
<li><a href="#https-support">HTTPS support</a></li>
<li><a href="#server-load-and-uptime">Server load and Uptime</a></li>
</ul>
</li>
<li><a href="#solution-to-ngroks-issues">Solution to Ngrok’s issues</a><ul>
<li><a href="#intermittent-disconnects-1">Intermittent Disconnects</a></li>
<li><a href="#https-support-1">HTTPS support</a></li>
<li><a href="#server-load-and-uptime-1">Server load and Uptime</a></li>
</ul>
</li>
<li><a href="#client-side-testing">Client-Side Testing</a><ul>
<li><a href="#user-agent-overrider-extension">User Agent Overrider Extension</a></li>
<li><a href="#remote-debugging-on-android-using-chrome">Remote Debugging on Android using Chrome</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#concurrency">Concurrency</a><ul>
<li><a href="#threading">Threading</a><ul>
<li><a href="#non-blocking-io">Non-blocking I/O</a></li>
</ul>
</li>
<li><a href="#vertical-scaling">Vertical Scaling</a></li>
</ul>
</li>
<li><a href="#bibliography">Bibliography</a></li>
</ul>
</div>
</p>
<h2 id="game-concept">Game Concept</h2>
<p>Our group wanted to create a <strong>simple</strong> and <strong>easy to learn</strong> game that will <strong>bring family and friends together in a fun setting</strong>. The game aims to elicit fun and laughter through silly and ridiculous actions which can help players build memorable moments with family and friends. Unlike many online games, this game encourages players to be physically close to each other, to promote bonding.</p>
<p>We drew inspiration from <em>Nintendo Wii</em> games and the <em>Google Star Wars Demo</em> (where we brandish our phones like lightsabers) to create Freewee in hopes that our game will become an <em>easily accessible and widely relevant party game for people of all ages</em>. </p>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/At%20A%20Glance.png?raw=true" alt="At A Glance" title="At A Glance"></p>
<p>The main concept is that players will use their phones as controllers and have an additional laptop or PC to function as the game screen. Players can play with one another by joining the same room. For this type of concept where the game would need to be <strong>displayed not just on phones</strong>, but on a computer screen as well, we chose to create a <strong>web-based HTML5 game application</strong>. An added bonus of a web platform is an ever lower barrier to introducing your friends and family to Freewee — you don’t even have to install anything, just go to the <a href="http://freewee.herokuapp.com">URL</a>!</p>
<h2 id="game-components">Game Components</h2>
<h3 id="game-lobby">Game Lobby</h3>
<p><img src="http://i.imgur.com/r0tGHLs.png" alt="Welcome page" title="Welcome page"> <br>
<em>Welcome Page</em> <br>
<img src="http://i.imgur.com/UBVVb1l.png" alt="Lobby" title="Players get the pick the game they want to play"> <br>
<em>Lobby</em></p>
<p>In the game lobby, players match up with one another and get to pick which mini-game they want to play. The game is chosen by clicking on one out of the three mini-games.</p>
<p><img src="http://i.imgur.com/H8TNbtq.png" alt="Sumo Client" title="Your unique sumo"> <br>
Players are assigned a unique sumo avatar which will be used to identify them in the games. They can check which avatar they are assigned to by looking at their mobile device’s screen.</p>
<h3 id="run-sumo-run">Run Sumo Run!</h3>
<p><img src="http://i.imgur.com/I6ksRuB.png" alt="SumoRun Menu" title="Run Sumo Run! Intro screen"> <br>
<img src="http://i.imgur.com/A63GLTN.png" alt="SumoRun Instructions" title="How to play Run Sumo Run!"> <br>
<img src="http://i.imgur.com/4estsWs.png" alt="SumoRun Game" title="The game!"> <br>
<img src="http://i.imgur.com/H8TNbtq.png" alt="SumoRun Client" title="This is shown on the mobile device"> <br>
In <em>Run Sumo Run!</em>, players race against each other to the finish line. The players are able to collide into one another in an attempt to slow each other down.</p>
<p>The players move forward by performing a forward/backward tilting motion with their mobile devices. They are also able to move sideways by tilting their mobile devices to its sides. The faster the player does the forward/backward tilting motion, the faster the Sumo runs towards the finish line. However, if the player does not tilt rigorously enough, the sumo will slow down and eventually come to a halt.</p>
<p>The first player to reach the finish line wins.</p>
<h3 id="save-our-planet">Save Our Planet!</h3>
<p><img src="http://i.imgur.com/cL8V8b3.png" alt="Planet Game" title="Save Our Planet! Intro screen"> <br>
<img src="http://i.imgur.com/6rEqBDl.png" alt="Planet Instructions" title="How to play Save Our Planet!"> <br>
<img src="http://i.imgur.com/e0zFNIS.png" alt="Planet Game screen" title="The game!"> <br>
<img src="http://i.imgur.com/VBbK7nN.png" alt="Planet Game Client Side" title="This is shown on the mobile device"> <br>
In <em>Save Our Planet!</em>, players collaborate to stop a deadly meteor from wiping out planet Earth. The players are tasked to charge up their Sumo to stop the meteor by tapping on various buttons on their mobile devices. </p>
<p>Players score points by rapidly tapping on buttons on their mobile device. Every single tap action from every player contributes to stopping the meteor from destroying planet Earth. If the time limit is reached and the meteor has not been destroyed, then it is the end for planet Earth. Scores are calculated based on how many times the player has tapped on the right buttons on their mobile devices.</p>
<p>The player with the highest score wins.</p>
<h3 id="sumos-can-charm-snakes-too">Sumos Can Charm Snakes Too!</h3>
<p><img src="http://i.imgur.com/PWPnpHi.png" alt="Snake Game" title="Sumos Can Charm Snakes Too! Intro Screen"> <br>
<img src="http://i.imgur.com/czf47xF.png" alt="Snake Game Instructions" title="How to play Sumos Can Charm Snakes Too!"> <br>
<img src="http://i.imgur.com/aTf3Rrt.png" alt="Snake Game" title="Charm Snakes"> <br>
<img src="http://i.imgur.com/xyRCLfp.png" alt="Snake Game Client Side" title="This is shown on the mobile device"> <br>
In <em>Sumos Can Charm Snakes Too!</em>, players are tasked with charming a deadly snake by using their trusty snake charming flute. </p>
<p>The players will have to follow a sequence of button presses shown on the PC screen and replicate the same sequence while blowing into the mobile device’s microphone. If the right sequence is replicated, the deadly snake will emerge from its basket and dance to the player’s soothing beats. To increase the fun factor, we implemented force feedback when the player blows into the microphone.</p>
<p>The player who manages to charm the snake out with the highest score wins.</p>
<h1 id="system-requirements">System Requirements</h1>
<h2 id="user-requirements">User Requirements</h2>
<p>As we are targeting a general public, the user requirements are varied as well. This is the analysis of what the user needs and wants out of a party-style themed game.</p>
<ol>
<li>User needs to be able to join and play with multiple players in real time.</li>
<li>User needs to be able to send data over from his controller and receive feedback almost instantaneously.</li>
<li>User wants a game that is easily understandable, simple (not too complex). Game can be brainless and physical also. User does not want to spend too much time on one game. </li>
<li>User wants a game that is aesthetically appealing.</li>
<li>User wants a game that loads fast. </li>
</ol>
<h2 id="functional-and-non-functional-requirements">Functional and Non-Functional Requirements</h2>
<p>Use cases distill the essence of requirements as sets of action-response transactions between the user and the system.</p>
<p>A functional requirement is one on the functionality of the system, while a non-functional requirement is one on the performance of the system.</p>
<table>
<thead>
<tr>
<th>Functional Requirement</th>
<th>Non-Functional Requirement</th>
</tr>
</thead>
<tbody><tr>
<td>Concept: Mini-Games that do not take too long to learn, understand and play. Maximum fun in minimum time!</td>
<td>Response Time:The response time of the game must be immediate and fast to keep the interest of the players.</td>
</tr>
<tr>
<td>Function: Each game has to allow up to 4 players to join in the game. Game has to have a simple objective to be met.</td>
<td>Reliability: Game hosted must be reliable and not have bugs or crash. Data sent over from client devices have to be reliable.</td>
</tr>
<tr>
<td>Behaviour: Game should behave in a logical flow.</td>
<td>Availability: Game must be accessible and available anywhere and everywhere as long as there is internet connection.</td>
</tr>
<tr>
<td>I/O Operations: Game needs to be able to support heavy I/O operations based on game concept as it is retrieving and interpreting player data.</td>
<td>Security: Game should be secure. It should not be hosted on malicious server, or request any personal details from players.</td>
</tr>
<tr>
<td>Logic & Computation: Game logic should be logical, modularized and simple to implement.</td>
<td>Cost: Game should cost little or nothing.</td>
</tr>
<tr>
<td>-</td>
<td>Technology: Type of technology required should be the minimum. We considered a phone to be something one should own in order to play.</td>
</tr>
</tbody></table>
<h2 id="use-cases-and-use-case-diagrams">Use Cases and Use Case Diagrams</h2>
<h3 id="1-join-game">1. Join Game</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC01 - Join Game</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Join Game</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>Allow players to enter the room and match to play.</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>1.Players can establish connection to the website server. <br>2.Players type in the same room ID with their friends. <br>3.Players are using compatible devices.</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong> <br> 1.Players enter to the main page. <br> 2.Player’s phone display different colors of sumo as their identity. <br> 3.Game screen displays main menu for users to select games. <br> <strong>Failure</strong><br>Can’t go into the room.</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br>1.Players <br> 2.Lobby <br> <strong>Secondary</strong> <br> Main Menu</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>Connection request from players.</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.PC (game screen) browse to <a href="https://freewee.herokuapp.com">https://freewee.herokuapp.com</a> and server will generate a game ID. <br> 2.Players also browse to this website on their phone and login with room ID and own username. <br> 3.Player’s handphone will display different colors of sumo as their identity. <br> 4.Once the players see that all their fellow players have successfully connected to the lobby, they press “All Players Ready” button on the game screen which direct them to the main menu.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>1&2.Player is unable to connect; use case concludes with error notification. <br> 3.Players are distrubuted with same color of sumo; use case concludes with error notification.</td>
</tr>
<tr>
<td align="center"><strong>Interacts with</strong></td>
<td>Main Page</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>Network connectivity issues</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Join%20Game.png?raw=true" alt="Join Game" title="Join Game"></p>
<h3 id="2-main-menu">2. Main Menu</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC02 - Main Menu</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Main Menu</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>After all the players join the room, allow players to select games</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>Players have entered the room successfully.</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong><br> 1.Go to corresponding game introduction page. <br> 2.Continue to start the game.<br><strong>Failure</strong><br>Game page was not loaded.</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br> Main menu <br><strong>Secondary</strong> <br> Each game page</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>Click “All Players Ready” button.</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.After players successfully join the game, they proceed to main menu page. <br> 2.Game screen displays different game buttons for players to choose. <br> 3.Players click the game they want to play and proceed to corresponding game page.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>2.Game options are not successfully loaded; use case concludes with error notification. <br> 3.Game was not successfully loaded; use case concludes with error notification.</td>
</tr>
<tr>
<td align="center"><strong>Interacts with</strong></td>
<td>Game Start</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>Network connectivity issues</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Main%20Page.png?raw=true" alt="Main Menu" title="Main Menu"></p>
<h3 id="3-game-start-general">3. Game Start - General</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC03 - Game Start - General</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Game Start</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>Allow players to start playing game.</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>1.Players click the game they want to play.</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong><br> Game start. <br><strong>Failure</strong><br> Game doesn’t start.</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br> Game Start. <br><strong>Secondary</strong> <br> Game engine.</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>Click the game on game screen.</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.Game screen display introduction page. <br> 2.Click to continue to game page. <br> 3.Start the game.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>1.Game introduction page isn’t successfully loaded; use case concludes with error notification. <br> 2. a. Game page isn’t successfully loaded; use case concludes with error notification. <br>b. Players’ phone sensors don’t work.</td>
</tr>
<tr>
<td align="center"><strong>Interacts with</strong></td>
<td>Game Page</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>Network connectivity issues, phone sensor issues</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Game%20Start.png?raw=true" alt="Game Start" title="Game Start"></p>
<h3 id="4-increase-running-speed-run-sumo-run">4. Increase Running Speed - Run Sumo Run!</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC04 - Increase Running Speed - Run Sumo Run!</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Increase Running Speed</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>Let players advance in distance towards the finish line, the crossing of which is the game’s win condition.</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>Players are in the game of “Run Sumo Run!”</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong><br> Players speed up <br><strong>Failure</strong><br> Player doesn’t speed up</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br> 1.Players <br> 2.Sensors <br> 3.Game engine</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>Periodic update of phone sensor data.</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.All Players are playing in the game of “Run Sumo Run!”. <br> 2.Player moves their device up and down in rapid succession. <br> 3.The sensor detects the motion and sumo will increase his speed. <br> 4.Keep updating until game over.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>3.a. The sensor doesn’t work or have problem with data transimisson. <br> b. The sensor have lagging issue on data transmission.</td>
</tr>
<tr>
<td align="center"><strong>Interacts with</strong></td>
<td>Game Start, Cross Finish Line</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>Sensitivity of phone sensors, transmission of sensor data</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Increase%20Running%20Speed.png?raw=true" alt="Increase Running Speed" title="Increase Running Speed"></p>
<h3 id="5-cross-finish-line-run-sumo-run">5. Cross Finish Line - Run Sumo Run!</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC05 - Cross Finish Line - Run Sumo Run!</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Cross Finish Line</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>When the player cross the finish line, it will direct to “game over” state.</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>Players are in the game of “Run Sumo Run!”</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong><br> 1.The rank of the player will be displayed on his lane <br> 2.Change to “game over” state. <br><strong>Failure</strong><br> Keep tracking players’ position.</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br> 1.Player <br> 2.Position tracker</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>When players’ position equals to finish line position.</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.Position tracker keeps updating player’s position. <br> 2.When player’s position equals to finish line, the rank will be displayed on player’s lane. <br> 3.After all players crossed finish line, change to “game over” state.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>1&2.Position tracker is lagging with position updating. <br> 2&3.More than one player cross the line.</td>
</tr>
<tr>
<td align="center"><strong>Interacts with</strong></td>
<td>Game Over</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>Synchronization issues</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Cross%20Finish%20Line.png?raw=true" alt="Cross Finish Line" title="Cross Finish Line"></p>
<h3 id="6-decrease-hp-save-our-planet">6. Decrease HP - Save Our Planet!</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC06 - Decrease HP - Save Our Planet!</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Decrease HP</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>Decrease the HP to zero to crack the meteor.</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>Players are in the game of “Save Our Planet!”</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong><br> As the HP decrease, cracks will appear on the meteor and finally explode if HP decrease to zero. <br><strong>Failure</strong><br> HP can’t decrease.</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br> Lifting method <br><strong>Secondary</strong> <br> damageDone method</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>Player tap on the buttons on sumo.</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.Players tap to lift the meteor and decrease HP. <br> 2.Cracks appear as the HP decrease. <br> 3.If the HP decrease to zero when time’s up, meteor explode and players all win.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>1.Counter can’t synchronize player’s lifting smoothly <br> 3.If the HP isn’t zero when time’s up, players all died.</td>
</tr>
<tr>
<td align="center"><strong>Interacts with</strong></td>
<td>Game Over</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>-</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Decrease%20HP.png?raw=true" alt="Decrease HP" title="Decrease HP"></p>
<h3 id="7-game-over-save-our-planet">7. Game Over - Save Our Planet!</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC07 - Game Over - Save Our Planet!</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Game Over - Save Our Planet!</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>End the game and show the result.</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>Time’s up.</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong><br> Game will end and result will display. <br><strong>Failure</strong><br>Game won’t end and result won’t show.</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br> Game Over</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>Time’s up.</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.Time’s up. <br> 2.Game ends and game screen display the pointText for each player. The winner is the one get highest points.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>2.Game doesn’t end and game screen won’t show game over page.</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>-</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Game%20Over.png?raw=true" alt="Game Over" title="Game Over"></p>
<h3 id="8-play-flute-sumos-can-charm-snakes-too">8. Play Flute - Sumos Can Charm Snakes Too!</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC08 - Play Flute - Sumos Can Charm Snakes Too!</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Play Flute</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>Players play flute according to the instruction to charm snake up.</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>Players are in the game of “Sumos Can Charm Snakes Too!”</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong><br> Snakes will be charmed up. <br><strong>Failure</strong><br>Snakes can’t be charmed.</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br> Phone microphone <br> Blowing method</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>Player blow and tap the correct button.</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.Player blow the microphone and tap the button in correct sequence. <br> 2.Corresponding pitch will play and snake will be charmed up <br> 3.If time’s up, change to “game over” state and game screen will display players’ scores.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>If the microphone doesn’t detect blow or players don’t press the button in correct sequence, the pitch will not play and snake will not be charmed.</td>
</tr>
<tr>
<td align="center"><strong>Interacts with</strong></td>
<td>Game Over</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>Sensitivity of phone sensors, transmission of sensor data</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Play%20Flute.png?raw=true" alt="Play Flute" title="Play Flute"></p>
<h3 id="9-game-over-sumos-can-charm-snakes-too">9. Game Over - Sumos Can Charm Snakes Too!</h3>
<table>
<thead>
<tr>
<th align="center">-</th>
<th>UC09 - Game Over - Sumos Can Charm Snakes Too!</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Name</strong></td>
<td>Game Over - Sumos Can Charm Snakes Too!</td>
</tr>
<tr>
<td align="center"><strong>Objective</strong></td>
<td>End the game and show which player is the winner.</td>
</tr>
<tr>
<td align="center"><strong>Pre-conditions</strong></td>
<td>Time’s up.</td>
</tr>
<tr>
<td align="center"><strong>Post-conditions</strong></td>
<td><strong>Success</strong><br> Game will end and winner will display. <br><strong>Failure</strong><br>Game won’t end and winner won’t show.</td>
</tr>
<tr>
<td align="center"><strong>Actors</strong></td>
<td><strong>Primary</strong><br> Game Over</td>
</tr>
<tr>
<td align="center"><strong>Trigger</strong></td>
<td>Time’s up</td>
</tr>
<tr>
<td align="center"><strong>Normal Flow</strong></td>
<td>1.Time’s up. <br> 2.Game ends and game screen display the pointText for each player. The winner is the one get highest points.</td>
</tr>
<tr>
<td align="center"><strong>Alternative Flow</strong></td>
<td>2.Game doesn’t end and game screen won’t show game over page.</td>
</tr>
<tr>
<td align="center"><strong>Open Issues</strong></td>
<td>-</td>
</tr>
</tbody></table>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/useCaseDiagram/Game%20Over.png?raw=true" alt="Game Over" title="Game Over"></p>
<h1 id="system-design">System Design</h1>
<p>Clients (game screens or controllers) communicate with a <strong>Node.js server</strong> in realtime through <strong>XHR/JSONP polling transport or WebSocket transport</strong> (depending on browser support). The game is created with the <strong>Phaser game framework</strong>.</p>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/Overall%20Infrastructure.png?raw=true" alt="Overall Infrastructure" title="Overall Infrastructure"> <br>
<em>Overall Infrastructure</em></p>
<p>On top of Node.js, we used <strong>Express</strong>, a minimal and flexible Node.js web application framework, to set up middlewares to respond to HTTP Requests, define a routing table (Freewee only uses the root route), and dynamically render HTML Pages based on passing arguments to templates.</p>
<p>For realtime communication, we used <strong>Socket.IO</strong>, a realtime web application framework for bidirectional event-based communication. The evented, streaming nature of sockets fits conceptually with the Node architecture — clients and servers are simply piping data back and forth through consistent interfaces:</p>
<p><img src="http://blog.nodejitsu.com/content/images/2014/Feb/express.png" alt="Node.js Express Server and Socket.IO Realtime IO Library" title=""> <br>
<em>Node.js Express Framework and Socket.IO Realtime IO Library</em></p>
<h2 id="sequence-diagram">Sequence Diagram</h2>
<p>Here is an example of how we use Node.js, Socket.IO, and client-side rendering to <strong>create a room, join a room, and start a game</strong>.</p>
<div class="sequence-diagram"><svg height="1031" version="1.1" width="1331.921875" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="overflow: hidden; position: relative; top: -0.75px;"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.2</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><marker id="raphael-marker-endblock55-obj43" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj46" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj49" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj52" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj55" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj64" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj67" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj70" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj73" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj79" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj82" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker><marker id="raphael-marker-endblock55-obj85" markerHeight="5" markerWidth="5" orient="auto" refX="2.5" refY="2.5" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#raphael-marker-block" transform="rotate(180 2.5 2.5) scale(1,1)" stroke-width="1.0000" fill="#000" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></use></marker></defs><rect x="175.796875" y="20" width="102.671875" height="39" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="185.78125" y="30" width="82.671875" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="227.1328125" y="39.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Game Screen</tspan></text><rect x="175.796875" y="972" width="102.671875" height="39" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="185.78125" y="982" width="82.671875" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="227.1328125" y="991.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Game Screen</tspan></text><path fill="none" stroke="#000000" d="M227.1328125,59L227.1328125,972" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="564.109375" y="20" width="60.484375" height="39" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="574.109375" y="30" width="40.484375" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="594.3515625" y="39.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Server</tspan></text><rect x="564.109375" y="972" width="60.484375" height="39" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="574.109375" y="982" width="40.484375" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="594.3515625" y="991.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Server</tspan></text><path fill="none" stroke="#000000" d="M594.3515625,59L594.3515625,972" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="1055.9453125" y="20" width="83.40625" height="39" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="1065.953125" y="30" width="63.40625" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="1097.6484375" y="39.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Controller</tspan></text><rect x="1055.9453125" y="972" width="83.40625" height="39" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="1065.953125" y="982" width="63.40625" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="1097.6484375" y="991.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Controller</tspan></text><path fill="none" stroke="#000000" d="M1097.6484375,59L1097.6484375,972" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="394.109375" y="74.5" width="33.25" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="410.7421875" y="84" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">GET /</tspan></text><path fill="none" stroke="#000000" d="M227.1328125,98C227.1328125,98,545.4444036106579,98,589.3521304118107,98" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj43)" stroke-dasharray="0" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="281.9375" y="113.5" width="257.578125" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="410.7421875" y="123" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">HTTP 200 OK: rendered game.handlebars</tspan></text><path fill="none" stroke="#000000" d="M594.3515625,137C594.3515625,137,276.0399713893421,137,232.13224458818934,137" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj46)" stroke-dasharray="6,2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="344.84375" y="152.5" width="131.78125" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="410.7421875" y="162" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Socket.io Handshake</tspan></text><path fill="none" stroke="#000000" d="M227.1328125,176C227.1328125,176,545.4444036106579,176,589.3521304118107,176" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj49)" stroke-dasharray="0" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="334.078125" y="191.5" width="153.3125" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="410.7421875" y="201" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Socket.io Handshake OK</tspan></text><path fill="none" stroke="#000000" d="M594.3515625,215C594.3515625,215,276.0399713893421,215,232.13224458818934,215" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj52)" stroke-dasharray="6,2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="276.28125" y="230.5" width="268.90625" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="410.7421875" y="240" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">socket.emit('synchronizer-create', roomID);</tspan></text><path fill="none" stroke="#000000" d="M227.1328125,254C227.1328125,254,545.4444036106579,254,589.3521304118107,254" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj55)" stroke-dasharray="0" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="492.8203125" y="274" width="203.0625" height="47" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="497.8125" y="279" width="193.0625" height="37" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="594.3515625" y="297.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="-3.5">Socket.IO room (channel) with </tspan><tspan dy="18" x="594.3515625" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">ID : roomID created</tspan></text><rect x="146.40625" y="341" width="161.453125" height="29" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="151.390625" y="346" width="151.453125" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="227.1328125" y="355.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Show room ID on screen</tspan></text><rect x="783.375" y="385.5" width="125.21875" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="846" y="395" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">GET / (lobby screen)</tspan></text><path fill="none" stroke="#000000" d="M1097.6484375,409C1097.6484375,409,651.7194003418554,409,599.3532219060479,409" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj64)" stroke-dasharray="0" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="704.359375" y="424.5" width="283.25" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="846" y="434" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">HTTP 200 OK: rendered controller.handlebars</tspan></text><path fill="none" stroke="#000000" d="M594.3515625,448C594.3515625,448,1040.2805996581446,448,1092.6467780939522,448" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj67)" stroke-dasharray="6,2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="780.09375" y="463.5" width="131.78125" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="846" y="473" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Socket.io Handshake</tspan></text><path fill="none" stroke="#000000" d="M1097.6484375,487C1097.6484375,487,651.7194003418554,487,599.3532219060479,487" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj70)" stroke-dasharray="0" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="769.328125" y="502.5" width="153.3125" height="19" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="846" y="512" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="5.5">Socket.io Handshake OK</tspan></text><path fill="none" stroke="#000000" d="M594.3515625,526C594.3515625,526,1040.2805996581446,526,1092.6467780939522,526" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj73)" stroke-dasharray="6,2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="962.8203125" y="546" width="269.65625" height="65" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="967.8125" y="551" width="259.65625" height="55" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="1097.6484375" y="578.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="-12.5">User enters a username and the roomID</tspan><tspan dy="18" x="1097.6484375" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"> shown on existing Game Screen, and </tspan><tspan dy="18" x="1097.6484375" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">requests to join the room with id : roomID</tspan></text><rect x="733.390625" y="617.5" width="225.203125" height="37" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="846" y="636" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="-3.5">socket.emit('synchronizer-join',</tspan><tspan dy="18" x="846" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"> {id: roomID, username: username});</tspan></text><path fill="none" stroke="#000000" d="M1097.6484375,668C1097.6484375,668,651.7194003418554,668,599.3532219060479,668" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj79)" stroke-dasharray="0" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="604.34375" y="674.5" width="483.296875" height="37" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="846" y="693" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="-3.5">io.to(roomID).emit('synchronizer-join', {username: msg.username, id: msg.id, </tspan><tspan dy="18" x="846" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"> playerOrder: rooms[msg.id], success: true, msg: "Successfully joined room."});</tspan></text><path fill="none" stroke="#000000" d="M594.3515625,725C594.3515625,725,1040.2805996581446,725,1092.6467780939522,725" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj82)" stroke-dasharray="6,2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="237.125" y="722.5" width="347.21875" height="55" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="410.7421875" y="750" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="-12.5">io.to(roomID).emit('synchronizer-join', {username: </tspan><tspan dy="18" x="410.7421875" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"> msg.username, id: msg.id, playerOrder: rooms[msg.id], </tspan><tspan dy="18" x="410.7421875" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">success: true, msg: "Successfully joined room."});</tspan></text><path fill="none" stroke="#000000" d="M594.3515625,800C594.3515625,800,276.0399713893421,800,232.13224458818934,800" stroke-width="2" marker-end="url(#raphael-marker-endblock55-obj85)" stroke-dasharray="6,2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><rect x="945.078125" y="820" width="305.140625" height="47" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="950.0625" y="825" width="295.140625" height="37" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="1097.6484375" y="843.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="-3.5">Display appropriate sumo on controller </tspan><tspan dy="18" x="1097.6484375" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">screen, according to received data.playerOrder.</tspan></text><rect x="10" y="887" width="434.265625" height="65" rx="0" ry="0" fill="none" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><rect x="14.984375" y="892" width="424.265625" height="55" rx="0" ry="0" fill="#ffffff" stroke="none" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></rect><text x="227.1328125" y="919.5" text-anchor="middle" font-family="Andale Mono, monospace" font-size="16px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: "Andale Mono", monospace; font-size: 16px;"><tspan style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" dy="-12.5">Once all players have joined the room, click "ALL PLAYERS READY" </tspan><tspan dy="18" x="227.1328125" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">button. Use client-side JavaScript to render a Phaser game, starting </tspan><tspan dy="18" x="227.1328125" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">with the Lobby game state, a screen with mini-games.</tspan></text></svg></div>
<h2 id="nodejs-app-architecture">Node.js App Architecture</h2>
<p>We structured our Node app into modules, with a separate module for the app itself, and another module for the synchronization between controllers, clients, and servers. These are elaborated on in the <strong>Code Structure</strong> section.</p>
<h3 id="synchronizer-class-diagram">Synchronizer Class Diagram</h3>
<h2 id="realtime-communication">Realtime Communication</h2>
<p>In Freewee, we use TCP socket connections and pipe data through them bidirectionally with <strong>Socket.IO</strong>. Socket communication is <em>efficient</em>, only occurring when one of the parties has something useful to say: <br>
<img src="https://masteringmean.com/graphics/6320OS_06_04.jpg" alt="Responding to messages" title="Responding to messages"></p>
<p>For a <em>realtime multiplayer game</em> such as Freewee, where <strong>high-frequency messaging</strong> between clients and server are required, this lightweight model is an excellent choice.</p>
<p>The <strong>native WebSocket API</strong> is an API proposed by the W3C, that allows browsers to communicate with a socket server over a persistent connection. </p>
<p><strong>Socket.IO</strong> is a library that facilitates the management of persistent socket connections for those developing with Node.js, providing both a <em>Node.js-based socket server and an emulation layer for browsers that do not support the WebSocket API natively</em>.</p>
<h3 id="websocket-api">WebSocket API</h3>
<p>The general schematic for an application using the WebSocket API implementation for bidirectional communication looks like this: <br>
<img src="https://masteringmean.com/graphics/6320OS_06_06.jpg" alt="Schematic of a web app using the WebSocket API" title="Schematic of a web app using the WebSocket API"> <br>
As you can see, the socket server and browsers do not require any specific client library or module, but only JavaScript code to establish a WebSocket connection on a client browser.</p>
<h3 id="socketio-library">Socket.io Library</h3>
<p>Socket.IO aims to provide an emulation layer that will <strong>use the native WebSocket implementation in browsers that support it</strong>, reverting to other methods (such as long-polling) to simulate the native API in browsers that don’t. </p>
<p>Unlike the native WebSocket API implementation, Socket.IO requires a custom <code>socket.io.js</code> client library on client browsers, and an identical <code>socket.io</code> module on the Node.js server:</p>
<p><img src="https://lh5.googleusercontent.com/unfpPe6OC4zzXxe89VXn0Sbmp5uQBifvTx6illIno-OofyFXm-PmMYXe5gGaokGLcu7VCJjB_koRspcneTHfjuMct9yhk_YiwX4XaLCY6O13vKzHGsQ0A8RkB_oYhzmrzFM" alt="Socket.io Web App Schematic" title="Socket.io Web App Schematic"></p>
<h3 id="evaluation-of-sockets">Evaluation of Sockets</h3>
<table>
<thead>
<tr>
<th>Pros</th>
<th>Cons</th>
</tr>
</thead>
<tbody><tr>
<td>Rapid bidirectional communication essential to realtime games, along with collaborative editing tools and other applications</td>
<td>The number of allowed persistent socket connections can be limited on the server side</td>
</tr>
<tr>
<td>Lower overhead than standard HTTP protocol request</td>
<td>If browser does not natively support WebSocket, emulation libraries such as Socket.IO resort to long-polling or other inefficient techniques</td>
</tr>
<tr>
<td>-</td>
<td>Requires a custom protocol server, and often a custom client library</td>
</tr>
<tr>
<td>-</td>
<td>Many proxies and reverse-proxies are known to confound socket implementations, leading to lost clients</td>
</tr>
</tbody></table>
<h2 id="game-implementation">Game Implementation</h2>
<h3 id="phaserio">Phaser.io</h3>
<p>Phaser.io is a desktop and mobile HTML game framework. It is a free open source framework that is powered by Canvas and WebGL. </p>
<p>Our Phaser games are organised around states. Phaser supports game states, which allows us to break our game up into smaller pieces that can handle different mechanics of the game. The states employed in our game are as follows, where each mini-game has the same composite state machine <em>“Game n”</em>, where <em>n</em> is the game’s ID:</p>
<h3 id="state-diagram">State Diagram</h3>
<p><img src="https://github.com/christabella/freewee/blob/master/assets/Report/Freewee%20Phaser%20Game%20State%20Machine.png?raw=true" alt="enter image description here" title="Phaser Game State Machine Diagram"></p>
<p>The state diagram shows the logical flow of events. </p>
<h4 id="initial-state">Initial State</h4>
<p>The initial state is handled by <code>main.js</code>. We initialise our game here using the global Phaser object and create a new game instance. We also add the various states to the game. </p>
<pre class="prettyprint"><code class=" hljs r">var game;
game = new Phaser.Game(screen.availWidth,screen.availHeight, Phaser.AUTO, null);
game.state.add(<span class="hljs-string">'Lobby'</span>, Lobby);
// Game <span class="hljs-number">1</span>
game.state.add(<span class="hljs-string">'SumoBoot'</span>, SumoBoot);
game.state.add(<span class="hljs-string">'SumoPreload'</span>, SumoPreload);
game.state.add(<span class="hljs-string">'SumoMenu'</span>, SumoMenu);
game.state.add(<span class="hljs-string">'SumoGame'</span>, SumoGame);
game.state.add(<span class="hljs-string">'SumoGameOver'</span>, SumoGameOver);
// Game <span class="hljs-number">2</span>
// <span class="hljs-keyword">...</span>
// Game <span class="hljs-number">3</span>
// <span class="hljs-keyword">...</span>
game.state.start(<span class="hljs-string">'Lobby'</span>);</code></pre>
<h4 id="lobby-state">Lobby State</h4>
<p>In <code>lobby.js</code>, either a game is selected or the session is ended. If a game is selected, Lobby State will call the Boot State of the selected game.</p>
<h4 id="boot-state">Boot State</h4>
<p>Boot State is handled by <code>boot.js</code>. This screen loads the instructions and calls the Preload State.</p>
<h4 id="preload-state">Preload State</h4>
<p>Preload State is handled by <code>preload.js</code>. This preloads all the assets, background music, spritesheets, audio into the game. Once done, mouse click will bring it to the Menu State.</p>
<h4 id="menu-state">Menu State</h4>
<p>Menu State is handled by <code>menu.js</code>. We display the game name and simple animation to introduce the game. When a mouse click is registered, it will call the Game State.</p>
<h4 id="game-state">Game State</h4>
<p>Game State is handled by <code>game.js</code>. We implement the actual game logic here. When a player wins, we call the Game Over state. </p>
<h4 id="game-over-state">Game Over State</h4>
<p>Game Over state is handled by <code>gameover.js</code>. It will display the game over screen. Upon mouse click, it will return to Lobby State. </p>
<h2 id="client-side-device-sensors">Client-Side Device Sensors</h2>
<p>Our game aims to explore the various uses of sensors in our mobile devices. Some of the sensors exposed by the HTML5 Javascript API that our group employed are: </p>
<h3 id="deviceorientationevent">DeviceOrientationEvent</h3>
<p>DeviceOrientationEvent returns the alpha, beta and gamma values of the device’s orientation obtained from the device’s gyroscope. <br>
<img src="http://www.html5rocks.com/en/tutorials/device/orientation/rotation.png" alt="Device Orientation" title=""> <br>
Alpha refers to the direction the device is facing according to the compass. <br>
Beta refers to the angle in degrees the device is tilted front-to-back <br>
Gamma refers to the angle in degrees the device is tilted left-to-right.</p>
<p>We used the gamma values to move the player left and right in the Run Sumo Run! game.</p>
<p>The following code snippet is from <code>synchronizer-client.js</code>, the <strong>client-side script responsible for communication between players</strong> <em>(on phones/tablets)</em> <strong>and their respective game screens</strong> <em>(on *computers/tablets)</em>. It allows us to track the the DeviceOrientationEvents from different hosts. We can now fetch individual device orientation data from different devices. </p>
<pre class="prettyprint"><code class=" hljs mel"><span class="hljs-keyword">if</span> (<span class="hljs-keyword">window</span>.DeviceOrientationEvent) {
var options = {
alphaThreshold: <span class="hljs-number">5</span>,
betaThreshold: <span class="hljs-number">5</span>,
gammaThreshold: <span class="hljs-number">5</span>,
yThreshold: <span class="hljs-number">0</span>
};
_instance.prevOrientation = {
alpha: <span class="hljs-number">0</span>,
beta: <span class="hljs-number">0</span>,
<span class="hljs-keyword">gamma</span>: <span class="hljs-number">0</span>
};
_instance.prevMotion = {
y: <span class="hljs-number">0</span>,
};