globals_control.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. /**************************************************************
  2. * LInE - Free Education, Private Data - http://www.usp.br/line
  3. *
  4. * This file holds all global elements to the game.
  5. *
  6. * Generating game levels in menu:
  7. * .....................................................
  8. * ...............square....................circle...... } = gameShape
  9. * .........../...........\....................|........ } = gameName (game)
  10. * ........One.............Two................One....... }
  11. * ......./...\.........../...\............./....\......
  12. * ......a.....b.........a.....b...........a......b..... = gameMode (game mode)
  13. * .(floor)..(stack)..(top)..(bottom)..(floor)..(stack).
  14. * .......\./.............\./................\./........
  15. * ........|...............|..................|.........
  16. * ......./.\..............|................/.|.\.......
  17. * ...plus...minus.......minus........plus.minus.mixed. = gameOperation (game math operation)
  18. * .......\./..............|................\.|./.......
  19. * ........|...............|..................|.........
  20. * ......1,2,3.........1,2,3,4,5............1,2,3,...... = gameDifficulty (difficulty level)
  21. * .....................................................
  22. *
  23. * About levels in map:
  24. *
  25. * ..................(game.levels)......................
  26. * ......................__|__..........................
  27. * .....................|.|.|.|.........................
  28. * ...................0,1,2,3,4,5....................... = curMapPosition (map positions)
  29. * ...................|.........|.......................
  30. * ................(start)....(end).....................
  31. **************************************************************/
  32. /** FOR MOODLE <br>
  33. *
  34. * iFractions can run on a server or inside moodle through iAssign. <br>
  35. * This variable should be set according to where it is suposed to run: <br>
  36. * - if true, on moodle <br>
  37. * - if false, on a server
  38. */
  39. const moodle = false;
  40. let moodleVar = {
  41. hits: [0, 0, 0, 0],
  42. errors: [0, 0, 0, 0],
  43. time: [0, 0, 0, 0],
  44. };
  45. /**
  46. * Index of the current game in gameList array
  47. *
  48. * @type {number}
  49. */
  50. let gameId;
  51. /**
  52. * Selected game name.<br>
  53. * Can be: 'squareOne', 'squareTwo' or 'circleOne'.
  54. *
  55. * @type {string}
  56. */
  57. let gameName;
  58. /**
  59. * Used for text and game information.<br>
  60. * Shape that makes the name of the game - e.g in 'squareOne' it is 'square'.<br>
  61. * Can be: 'circle' or 'square'.
  62. *
  63. * @type {string}
  64. */
  65. let gameShape;
  66. /**
  67. * Holds selected game mode.<br>
  68. * In squareOne/circleOne can be: 'a' (click on the floor) or 'b' (click on the amount to go/stacked figures).<br>
  69. * In squareTwo can be: 'a' (more subdivisions on top) or 'b' (more subdivisions on bottom).
  70. *
  71. * @type {string}
  72. */
  73. let gameMode;
  74. /**
  75. * Holds game math operation.<br>
  76. * In squareOne can be: 'plus' (green tractor goes right) or 'minus' (red tractor goes left).<br>
  77. * In circleOne can be: 'plus' (green tractor goes right), 'minus' (red tractor goes left) or 'mixed' (green tractor goes both sides).<br>
  78. * In squareTwo can be: 'minus' (compares two rectangle subdivisions).
  79. *
  80. * @type {string}
  81. */
  82. let gameOperation;
  83. /**
  84. * Holds game overall difficulty. 1 (easier) -> n (harder).<br>
  85. * In squareOne can be: 1..3.<br>
  86. * In circleOne/squareTwo can be: 1..5.
  87. *
  88. * @type {number}
  89. */
  90. let gameDifficulty;
  91. /**
  92. * Turns displaying the fraction labels on levels ON/OFF
  93. * @type {boolean}
  94. */
  95. let showFractions = true;
  96. /**
  97. * When true, the character can move to next position in the map
  98. * @type {boolean}
  99. */
  100. let canGoToNextMapPosition;
  101. /**
  102. * Character position on the map, aka game levels (1..4: valid; 5: end)
  103. * @type {number}
  104. */
  105. let curMapPosition;
  106. /**
  107. * Number of finished levels in the map
  108. * @type {number}
  109. */
  110. let completedLevels;
  111. /**
  112. * Turns game audio ON/OFF
  113. * @type {boolean}
  114. */
  115. let audioStatus = false;
  116. /**
  117. * Player's name
  118. * @type {string}
  119. */
  120. let playerName;
  121. /**
  122. * String that contains the selected language.<br>
  123. * It is the name of the language file.
  124. * @type {string}
  125. */
  126. let langString;
  127. /**
  128. * Holds the current state.<br>
  129. * Is used as if it was a 'this' inside state functions.
  130. * @type {object}
  131. */
  132. let self;
  133. /**
  134. * Information for all the games
  135. * @type {Array}
  136. */
  137. const gameList = [
  138. {
  139. gameName: 'squareOne',
  140. gameMode: ['a', 'b'],
  141. gameOperation: ['plus', 'minus'],
  142. gameDifficulty: 3,
  143. gameShape: 'square',
  144. assets: {
  145. menu: {
  146. gameNameBtn: 'game_0',
  147. infoBox: () => ({
  148. title: `<strong>${game.lang.game}:</strong> ${game.lang.square} I`,
  149. body: `<ul>${game.lang.infoBox_squareOne}</ul>`,
  150. img: `<img class="ifr-infoBox__menu__img" src="${game.image['s1-A'].src}">`,
  151. }),
  152. },
  153. customMenu: {
  154. gameModeBtn: ['mode_0', 'mode_1'],
  155. gameOperationBtn: ['operation_plus', 'operation_minus'],
  156. auxiliarTitle: (x, y, offsetW, offsetH) => {
  157. game.add.text(
  158. x + 5 * offsetW,
  159. y + offsetH + 50,
  160. game.lang.show + '\n' + game.lang.title,
  161. textStyles.h4_
  162. );
  163. },
  164. infoBox: () => ({
  165. gameMode: {
  166. title: game.lang.game_modes,
  167. body: `<p>${game.lang.infoBox_mode}</p>`,
  168. img: `<table>
  169. <tr>
  170. <td><b>${game.lang.mode}: A</b> - ${game.lang.infoBox_mode_s1_A}</td>
  171. <td><b>${game.lang.mode}: B</b> - ${game.lang.infoBox_mode_s1_B}</td>
  172. </tr>
  173. <tr>
  174. <td><img width=100% src="${game.image['s1-A-h'].src}"></td>
  175. <td><img width=100% src="${game.image['s1-B-h'].src}"></td>
  176. </tr>
  177. <table>`,
  178. },
  179. gameDifficulty: {
  180. title: game.lang.difficulties,
  181. body: `<p>${game.lang.infoBox_diff}</p><p>${game.lang.infoBox_diff_obs}</p>`,
  182. img: `<table>
  183. <tr>
  184. <td><b>${game.lang.difficulty}:</b> 1</td>
  185. <td><b>${game.lang.difficulty}:</b> 3</td>
  186. </tr>
  187. <tr>
  188. <td><img width=100% src="${game.image['s1-diff-1'].src}"></td>
  189. <td style="border-left: 4px solid white"><img width=100% src="${game.image['s1-diff-3'].src}"></td>
  190. </tr>
  191. </table>
  192. <br>
  193. ${game.lang.infoBox_diff_aux}
  194. <div><img width=50% src="${game.image['map-s1'].src}"></div>`,
  195. },
  196. gameMisc: {
  197. title: `${game.lang.show} ${self.auxText}`,
  198. body: game.lang.infoBox_misc_label,
  199. img: `<img class="mx-auto" width=80% src="${game.image['s1-label'].src}">`,
  200. },
  201. }),
  202. },
  203. map: {
  204. characterAnimation: (operation) => {
  205. return operation === 'plus'
  206. ? ['move', [0, 1, 2, 3, 4], 3]
  207. : ['move', [10, 11, 12, 13, 14], 3];
  208. },
  209. character: (operation) => {
  210. let char;
  211. if (operation == 'plus') {
  212. char = game.add.sprite(
  213. self.scene.roadPoints.x[curMapPosition],
  214. self.scene.roadPoints.y[curMapPosition],
  215. 'tractor',
  216. 0,
  217. 0.75
  218. );
  219. }
  220. if (operation === 'minus') {
  221. char = game.add.sprite(
  222. self.scene.roadPoints.x[curMapPosition],
  223. self.scene.roadPoints.y[curMapPosition],
  224. 'tractor',
  225. 10,
  226. 0.75
  227. );
  228. }
  229. char.rotate = -30; // 25 counterclockwise
  230. char.anchor(0.25, 0.5);
  231. return char;
  232. },
  233. startBuilding: () => {
  234. return game.add.image(
  235. self.scene.roadPoints.x[0] - 60,
  236. self.scene.roadPoints.y[0] - 155,
  237. 'garage',
  238. 0.6
  239. );
  240. },
  241. endBuilding: () => {
  242. return game.add.image(
  243. self.scene.roadPoints.x[5] - 10,
  244. self.scene.roadPoints.y[5] - 215,
  245. 'farm',
  246. 0.9
  247. );
  248. },
  249. },
  250. end: {
  251. characterAnimation: () =>
  252. gameOperation === 'plus'
  253. ? ['move', [0, 1, 2, 3, 4], 3]
  254. : ['move', [10, 11, 12, 13, 14], 3],
  255. character: () => {
  256. const char = game.add.sprite(
  257. 0,
  258. context.canvas.height - 170 - 80,
  259. 'tractor',
  260. 0,
  261. 1.05
  262. );
  263. char.anchor(0.5, 0.5);
  264. if (gameOperation === 'minus') char.curFrame = 10;
  265. return char;
  266. },
  267. building: () =>
  268. game.add
  269. .image(
  270. context.canvas.width - 420,
  271. context.canvas.height - 100,
  272. 'farm',
  273. 1.7
  274. )
  275. .anchor(0, 1),
  276. },
  277. },
  278. },
  279. {
  280. gameName: 'circleOne',
  281. gameMode: ['a', 'b'],
  282. gameOperation: ['plus', 'minus', 'mixed'],
  283. gameDifficulty: 3,
  284. // info
  285. gameShape: 'circle',
  286. assets: {
  287. menu: {
  288. gameNameBtn: 'game_1',
  289. infoBox: () => ({
  290. title: `<strong>${game.lang.game}:</strong> ${game.lang.circle} I`,
  291. body: `<ul>${game.lang.infoBox_circleOne}</ul>`,
  292. img: `<img class="mx-auto" width=60% src="${game.image['c1-A'].src}">`,
  293. }),
  294. },
  295. customMenu: {
  296. gameModeBtn: ['mode_2', 'mode_3'],
  297. gameOperationBtn: [
  298. 'operation_plus',
  299. 'operation_minus',
  300. 'operation_mixed',
  301. ],
  302. auxiliarTitle: (x, y, offsetW, offsetH) => {
  303. game.add.text(
  304. x + 5 * offsetW,
  305. y + offsetH + 50,
  306. game.lang.show + '\n' + game.lang.title,
  307. textStyles.h4_
  308. );
  309. },
  310. infoBox: () => ({
  311. gameMode: {
  312. title: game.lang.game_modes,
  313. body: `<p>${game.lang.infoBox_mode}</p>`,
  314. img: `<table>
  315. <tr style="border-bottom: 5px solid white">
  316. <td width=70%>
  317. <img width=100% src=${game.image['c1-A-h'].src}>
  318. </td>
  319. <td>&nbsp;<b>${game.lang.mode}: A</b> - ${game.lang.infoBox_mode_c1_A}</td>
  320. </tr>
  321. <tr>
  322. <td><img width=100% src=${game.image['c1-B-h'].src}></td>
  323. <td>&nbsp;<b>${game.lang.mode}: B</b> - ${game.lang.infoBox_mode_c1_B}</td>
  324. </tr>
  325. </table>`,
  326. },
  327. gameDifficulty: {
  328. title: game.lang.difficulties,
  329. body: `<p>${game.lang.infoBox_diff}</p><p>${game.lang.infoBox_diff_obs}</p>`,
  330. img: `<table>
  331. <tr>
  332. <td style="border-right: 4px solid white">
  333. <b>${game.lang.difficulty}:</b> 1
  334. </td>
  335. <td>
  336. <b>${game.lang.difficulty}:</b> 5
  337. </td>
  338. </tr>
  339. <tr>
  340. <td>
  341. <img width=100% src="${game.image['c1-diff-1'].src}">
  342. </td>
  343. <td style="border-left: 4px solid white">
  344. <img width=100% src="${game.image['c1-diff-5'].src}">
  345. </td>
  346. </tr>
  347. </table>
  348. <br>
  349. ${game.lang.infoBox_diff_aux}
  350. <div><img width=50% src="${game.image['map-c1s2'].src}"></div>`,
  351. },
  352. gameMisc: {
  353. title: `${game.lang.show} ${self.auxText}`,
  354. body: game.lang.infoBox_misc_label,
  355. img: `<img class="mx-auto" width=60% src="${game.image['c1-label'].src}">`,
  356. },
  357. }),
  358. },
  359. map: {
  360. characterAnimation: (operation) => {
  361. return ['kid', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3];
  362. },
  363. character: (operation) => {
  364. const char = game.add.sprite(
  365. self.scene.roadPoints.x[curMapPosition],
  366. self.scene.roadPoints.y[curMapPosition],
  367. 'kid_running',
  368. 0,
  369. 0.57
  370. );
  371. char.anchor(0, 0.85);
  372. return char;
  373. },
  374. startBuilding: () => {
  375. return game.add.image(
  376. self.scene.roadPoints.x[0] - 193,
  377. self.scene.roadPoints.y[0] - 205,
  378. 'house',
  379. 1.03
  380. );
  381. },
  382. endBuilding: () => {
  383. return game.add.image(
  384. self.scene.roadPoints.x[5] - 28,
  385. self.scene.roadPoints.y[5] - 215,
  386. 'school',
  387. 0.52
  388. );
  389. },
  390. },
  391. end: {
  392. characterAnimation: () => [
  393. 'move',
  394. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
  395. 3,
  396. ],
  397. character: () => {
  398. const char = game.add.sprite(0, -152, 'kid_running', 0, 1.05);
  399. char.anchor(0.5, 0.5);
  400. return char;
  401. },
  402. building: () =>
  403. game.add
  404. .image(
  405. context.canvas.width - 620,
  406. context.canvas.height - 20 - 15,
  407. 'school',
  408. 1.3
  409. )
  410. .anchor(0, 1),
  411. },
  412. },
  413. },
  414. {
  415. gameName: 'squareTwo',
  416. gameMode: ['a', 'b'],
  417. gameOperation: ['minus'],
  418. gameDifficulty: 5,
  419. // info
  420. gameShape: 'square',
  421. assets: {
  422. menu: {
  423. gameNameBtn: 'game_2',
  424. infoBox: () => ({
  425. title: `<strong>${game.lang.game}:</strong> ${game.lang.square} II`,
  426. body: `<ul>${game.lang.infoBox_squareTwo}</ul>`,
  427. img: `<img class="mx-auto" width=60% src="${game.image['s2'].src}">`,
  428. }),
  429. },
  430. customMenu: {
  431. gameModeBtn: ['mode_4', 'mode_5'],
  432. gameOperationBtn: ['operation_equals'],
  433. auxiliarTitle: (x, y, offsetW, offsetH) => {
  434. game.add.text(
  435. x + 5 * offsetW,
  436. y + offsetH + 50,
  437. game.lang.show + '\n' + game.lang.aux_rectangle,
  438. textStyles.h4_
  439. );
  440. },
  441. infoBox: () => ({
  442. gameMode: {
  443. title: game.lang.game_modes,
  444. body: `<p>${game.lang.infoBox_mode}</p>`,
  445. img: `<table>
  446. <tr>
  447. <td><b>${game.lang.mode}: A</b> - ${game.lang.infoBox_mode_s2_A}</td>
  448. <td><b>${game.lang.mode}: B</b> - ${game.lang.infoBox_mode_s2_B}</td>
  449. </tr>
  450. <tr>
  451. <td><img width=98% src="${game.image['s2-A-h'].src}"></td>
  452. <td><img width=98% src="${game.image['s2-B-h'].src}"></td>
  453. </tr>
  454. <table>`,
  455. },
  456. gameDifficulty: {
  457. title: game.lang.difficulties,
  458. body: game.lang.infoBox_diff,
  459. img: `<table>
  460. <tr>
  461. <td><b>${game.lang.difficulty}:</b> 1</td>
  462. <td><b>${game.lang.difficulty}:</b> 5</td>
  463. </tr>
  464. <tr>
  465. <td><img width=100% src="${game.image['s2-diff-1'].src}"></td>
  466. <td style="border-left: 4px solid white"><img width=100% src="${game.image['s2-diff-5'].src}"></td>
  467. </tr>
  468. </table>
  469. <br>
  470. ${game.lang.infoBox_diff_aux}
  471. <div><img width=50% src="${game.image['map-c1s2'].src}"></div>`,
  472. },
  473. gameMisc: {
  474. title: `${game.lang.show} ${self.auxText}`,
  475. body: game.lang.infoBox_misc_rect,
  476. img: `<img class="mx-auto" width=100% src="${game.image['s2-label'].src}">`,
  477. },
  478. }),
  479. },
  480. map: {
  481. characterAnimation: (operation) => {
  482. return ['kid', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3];
  483. },
  484. character: (operation) => {
  485. const char = game.add.sprite(
  486. self.scene.roadPoints.x[curMapPosition],
  487. self.scene.roadPoints.y[curMapPosition],
  488. 'kid_running',
  489. 0,
  490. 0.57
  491. );
  492. char.anchor(0, 0.85);
  493. return char;
  494. },
  495. startBuilding: () => {
  496. return game.add.image(
  497. self.scene.roadPoints.x[0] - 193,
  498. self.scene.roadPoints.y[0] - 205,
  499. 'house',
  500. 1.03
  501. );
  502. },
  503. endBuilding: () => {
  504. return game.add.image(
  505. self.scene.roadPoints.x[5] - 28,
  506. self.scene.roadPoints.y[5] - 215,
  507. 'school',
  508. 0.52
  509. );
  510. },
  511. },
  512. end: {
  513. characterAnimation: () => [
  514. 'move',
  515. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
  516. 3,
  517. ],
  518. character: () => {
  519. const char = game.add.sprite(
  520. 0,
  521. context.canvas.height - 240,
  522. 'kid_running',
  523. 0,
  524. 1.05
  525. );
  526. char.anchor(0.5, 0.5);
  527. return char;
  528. },
  529. building: () =>
  530. game.add
  531. .image(
  532. context.canvas.width - 620,
  533. context.canvas.height - 20 - 15,
  534. 'school',
  535. 1.3
  536. )
  537. .anchor(0, 1),
  538. },
  539. },
  540. },
  541. // {
  542. // gameName: 'scaleOne',
  543. // gameMode: ['a'],
  544. // gameOperation: ['plus'],
  545. // gameDifficulty: 1,
  546. // // info
  547. // gameShape: 'noShape',
  548. // assets: {
  549. // menu: {
  550. // gameNameBtn: 'game_3',
  551. // // infoBox
  552. // },
  553. // customMenu: {
  554. // gameModeBtn: ['mode_6'],
  555. // gameOperationBtn: ['operation_equals'],
  556. // auxiliarTitle: (x, y, offsetW, offsetH) => {},
  557. // // infoBox
  558. // },
  559. // map: {
  560. // characterAnimation: (operation) => {
  561. // return operation === 'plus'
  562. // ? ['green_tractor', [0, 1, 2, 3, 4], 3]
  563. // : ['red_tractor', [10, 11, 12, 13, 14], 3];
  564. // },
  565. // character: (operation) => {
  566. // let char;
  567. // if (operation == 'plus') {
  568. // char = game.add.sprite(
  569. // self.scene.roadPoints.x[curMapPosition],
  570. // self.scene.roadPoints.y[curMapPosition],
  571. // 'tractor',
  572. // 0,
  573. // 0.75
  574. // );
  575. // }
  576. // if (operation === 'minus') {
  577. // char = game.add.sprite(
  578. // self.scene.roadPoints.x[curMapPosition],
  579. // self.scene.roadPoints.y[curMapPosition],
  580. // 'tractor',
  581. // 10,
  582. // 0.75
  583. // );
  584. // }
  585. // char.rotate = -30; // 25 counterclockwise
  586. // return char;
  587. // },
  588. // startBuilding: () => {
  589. // return game.add
  590. // .image(self.scene.roadPoints.x[0], self.scene.roadPoints.y[0], 'garage', 0.6)
  591. // .anchor(0.5, 1);
  592. // },
  593. // endBuilding: () => {
  594. // return game.add
  595. // .image(self.scene.roadPoints.x[5], self.scene.roadPoints.y[5], 'farm', 0.9)
  596. // .anchor(0.4, 0.7);
  597. // },
  598. // },
  599. // end: {
  600. // // TODO
  601. // },
  602. // },
  603. // },
  604. ];