globals_control.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  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-5'].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(0, -152, 'kid_running', 0, 1.05);
  422. char.anchor(0.5, 0.5);
  423. return char;
  424. },
  425. building: () =>
  426. game.add
  427. .image(
  428. context.canvas.width - 620,
  429. context.canvas.height - 20 - 15,
  430. 'school',
  431. 1.3
  432. )
  433. .anchor(0, 1),
  434. },
  435. },
  436. },
  437. {
  438. gameName: 'squareTwo',
  439. gameMode: ['a', 'b'],
  440. gameOperation: ['minus'],
  441. gameDifficulty: 5,
  442. // info
  443. gameShape: 'square',
  444. assets: {
  445. menu: {
  446. gameNameBtn: 'game_2',
  447. infoBox: () => ({
  448. title: `<strong>${game.lang.game}:</strong> ${game.lang.square} II`,
  449. body: `<ul>${game.lang.infoBox_squareTwo}</ul>`,
  450. img: `<img class="mx-auto" width=60% src="${game.image['s2'].src}">`,
  451. }),
  452. },
  453. customMenu: {
  454. gameModeBtn: ['mode_4', 'mode_5'],
  455. gameOperationBtn: ['operation_equals'],
  456. gameModeDescription: ['s2_a_description', 's2_b_description'],
  457. gameOperationDescription: ['op_equals_description'],
  458. gameDifficultyDescription: [
  459. 's2_diff_1_description',
  460. 's2_diff_2_description',
  461. 's2_diff_3_description',
  462. 's2_diff_4_description',
  463. 's2_diff_5_description',
  464. ],
  465. gameLabelDescription: 'label_description',
  466. auxiliarTitle: (x, y, offsetW, offsetH) => {
  467. game.add.text(
  468. x + 5 * offsetW,
  469. y + offsetH + 50,
  470. game.lang.show + '\n' + game.lang.title,
  471. textStyles.h4_
  472. );
  473. },
  474. infoBox: () => ({
  475. gameMode: {
  476. title: game.lang.game_modes,
  477. body: `<p>${game.lang.infoBox_mode}</p>`,
  478. img: `<table>
  479. <tr>
  480. <td><b>${game.lang.mode}: A</b> - ${game.lang.infoBox_mode_s2_A}</td>
  481. <td><b>${game.lang.mode}: B</b> - ${game.lang.infoBox_mode_s2_B}</td>
  482. </tr>
  483. <tr>
  484. <td><img width=98% src="${game.image['s2-A-h'].src}"></td>
  485. <td><img width=98% src="${game.image['s2-B-h'].src}"></td>
  486. </tr>
  487. <table>`,
  488. },
  489. gameDifficulty: {
  490. title: game.lang.difficulties,
  491. body: game.lang.infoBox_diff,
  492. img: `<table>
  493. <tr>
  494. <td><b>${game.lang.difficulty}:</b> 1</td>
  495. <td><b>${game.lang.difficulty}:</b> 5</td>
  496. </tr>
  497. <tr>
  498. <td><img width=100% src="${game.image['s2-diff-1'].src}"></td>
  499. <td style="border-left: 4px solid white"><img width=100% src="${game.image['s2-diff-5'].src}"></td>
  500. </tr>
  501. </table>
  502. <br>
  503. ${game.lang.infoBox_diff_aux}
  504. <div><img width=50% src="${game.image['map-c1s2'].src}"></div>`,
  505. },
  506. gameMisc: {
  507. title: `${game.lang.show} ${self.auxText}`,
  508. body: game.lang.infoBox_misc_rect,
  509. img: `<img class="mx-auto" width=100% src="${game.image['s2-label'].src}">`,
  510. },
  511. }),
  512. },
  513. map: {
  514. characterAnimation: (operation) => {
  515. return ['kid', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3];
  516. },
  517. character: (operation) => {
  518. const char = game.add.sprite(
  519. self.scene.roadPoints.x[curMapPosition],
  520. self.scene.roadPoints.y[curMapPosition],
  521. 'kid_running',
  522. 0,
  523. 0.57
  524. );
  525. char.anchor(0, 0.85);
  526. return char;
  527. },
  528. startBuilding: () => {
  529. return game.add.image(
  530. self.scene.roadPoints.x[0] - 193,
  531. self.scene.roadPoints.y[0] - 205,
  532. 'house',
  533. 1.03
  534. );
  535. },
  536. endBuilding: () => {
  537. return game.add.image(
  538. self.scene.roadPoints.x[5] - 28,
  539. self.scene.roadPoints.y[5] - 215,
  540. 'school',
  541. 0.52
  542. );
  543. },
  544. },
  545. end: {
  546. characterAnimation: () => [
  547. 'move',
  548. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
  549. 3,
  550. ],
  551. character: () => {
  552. const char = game.add.sprite(
  553. 0,
  554. context.canvas.height - 240,
  555. 'kid_running',
  556. 0,
  557. 1.05
  558. );
  559. char.anchor(0.5, 0.5);
  560. return char;
  561. },
  562. building: () =>
  563. game.add
  564. .image(
  565. context.canvas.width - 620,
  566. context.canvas.height - 20 - 15,
  567. 'school',
  568. 1.3
  569. )
  570. .anchor(0, 1),
  571. },
  572. },
  573. },
  574. // {
  575. // gameName: 'scaleOne',
  576. // gameMode: ['a'],
  577. // gameOperation: ['plus'],
  578. // gameDifficulty: 1,
  579. // // info
  580. // gameShape: 'noShape',
  581. // assets: {
  582. // menu: {
  583. // gameNameBtn: 'game_3',
  584. // // infoBox
  585. // },
  586. // customMenu: {
  587. // gameModeBtn: ['mode_6'],
  588. // gameOperationBtn: ['operation_equals'],
  589. // auxiliarTitle: (x, y, offsetW, offsetH) => {},
  590. // // infoBox
  591. // },
  592. // map: {
  593. // characterAnimation: (operation) => {
  594. // return operation === 'plus'
  595. // ? ['green_tractor', [0, 1, 2, 3, 4], 3]
  596. // : ['red_tractor', [10, 11, 12, 13, 14], 3];
  597. // },
  598. // character: (operation) => {
  599. // let char;
  600. // if (operation == 'plus') {
  601. // char = game.add.sprite(
  602. // self.scene.roadPoints.x[curMapPosition],
  603. // self.scene.roadPoints.y[curMapPosition],
  604. // 'tractor',
  605. // 0,
  606. // 0.75
  607. // );
  608. // }
  609. // if (operation === 'minus') {
  610. // char = game.add.sprite(
  611. // self.scene.roadPoints.x[curMapPosition],
  612. // self.scene.roadPoints.y[curMapPosition],
  613. // 'tractor',
  614. // 10,
  615. // 0.75
  616. // );
  617. // }
  618. // char.rotate = -30; // 25 counterclockwise
  619. // return char;
  620. // },
  621. // startBuilding: () => {
  622. // return game.add
  623. // .image(self.scene.roadPoints.x[0], self.scene.roadPoints.y[0], 'garage', 0.6)
  624. // .anchor(0.5, 1);
  625. // },
  626. // endBuilding: () => {
  627. // return game.add
  628. // .image(self.scene.roadPoints.x[5], self.scene.roadPoints.y[5], 'farm', 0.9)
  629. // .anchor(0.4, 0.7);
  630. // },
  631. // },
  632. // end: {
  633. // // TODO
  634. // },
  635. // },
  636. // },
  637. ];