globals_control.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  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. gameModeDescription: ['s1_a_description', 's1_b_description'],
  157. gameOperationDescription: [
  158. 'op_plus_description',
  159. 'op_minus_description',
  160. ],
  161. gameDifficultyDescription: [
  162. 'diff_1_description',
  163. 'diff_2_description',
  164. 'diff_3_description',
  165. ],
  166. gameLabelDescription: 'label_description',
  167. auxiliarTitle: (x, y, offsetW, offsetH) => {
  168. game.add.text(
  169. x + 5 * offsetW,
  170. y + offsetH + 50,
  171. game.lang.show + '\n' + game.lang.title,
  172. textStyles.h4_
  173. );
  174. },
  175. infoBox: () => ({
  176. gameMode: {
  177. title: game.lang.game_modes,
  178. body: `<p>${game.lang.infoBox_mode}</p>`,
  179. img: `<table>
  180. <tr>
  181. <td><b>${game.lang.mode}: A</b> - ${game.lang.infoBox_mode_s1_A}</td>
  182. <td><b>${game.lang.mode}: B</b> - ${game.lang.infoBox_mode_s1_B}</td>
  183. </tr>
  184. <tr>
  185. <td><img width=100% src="${game.image['s1-A-h'].src}"></td>
  186. <td><img width=100% src="${game.image['s1-B-h'].src}"></td>
  187. </tr>
  188. <table>`,
  189. },
  190. gameDifficulty: {
  191. title: game.lang.difficulties,
  192. body: `<p>${game.lang.infoBox_diff}</p><p>${game.lang.infoBox_diff_obs}</p>`,
  193. img: `<table>
  194. <tr>
  195. <td><b>${game.lang.difficulty}:</b> 1</td>
  196. <td><b>${game.lang.difficulty}:</b> 3</td>
  197. </tr>
  198. <tr>
  199. <td><img width=100% src="${game.image['s1-diff-1'].src}"></td>
  200. <td style="border-left: 4px solid white"><img width=100% src="${game.image['s1-diff-3'].src}"></td>
  201. </tr>
  202. </table>
  203. <br>
  204. ${game.lang.infoBox_diff_aux}
  205. <div><img width=50% src="${game.image['map-s1'].src}"></div>`,
  206. },
  207. gameMisc: {
  208. title: `${game.lang.show} ${self.auxText}`,
  209. body: game.lang.infoBox_misc_label,
  210. img: `<img class="mx-auto" width=80% src="${game.image['s1-label'].src}">`,
  211. },
  212. }),
  213. },
  214. map: {
  215. characterAnimation: (operation) => {
  216. return operation === 'plus'
  217. ? ['move', [0, 1, 2, 3, 4], 3]
  218. : ['move', [10, 11, 12, 13, 14], 3];
  219. },
  220. character: (operation) => {
  221. let char;
  222. if (operation == 'plus') {
  223. char = game.add.sprite(
  224. self.scene.roadPoints.x[curMapPosition],
  225. self.scene.roadPoints.y[curMapPosition],
  226. 'tractor',
  227. 0,
  228. 0.75
  229. );
  230. }
  231. if (operation === 'minus') {
  232. char = game.add.sprite(
  233. self.scene.roadPoints.x[curMapPosition],
  234. self.scene.roadPoints.y[curMapPosition],
  235. 'tractor',
  236. 10,
  237. 0.75
  238. );
  239. }
  240. char.rotate = -30; // 25 counterclockwise
  241. char.anchor(0.25, 0.5);
  242. return char;
  243. },
  244. startBuilding: () => {
  245. return game.add.image(
  246. self.scene.roadPoints.x[0] - 60,
  247. self.scene.roadPoints.y[0] - 155,
  248. 'garage',
  249. 0.6
  250. );
  251. },
  252. endBuilding: () => {
  253. return game.add.image(
  254. self.scene.roadPoints.x[5] - 10,
  255. self.scene.roadPoints.y[5] - 215,
  256. 'farm',
  257. 0.9
  258. );
  259. },
  260. },
  261. end: {
  262. characterAnimation: () =>
  263. gameOperation === 'plus'
  264. ? ['move', [0, 1, 2, 3, 4], 3]
  265. : ['move', [10, 11, 12, 13, 14], 3],
  266. character: () => {
  267. const char = game.add.sprite(
  268. 0,
  269. context.canvas.height - 170 - 80,
  270. 'tractor',
  271. 0,
  272. 1.05
  273. );
  274. char.anchor(0.5, 0.5);
  275. if (gameOperation === 'minus') char.curFrame = 10;
  276. return char;
  277. },
  278. building: () =>
  279. game.add
  280. .image(
  281. context.canvas.width - 420,
  282. context.canvas.height - 100,
  283. 'farm',
  284. 1.7
  285. )
  286. .anchor(0, 1),
  287. },
  288. },
  289. },
  290. {
  291. gameName: 'circleOne',
  292. gameMode: ['a', 'b'],
  293. gameOperation: ['plus', 'minus', 'mixed'],
  294. gameDifficulty: 3,
  295. // info
  296. gameShape: 'circle',
  297. assets: {
  298. menu: {
  299. gameNameBtn: 'game_1',
  300. infoBox: () => ({
  301. title: `<strong>${game.lang.game}:</strong> ${game.lang.circle} I`,
  302. body: `<ul>${game.lang.infoBox_circleOne}</ul>`,
  303. img: `<img class="mx-auto" width=60% src="${game.image['c1-A'].src}">`,
  304. }),
  305. },
  306. customMenu: {
  307. gameModeBtn: ['mode_2', 'mode_3'],
  308. gameModeDescription: ['c1_a_description', 'c1_b_description'],
  309. gameOperationDescription: [
  310. 'op_plus_description',
  311. 'op_minus_description',
  312. 'op_mixed_description',
  313. ],
  314. gameDifficultyDescription: [
  315. 'diff_1_description',
  316. 'diff_2_description',
  317. 'diff_3_description',
  318. ],
  319. gameLabelDescription: 'label_description',
  320. gameOperationBtn: [
  321. 'operation_plus',
  322. 'operation_minus',
  323. 'operation_mixed',
  324. ],
  325. auxiliarTitle: (x, y, offsetW, offsetH) => {
  326. game.add.text(
  327. x + 5 * offsetW,
  328. y + offsetH + 50,
  329. game.lang.show + '\n' + game.lang.title,
  330. textStyles.h4_
  331. );
  332. },
  333. infoBox: () => ({
  334. gameMode: {
  335. title: game.lang.game_modes,
  336. body: `<p>${game.lang.infoBox_mode}</p>`,
  337. img: `<table>
  338. <tr style="border-bottom: 5px solid white">
  339. <td width=70%>
  340. <img width=100% src=${game.image['c1-A-h'].src}>
  341. </td>
  342. <td>&nbsp;<b>${game.lang.mode}: A</b> - ${game.lang.infoBox_mode_c1_A}</td>
  343. </tr>
  344. <tr>
  345. <td><img width=100% src=${game.image['c1-B-h'].src}></td>
  346. <td>&nbsp;<b>${game.lang.mode}: B</b> - ${game.lang.infoBox_mode_c1_B}</td>
  347. </tr>
  348. </table>`,
  349. },
  350. gameDifficulty: {
  351. title: game.lang.difficulties,
  352. body: `<p>${game.lang.infoBox_diff}</p><p>${game.lang.infoBox_diff_obs}</p>`,
  353. img: `<table>
  354. <tr>
  355. <td style="border-right: 4px solid white">
  356. <b>${game.lang.difficulty}:</b> 1
  357. </td>
  358. <td>
  359. <b>${game.lang.difficulty}:</b> 5
  360. </td>
  361. </tr>
  362. <tr>
  363. <td>
  364. <img width=100% src="${game.image['c1-diff-1'].src}">
  365. </td>
  366. <td style="border-left: 4px solid white">
  367. <img width=100% src="${game.image['c1-diff-3'].src}">
  368. </td>
  369. </tr>
  370. </table>
  371. <br>
  372. ${game.lang.infoBox_diff_aux}
  373. <div><img width=50% src="${game.image['map-c1s2'].src}"></div>`,
  374. },
  375. gameMisc: {
  376. title: `${game.lang.show} ${self.auxText}`,
  377. body: game.lang.infoBox_misc_label,
  378. img: `<img class="mx-auto" width=60% src="${game.image['c1-label'].src}">`,
  379. },
  380. }),
  381. },
  382. map: {
  383. characterAnimation: (operation) => {
  384. return ['kid', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3];
  385. },
  386. character: (operation) => {
  387. const char = game.add.sprite(
  388. self.scene.roadPoints.x[curMapPosition],
  389. self.scene.roadPoints.y[curMapPosition],
  390. 'kid_running',
  391. 0,
  392. 0.57
  393. );
  394. char.anchor(0, 0.85);
  395. return char;
  396. },
  397. startBuilding: () => {
  398. return game.add.image(
  399. self.scene.roadPoints.x[0] - 193,
  400. self.scene.roadPoints.y[0] - 205,
  401. 'house',
  402. 1.03
  403. );
  404. },
  405. endBuilding: () => {
  406. return game.add.image(
  407. self.scene.roadPoints.x[5] - 28,
  408. self.scene.roadPoints.y[5] - 215,
  409. 'school',
  410. 0.52
  411. );
  412. },
  413. },
  414. end: {
  415. characterAnimation: () => [
  416. 'move',
  417. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
  418. 3,
  419. ],
  420. character: () => {
  421. const char = game.add.sprite(
  422. 0,
  423. context.canvas.height - 240,
  424. 'kid_running',
  425. 0,
  426. 1.05
  427. );
  428. char.anchor(0.5, 0.5);
  429. return char;
  430. },
  431. building: () =>
  432. game.add
  433. .image(
  434. context.canvas.width - 620,
  435. context.canvas.height - 20 - 15,
  436. 'school',
  437. 1.3
  438. )
  439. .anchor(0, 1),
  440. },
  441. },
  442. },
  443. {
  444. gameName: 'squareTwo',
  445. gameMode: ['a', 'b'],
  446. gameOperation: ['minus'],
  447. gameDifficulty: 5,
  448. // info
  449. gameShape: 'square',
  450. assets: {
  451. menu: {
  452. gameNameBtn: 'game_2',
  453. infoBox: () => ({
  454. title: `<strong>${game.lang.game}:</strong> ${game.lang.square} II`,
  455. body: `<ul>${game.lang.infoBox_squareTwo}</ul>`,
  456. img: `<img class="mx-auto" width=60% src="${game.image['s2'].src}">`,
  457. }),
  458. },
  459. customMenu: {
  460. gameModeBtn: ['mode_4', 'mode_5'],
  461. gameOperationBtn: ['operation_equals'],
  462. gameModeDescription: ['s2_a_description', 's2_b_description'],
  463. gameOperationDescription: ['op_equals_description'],
  464. gameDifficultyDescription: [
  465. 's2_diff_1_description',
  466. 's2_diff_2_description',
  467. 's2_diff_3_description',
  468. 's2_diff_4_description',
  469. 's2_diff_5_description',
  470. ],
  471. gameLabelDescription: 'label_description',
  472. auxiliarTitle: (x, y, offsetW, offsetH) => {
  473. game.add.text(
  474. x + 5 * offsetW,
  475. y + offsetH + 50,
  476. game.lang.show + '\n' + game.lang.title,
  477. textStyles.h4_
  478. );
  479. },
  480. infoBox: () => ({
  481. gameMode: {
  482. title: game.lang.game_modes,
  483. body: `<p>${game.lang.infoBox_mode}</p>`,
  484. img: `<table>
  485. <tr>
  486. <td><b>${game.lang.mode}: A</b> - ${game.lang.infoBox_mode_s2_A}</td>
  487. <td><b>${game.lang.mode}: B</b> - ${game.lang.infoBox_mode_s2_B}</td>
  488. </tr>
  489. <tr>
  490. <td><img width=98% src="${game.image['s2-A-h'].src}"></td>
  491. <td><img width=98% src="${game.image['s2-B-h'].src}"></td>
  492. </tr>
  493. <table>`,
  494. },
  495. gameDifficulty: {
  496. title: game.lang.difficulties,
  497. body: game.lang.infoBox_diff,
  498. img: `<table>
  499. <tr>
  500. <td><b>${game.lang.difficulty}:</b> 1</td>
  501. <td><b>${game.lang.difficulty}:</b> 5</td>
  502. </tr>
  503. <tr>
  504. <td><img width=100% src="${game.image['s2-diff-1'].src}"></td>
  505. <td style="border-left: 4px solid white"><img width=100% src="${game.image['s2-diff-5'].src}"></td>
  506. </tr>
  507. </table>
  508. <br>
  509. ${game.lang.infoBox_diff_aux}
  510. <div><img width=50% src="${game.image['map-c1s2'].src}"></div>`,
  511. },
  512. gameMisc: {
  513. title: `${game.lang.show} ${self.auxText}`,
  514. body: game.lang.infoBox_misc_rect,
  515. img: `<img class="mx-auto" width=100% src="${game.image['s2-label'].src}">`,
  516. },
  517. }),
  518. },
  519. map: {
  520. characterAnimation: (operation) => {
  521. return ['kid', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3];
  522. },
  523. character: (operation) => {
  524. const char = game.add.sprite(
  525. self.scene.roadPoints.x[curMapPosition],
  526. self.scene.roadPoints.y[curMapPosition],
  527. 'kid_running',
  528. 0,
  529. 0.57
  530. );
  531. char.anchor(0, 0.85);
  532. return char;
  533. },
  534. startBuilding: () => {
  535. return game.add.image(
  536. self.scene.roadPoints.x[0] - 193,
  537. self.scene.roadPoints.y[0] - 205,
  538. 'house',
  539. 1.03
  540. );
  541. },
  542. endBuilding: () => {
  543. return game.add.image(
  544. self.scene.roadPoints.x[5] - 28,
  545. self.scene.roadPoints.y[5] - 215,
  546. 'school',
  547. 0.52
  548. );
  549. },
  550. },
  551. end: {
  552. characterAnimation: () => [
  553. 'move',
  554. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
  555. 3,
  556. ],
  557. character: () => {
  558. const char = game.add.sprite(
  559. 0,
  560. context.canvas.height - 240,
  561. 'kid_running',
  562. 0,
  563. 1.05
  564. );
  565. char.anchor(0.5, 0.5);
  566. return char;
  567. },
  568. building: () =>
  569. game.add
  570. .image(
  571. context.canvas.width - 620,
  572. context.canvas.height - 20 - 15,
  573. 'school',
  574. 1.3
  575. )
  576. .anchor(0, 1),
  577. },
  578. },
  579. },
  580. // {
  581. // gameName: 'scaleOne',
  582. // gameMode: ['a'],
  583. // gameOperation: ['plus'],
  584. // gameDifficulty: 1,
  585. // // info
  586. // gameShape: 'noShape',
  587. // assets: {
  588. // menu: {
  589. // gameNameBtn: 'game_3',
  590. // // infoBox
  591. // },
  592. // customMenu: {
  593. // gameModeBtn: ['mode_6'],
  594. // gameOperationBtn: ['operation_equals'],
  595. // auxiliarTitle: (x, y, offsetW, offsetH) => {},
  596. // // infoBox
  597. // },
  598. // map: {
  599. // characterAnimation: (operation) => {
  600. // return operation === 'plus'
  601. // ? ['green_tractor', [0, 1, 2, 3, 4], 3]
  602. // : ['red_tractor', [10, 11, 12, 13, 14], 3];
  603. // },
  604. // character: (operation) => {
  605. // let char;
  606. // if (operation == 'plus') {
  607. // char = game.add.sprite(
  608. // self.scene.roadPoints.x[curMapPosition],
  609. // self.scene.roadPoints.y[curMapPosition],
  610. // 'tractor',
  611. // 0,
  612. // 0.75
  613. // );
  614. // }
  615. // if (operation === 'minus') {
  616. // char = game.add.sprite(
  617. // self.scene.roadPoints.x[curMapPosition],
  618. // self.scene.roadPoints.y[curMapPosition],
  619. // 'tractor',
  620. // 10,
  621. // 0.75
  622. // );
  623. // }
  624. // char.rotate = -30; // 25 counterclockwise
  625. // return char;
  626. // },
  627. // startBuilding: () => {
  628. // return game.add
  629. // .image(self.scene.roadPoints.x[0], self.scene.roadPoints.y[0], 'garage', 0.6)
  630. // .anchor(0.5, 1);
  631. // },
  632. // endBuilding: () => {
  633. // return game.add
  634. // .image(self.scene.roadPoints.x[5], self.scene.roadPoints.y[5], 'farm', 0.9)
  635. // .anchor(0.4, 0.7);
  636. // },
  637. // },
  638. // end: {
  639. // // TODO
  640. // },
  641. // },
  642. // },
  643. ];