menu_main.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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. infoIcon.description = 'info_description';
  84. this.menuIcons.push(infoIcon);
  85. }
  86. // --------------------------- INFO BOX
  87. this.setInfoBoxes();
  88. // ------------- EVENTS
  89. game.event.add('click', this.onInputDown);
  90. game.event.add('mousemove', this.onInputOver);
  91. if (isDebugMode && debugState.menu.skip) {
  92. // programmatically select a game
  93. const id = debugState.menu.id;
  94. gameId = id;
  95. gameName = gameList[id].gameName;
  96. gameShape = gameList[id].gameShape;
  97. audioStatus = debugState.menu.audioStatus || false;
  98. self.menuIcons =
  99. game.lang[gameShape] + ' ' + gameName.slice(-3) == 'One' ? 'I' : 'II';
  100. game.state.start('customMenu');
  101. }
  102. }
  103. },
  104. setInfoBoxes: function () {
  105. self.infoBox = document.querySelector('.ifr-modal');
  106. // When the user clicks on the 'x', close the modal
  107. document.querySelector('.ifr-modal__closeButton').onclick = function () {
  108. self.infoBox.style.display = 'none';
  109. };
  110. // When the user clicks anywhere outside of the modal, close it
  111. window.onclick = function (event) {
  112. if (event.target == self.infoBox) {
  113. self.infoBox.style.display = 'none';
  114. }
  115. };
  116. },
  117. /**
  118. * Displays game menu information boxes.
  119. */
  120. showInfoBox: function (icon) {
  121. if (
  122. gameList[icon.id] &&
  123. gameList[icon.id].assets &&
  124. gameList[icon.id].assets.menu &&
  125. gameList[icon.id].assets.menu.infoBox
  126. ) {
  127. self.infoBox.style.display = 'block';
  128. const data = gameList[icon.id].assets.menu.infoBox();
  129. const content = `<h3>${data.title}</h3>
  130. <p>${data.body}</p>
  131. ${data.img}`;
  132. document.querySelector('.ifr-modal__infobox').innerHTML = content;
  133. } else {
  134. console.error('Error: no info box was setup for this game.');
  135. }
  136. },
  137. /**
  138. * Saves info from selected game and goes to next state
  139. *
  140. * @param {object} icon clicked icon
  141. */
  142. load: function (icon) {
  143. if (audioStatus) game.audio.popSound.play();
  144. switch (icon.iconType) {
  145. case 'infoIcon':
  146. self.showInfoBox(icon);
  147. break;
  148. case 'game':
  149. gameId = icon.gameId;
  150. gameName = gameList[gameId].gameName;
  151. gameShape = gameList[gameId].gameShape;
  152. if (!gameList.find((game) => game.gameName === gameName))
  153. console.error('Game error: the name of the game is not valid.');
  154. if (isDebugMode) console.log('Game Name: ' + gameName);
  155. self.menuIcons = self.lbl_game.name;
  156. game.state.start('customMenu');
  157. break;
  158. }
  159. },
  160. /**
  161. * Display the name of the game on screen
  162. *
  163. * @param {object} icon icon for the game
  164. */
  165. showTitle: function (icon) {
  166. if (icon.iconType === 'game') {
  167. const number =
  168. gameList[icon.gameId].gameName.slice(-3) == 'One' ? 'I' : 'II';
  169. const shape = gameList[icon.gameId].gameName.slice(0, -3);
  170. self.lbl_game.name = game.lang[shape] + ' ' + number;
  171. } else if (icon.iconType === 'infoIcon')
  172. self.lbl_game.name = game.lang.info_description;
  173. },
  174. /**
  175. * Remove the name of the game from screen
  176. */
  177. clearTitle: function () {
  178. self.lbl_game.name = '';
  179. },
  180. /**
  181. * Called by mouse click event
  182. *
  183. * @param {object} mouseEvent contains the mouse click coordinates
  184. */
  185. onInputDown: function (mouseEvent) {
  186. const x = game.math.getMouse(mouseEvent).x;
  187. const y = game.math.getMouse(mouseEvent).y;
  188. // Check menu icons
  189. for (let i in self.menuIcons) {
  190. // If mouse is within the bounds of an icon
  191. if (game.math.isOverIcon(x, y, self.menuIcons[i])) {
  192. // Click first valid icon
  193. self.load(self.menuIcons[i]);
  194. break;
  195. }
  196. }
  197. // Check navigation icons
  198. navigation.onInputDown(x, y);
  199. game.render.all();
  200. },
  201. /**
  202. * Called by mouse move event
  203. *
  204. * @param {object} mouseEvent contains the mouse move coordinates
  205. */
  206. onInputOver: function (mouseEvent) {
  207. const x = game.math.getMouse(mouseEvent).x;
  208. const y = game.math.getMouse(mouseEvent).y;
  209. let overIcon;
  210. // Check menu icons
  211. for (let i in self.menuIcons) {
  212. if (game.math.isOverIcon(x, y, self.menuIcons[i])) {
  213. overIcon = i;
  214. break;
  215. }
  216. }
  217. // Update gui
  218. if (overIcon) {
  219. // If pointer is over icon
  220. document.body.style.cursor = 'pointer';
  221. if (
  222. self.menuIcons[overIcon].iconType == 'game' ||
  223. self.menuIcons[overIcon].iconType == 'infoIcon'
  224. )
  225. self.showTitle(self.menuIcons[overIcon]);
  226. self.menuIcons.forEach((cur) => {
  227. if (cur.iconType == self.menuIcons[overIcon].iconType) {
  228. // If its in the same icon category
  229. if (cur == self.menuIcons[overIcon]) {
  230. // If its the icon the pointer is over
  231. cur.scale = cur.initialScale * 1.1;
  232. } else {
  233. cur.scale = cur.initialScale;
  234. }
  235. }
  236. });
  237. } else {
  238. // If pointer is not over icon
  239. self.clearTitle();
  240. self.menuIcons.forEach((cur) => {
  241. cur.scale = cur.initialScale;
  242. });
  243. document.body.style.cursor = 'auto';
  244. }
  245. // Check navigation icons
  246. navigation.onInputOver(x, y);
  247. game.render.all();
  248. },
  249. };