globals_functions.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /**
  2. * Manages navigation icons on the top of the screen
  3. * @namespace
  4. */
  5. const navigationIcons = {
  6. /**
  7. * Add navigation icons.<br>
  8. * * The icons on the left are ordered from left to right. <br>
  9. * * The icons on the right are ordered from right to left.
  10. *
  11. * @param {boolean} leftIcon0 1st left icon (back)
  12. * @param {boolean} leftIcon1 2nd left icon (main menu)
  13. * @param {boolean} leftIcon2 3rd left icon (solve game)
  14. * @param {boolean} rightIcon0 1st right icon (audio)
  15. * @param {boolean} rightIcon1 2nd right icon (lang)
  16. * @param {undefined|string} state state to be called by the 'back' button (must exist if param 'leftIcon0' is true)
  17. * @param {undefined|function} help function in the current game state that display correct answer
  18. */
  19. add: function (
  20. leftIcon0,
  21. leftIcon1,
  22. leftIcon2,
  23. rightIcon0,
  24. rightIcon1,
  25. state,
  26. help
  27. ) {
  28. const iconSize = 75;
  29. let xLeft = 10;
  30. let xRight = context.canvas.width - iconSize - 10;
  31. this.iconsList = [];
  32. // 'Descriptive labels' for the navigation icons
  33. this.left_text = game.add.text(xLeft, 110, '', textStyles.p_brown);
  34. this.left_text.align = 'left';
  35. this.right_text = game.add.text(xRight + 60, 110, '', textStyles.p_brown);
  36. this.right_text.align = 'right';
  37. // Left icons
  38. if (leftIcon0) {
  39. // Return to previous screen
  40. if (!state) {
  41. console.error(
  42. "Game error: You tried to add a 'back' icon without the 'state' parameter."
  43. );
  44. } else {
  45. this.state = state;
  46. this.iconsList.push(game.add.image(xLeft - 5, 10, 'back', 1.5));
  47. xLeft += iconSize;
  48. }
  49. }
  50. if (leftIcon1) {
  51. // Return to main menu screen
  52. this.iconsList.push(game.add.image(xLeft, 10, 'menu', 1.5));
  53. xLeft += iconSize;
  54. }
  55. if (leftIcon2) {
  56. // Shows solution to the game
  57. if (!help) {
  58. console.error(
  59. "Game error: You tried to add a 'game solution' icon without the 'help' parameter."
  60. );
  61. } else {
  62. this.help = help;
  63. this.iconsList.push(game.add.image(xLeft, 10, 'pointer', 1.5));
  64. xLeft += iconSize;
  65. }
  66. }
  67. // Right icons
  68. if (rightIcon0) {
  69. // Turns game audio on/off
  70. this.audioIcon = game.add.sprite(xRight, 10, 'audio', 1, 1.6);
  71. this.audioIcon.curFrame = audioStatus ? 0 : 1;
  72. this.audioIcon.anchor(0.3, 0);
  73. this.iconsList.push(this.audioIcon);
  74. xRight -= iconSize;
  75. }
  76. if (rightIcon1) {
  77. // Return to select language screen
  78. this.iconsList.push(game.add.image(xRight, 10, 'language', 1.5));
  79. this.audioIcon.anchor(0, 0);
  80. xRight -= iconSize;
  81. }
  82. },
  83. /**
  84. * When 'back' icon is clicked go to this state
  85. *
  86. * @param {string} state name of the next state
  87. */
  88. callState: function (state) {
  89. if (audioStatus) game.audio.popSound.play();
  90. game.event.clear(self);
  91. game.state.start(state);
  92. },
  93. /**
  94. * Called by mouse click event
  95. *
  96. * @param {number} x contains the mouse x coordinate
  97. * @param {number} y contains the mouse y coordinate
  98. */
  99. onInputDown: function (x, y) {
  100. navigationIcons.iconsList.forEach((cur) => {
  101. if (game.math.isOverIcon(x, y, cur)) {
  102. const name = cur.name;
  103. switch (name) {
  104. case 'back':
  105. navigationIcons.callState(navigationIcons.state);
  106. break;
  107. case 'menu':
  108. navigationIcons.callState('menu');
  109. break;
  110. case 'help':
  111. navigationIcons.help();
  112. break;
  113. case 'language':
  114. navigationIcons.callState('lang');
  115. break;
  116. case 'audio':
  117. if (audioStatus) {
  118. audioStatus = false;
  119. navigationIcons.audioIcon.curFrame = 1;
  120. } else {
  121. audioStatus = true;
  122. if (audioStatus) game.audio.popSound.play();
  123. navigationIcons.audioIcon.curFrame = 0;
  124. }
  125. game.render.all();
  126. break;
  127. default:
  128. console.error('Game error: error in navigation icon');
  129. }
  130. }
  131. });
  132. },
  133. /**
  134. * Called by mouse move event
  135. *
  136. * @param {number} x contains the mouse x coordinate
  137. * @param {number} y contains the mouse y coordinate
  138. */
  139. onInputOver: function (x, y) {
  140. let flag = false;
  141. navigationIcons.iconsList.forEach((cur) => {
  142. if (game.math.isOverIcon(x, y, cur)) {
  143. flag = true;
  144. let name = cur.name;
  145. switch (name) {
  146. case 'back':
  147. navigationIcons.left_text.name = game.lang.nav_back;
  148. break;
  149. case 'menu':
  150. navigationIcons.left_text.name = game.lang.nav_menu;
  151. break;
  152. case 'help':
  153. navigationIcons.left_text.name = game.lang.nav_help;
  154. break;
  155. case 'language':
  156. navigationIcons.right_text.name = game.lang.nav_lang;
  157. break;
  158. case 'audio':
  159. navigationIcons.right_text.name = game.lang.audio;
  160. break;
  161. }
  162. }
  163. });
  164. if (!flag) {
  165. navigationIcons.left_text.name = '';
  166. navigationIcons.right_text.name = '';
  167. } else {
  168. document.body.style.cursor = 'pointer';
  169. }
  170. },
  171. };
  172. /**
  173. * Sends game information to database
  174. *
  175. * @param {string} extraData player information for the current game
  176. */
  177. const sendToDatabase = function (extraData) {
  178. // FOR MOODLE
  179. if (moodle) {
  180. if (self.result) moodleVar.hits[curMapPosition - 1]++;
  181. else moodleVar.errors[curMapPosition - 1]++;
  182. moodleVar.time[curMapPosition - 1] += game.timer.elapsed;
  183. const url = iLMparameters.iLM_PARAM_ServerToGetAnswerURL;
  184. const grade = '' + getEvaluation();
  185. const report = getAnswer();
  186. const data =
  187. 'return_get_answer=1' +
  188. '&iLM_PARAM_ActivityEvaluation=' +
  189. encodeURIComponent(grade) +
  190. '&iLM_PARAM_ArchiveContent=' +
  191. encodeURIComponent(report);
  192. const init = {
  193. method: 'POST',
  194. body: data,
  195. headers: {
  196. 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  197. },
  198. };
  199. fetch(url, init)
  200. .then((response) => {
  201. if (response.ok) {
  202. if (isDebugMode) console.log('Processing...');
  203. } else {
  204. console.error('Game error: Network response was not ok.');
  205. }
  206. })
  207. .catch((error) => {
  208. console.error(
  209. 'Game error: problem with fetch operation - ' + error.message + '.'
  210. );
  211. });
  212. } else {
  213. // Create some variables we need to send to our PHP file
  214. // Attention: this names must be compactible to data table (MySQL server)
  215. // @see php/save.php
  216. const data =
  217. 'line_ip=143.107.45.11' + // INSERT database server IP
  218. '&line_name=' +
  219. playerName +
  220. '&line_lang=' +
  221. langString +
  222. extraData;
  223. const url = 'php/save.php';
  224. const init = {
  225. method: 'POST',
  226. body: data,
  227. headers: { 'Content-type': 'application/x-www-form-urlencoded' },
  228. };
  229. fetch(url, init)
  230. .then((response) => {
  231. if (response.ok) {
  232. if (isDebugMode) console.log('Processing...');
  233. response.text().then((text) => {
  234. if (isDebugMode) {
  235. console.log(text);
  236. }
  237. });
  238. } else {
  239. console.error('Game error: Network response was not ok.');
  240. }
  241. })
  242. .catch((error) => {
  243. console.error(
  244. 'Game error: problem with fetch operation - ' + error.message + '.'
  245. );
  246. });
  247. }
  248. };
  249. const renderBackground = (type) => {
  250. if (type === 'plain') {
  251. // Add plain blue background
  252. game.add.geom.rect(
  253. 0,
  254. 0,
  255. context.canvas.width,
  256. context.canvas.height,
  257. colors.white,
  258. 0,
  259. colors.blueBg,
  260. 1
  261. );
  262. return;
  263. }
  264. if (type === 'scale') {
  265. // Add background image
  266. game.add.image(0, 0, 'bg_snow', 1.8);
  267. const floor = {
  268. width: 128,
  269. last: context.canvas.width / 128,
  270. tiles: [3, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 4],
  271. };
  272. for (let i = 0; i < floor.tiles.length; i++) {
  273. game.add
  274. .sprite(i * floor.width, context.canvas.height, 'floor_snow', 0, 2)
  275. .anchor(0, 1);
  276. game.add
  277. .sprite(
  278. i * floor.width,
  279. context.canvas.height - 65,
  280. 'floor_snow',
  281. floor.tiles[i],
  282. 2
  283. )
  284. .anchor(0, 1);
  285. }
  286. game.add
  287. .image(-2, context.canvas.height - 410, 'wood_shelf', 2)
  288. .anchor(0, 1);
  289. game.add
  290. .image(-2, context.canvas.height - 650, 'wood_shelf', 2)
  291. .anchor(0, 1);
  292. game.add
  293. .sprite(4 * floor.width, context.canvas.height - 65, 'floor_snow', 7, 2)
  294. .anchor(0, 1);
  295. game.add
  296. .sprite(8 * floor.width, context.canvas.height - 65, 'floor_snow', 8, 2)
  297. .anchor(0, 1);
  298. game.add
  299. .sprite(13 * floor.width, context.canvas.height - 65, 'floor_snow', 7, 2)
  300. .anchor(0, 1);
  301. return;
  302. }
  303. // Add background image
  304. game.add.image(0, 0, 'bg_default', 2.2);
  305. // Add clouds
  306. game.add.image(640, 100, 'cloud', 1.5);
  307. game.add.image(1280, 80, 'cloud', 1.5);
  308. game.add.image(300, 85, 'cloud', 1.2);
  309. // Add floor
  310. for (let i = 0; i < context.canvas.width / 150; i++) {
  311. game.add.image(i * 150, context.canvas.height - 150, 'floor', 1.5);
  312. }
  313. };
  314. const gameFrame = function () {
  315. let x = (y = 300);
  316. let width = context.canvas.width - 2 * x;
  317. let height = context.canvas.height - 2 * y;
  318. let rect = function () {
  319. game.add.geom.rect(x, y, width, height, colors.red, 2);
  320. };
  321. let point = function (offsetW, offsetH) {
  322. for (let i = 0, y1 = y; i < 4; i++) {
  323. x1 = x;
  324. for (let j = 0; j < 7; j++) {
  325. let sqr = game.add.geom.rect(
  326. x1,
  327. y1,
  328. 20,
  329. 20,
  330. undefined,
  331. 0,
  332. colors.red,
  333. 1
  334. );
  335. sqr.anchor(0.5, 0.5);
  336. x1 += offsetW;
  337. }
  338. y1 += offsetH;
  339. }
  340. };
  341. return { x, y, width, height, rect, point };
  342. };
  343. const moveList = function (list, x, y) {
  344. list.forEach((item) => {
  345. item.x += x;
  346. item.y += y;
  347. });
  348. };