menu_main.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /******************************
  2. * This file holds game states.
  3. ******************************/
  4. /** [MAIN MENU STATE] Screen where the user can select a game.
  5. *
  6. * @namespace
  7. */
  8. const menuState = {
  9. /**
  10. * Main code
  11. */
  12. create: function () {
  13. // FOR MOODLE
  14. if (moodle && iLMparameters.iLM_PARAM_SendAnswer == 'false') {
  15. // Student role
  16. playerName = game.lang.student; // TODO pegar o nome do aluno no bd do moodle
  17. try {
  18. getiLMContent();
  19. } catch (error) {
  20. console.error(
  21. 'Game error: Could not load the iLM Content on Moodle. ' + error
  22. );
  23. }
  24. } else {
  25. // FOR MOODLE
  26. if (moodle && iLMparameters.iLM_PARAM_SendAnswer == 'true') {
  27. playerName = game.lang.professor;
  28. } else {
  29. // reset game values
  30. gameId = null;
  31. gameMode = null;
  32. gameOperation = null;
  33. gameDifficulty = null;
  34. showFractions = true;
  35. }
  36. renderBackground();
  37. // Overtitle: Welcome, <player name>!
  38. game.add.text(
  39. context.canvas.width / 2,
  40. 60,
  41. game.lang.welcome + ', ' + playerName + '!',
  42. { ...textStyles.h3_, fill: colors.maroon }
  43. );
  44. // Title : Select a game
  45. game.add.text(context.canvas.width / 2, 120, game.lang.menu_title, {
  46. ...textStyles.h1_,
  47. fill: colors.green,
  48. });
  49. // Subtitle : <game mode>
  50. this.lbl_game = game.add.text(
  51. context.canvas.width / 2,
  52. 170,
  53. '',
  54. textStyles.h2_
  55. );
  56. // Loads navigation icons
  57. navigation.add.right(['audio', 'lang']);
  58. this.menuIcons = [];
  59. // --------------------------- GAME ICONS
  60. const offset = game.math.getOffset(context.canvas.width, gameList.length);
  61. for (let i = 0, x = offset; i < gameList.length; i++, x += offset) {
  62. const icon = game.add.image(
  63. x,
  64. context.canvas.height / 2 - 70,
  65. gameList[i].assets.menu.gameNameBtn,
  66. 1.5
  67. );
  68. icon.anchor(0.5, 0.5);
  69. icon.gameId = i;
  70. icon.iconType = 'game';
  71. this.menuIcons.push(icon);
  72. // "more information" button
  73. const infoIcon = game.add.image(
  74. x + 110,
  75. context.canvas.height / 2 - 100 - 80 - 10,
  76. 'info',
  77. 0.8,
  78. 0.6
  79. );
  80. infoIcon.anchor(0.5, 0.5);
  81. infoIcon.iconType = 'infoIcon';
  82. infoIcon.id = i;
  83. this.menuIcons.push(infoIcon);
  84. }
  85. // --------------------------- INFO BOX
  86. this.setInfoBoxes();
  87. // ------------- EVENTS
  88. game.event.add('click', this.onInputDown);
  89. game.event.add('mousemove', this.onInputOver);
  90. if (isDebugMode && debugState.menu.skip) {
  91. // programmatically select a game
  92. const id = debugState.menu.id;
  93. gameId = id;
  94. gameName = gameList[id].gameName;
  95. gameShape = gameList[id].gameShape;
  96. audioStatus = debugState.menu.audioStatus || false;
  97. self.menuIcons =
  98. game.lang[gameShape] + ' ' + gameName.slice(-3) == 'One' ? 'I' : 'II';
  99. game.state.start('customMenu');
  100. }
  101. }
  102. },
  103. setInfoBoxes: function () {
  104. self.infoBox = document.querySelector('.ifr-modal');
  105. // When the user clicks on the 'x', close the modal
  106. document.querySelector('.ifr-modal__closeButton').onclick = function () {
  107. self.infoBox.style.display = 'none';
  108. };
  109. // When the user clicks anywhere outside of the modal, close it
  110. window.onclick = function (event) {
  111. if (event.target == self.infoBox) {
  112. self.infoBox.style.display = 'none';
  113. }
  114. };
  115. },
  116. /**
  117. * Displays game menu information boxes.
  118. */
  119. showInfoBox: function (icon) {
  120. if (
  121. gameList[icon.id] &&
  122. gameList[icon.id].assets &&
  123. gameList[icon.id].assets.menu &&
  124. gameList[icon.id].assets.menu.infoBox
  125. ) {
  126. self.infoBox.style.display = 'block';
  127. const data = gameList[icon.id].assets.menu.infoBox();
  128. const content = `<h3>${data.title}</h3>
  129. <p>${data.body}</p>
  130. ${data.img}`;
  131. document.querySelector('.ifr-modal__infobox').innerHTML = content;
  132. } else {
  133. console.error('Error: no info box was setup for this game.');
  134. }
  135. },
  136. /**
  137. * Saves info from selected game and goes to next state
  138. *
  139. * @param {object} icon clicked icon
  140. */
  141. load: function (icon) {
  142. if (audioStatus) game.audio.popSound.play();
  143. switch (icon.iconType) {
  144. case 'infoIcon':
  145. self.showInfoBox(icon);
  146. break;
  147. case 'game':
  148. gameId = icon.gameId;
  149. gameName = gameList[gameId].gameName;
  150. gameShape = gameList[gameId].gameShape;
  151. if (!gameList.find((game) => game.gameName === gameName))
  152. console.error('Game error: the name of the game is not valid.');
  153. if (isDebugMode) console.log('Game Name: ' + gameName);
  154. self.menuIcons = self.lbl_game.name;
  155. game.state.start('customMenu');
  156. break;
  157. }
  158. },
  159. /**
  160. * Display the name of the game on screen
  161. *
  162. * @param {object} icon icon for the game
  163. */
  164. showTitle: function (icon) {
  165. const number =
  166. gameList[icon.gameId].gameName.slice(-3) == 'One' ? 'I' : 'II';
  167. const shape = gameList[icon.gameId].gameName.slice(0, -3);
  168. self.lbl_game.name = game.lang[shape] + ' ' + number;
  169. },
  170. /**
  171. * Remove the name of the game from screen
  172. */
  173. clearTitle: function () {
  174. self.lbl_game.name = '';
  175. },
  176. /**
  177. * Called by mouse click event
  178. *
  179. * @param {object} mouseEvent contains the mouse click coordinates
  180. */
  181. onInputDown: function (mouseEvent) {
  182. const x = game.math.getMouse(mouseEvent).x;
  183. const y = game.math.getMouse(mouseEvent).y;
  184. // Check menu icons
  185. for (let i in self.menuIcons) {
  186. // If mouse is within the bounds of an icon
  187. if (game.math.isOverIcon(x, y, self.menuIcons[i])) {
  188. // Click first valid icon
  189. self.load(self.menuIcons[i]);
  190. break;
  191. }
  192. }
  193. // Check navigation icons
  194. navigation.onInputDown(x, y);
  195. game.render.all();
  196. },
  197. /**
  198. * Called by mouse move event
  199. *
  200. * @param {object} mouseEvent contains the mouse move coordinates
  201. */
  202. onInputOver: function (mouseEvent) {
  203. const x = game.math.getMouse(mouseEvent).x;
  204. const y = game.math.getMouse(mouseEvent).y;
  205. let overIcon;
  206. // Check menu icons
  207. for (let i in self.menuIcons) {
  208. if (game.math.isOverIcon(x, y, self.menuIcons[i])) {
  209. overIcon = i;
  210. break;
  211. }
  212. }
  213. // Update gui
  214. if (overIcon) {
  215. // If pointer is over icon
  216. document.body.style.cursor = 'pointer';
  217. if (self.menuIcons[overIcon].iconType == 'game')
  218. self.showTitle(self.menuIcons[overIcon]);
  219. self.menuIcons.forEach((cur) => {
  220. if (cur.iconType == self.menuIcons[overIcon].iconType) {
  221. // If its in the same icon category
  222. if (cur == self.menuIcons[overIcon]) {
  223. // If its the icon the pointer is over
  224. cur.scale = cur.initialScale * 1.1;
  225. } else {
  226. cur.scale = cur.initialScale;
  227. }
  228. }
  229. });
  230. } else {
  231. // If pointer is not over icon
  232. self.clearTitle();
  233. self.menuIcons.forEach((cur) => {
  234. cur.scale = cur.initialScale;
  235. });
  236. document.body.style.cursor = 'auto';
  237. }
  238. // Check navigation icons
  239. navigation.onInputOver(x, y);
  240. game.render.all();
  241. },
  242. };