squareTwo.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. /*
  2. let gameSquareTwo = {
  3. create: function(){},
  4. update: function(){},
  5. ---------------------------- end of phaser functions
  6. func_overSquare: function(){},
  7. func_outSquare: function(){},
  8. func_clickSquare: function(){},
  9. //func_setPlace: function(){},
  10. //func_checkOverlap: function(){}
  11. func_getRndDivisor: function(){}
  12. //func_viewHelp: function(){},
  13. func_updateCounter: function(){},
  14. func_postScore: function(){},
  15. };
  16. GAME LEVELS - SQUARE III: fraction comparisson level
  17. Name of game state : 'squareTwo'
  18. Shape : square
  19. Character : kid
  20. Theme : (not themed)
  21. Concept : player select equivalent dividends for fractions with different divisors
  22. Represent fractions as : subdivided blocks
  23. # of different difficulties for each level : 5
  24. Level : 'C' (in variable 'levelType')
  25. C : Player selects equivalent fractions of both blocks
  26. Sublevels can be : 'A', 'B' or 'C' (in variable 'sublevelType')
  27. A : equivalence of fractions (with low opacity blocks under the selectable blocks)
  28. top has more subdivisions
  29. B : equivalence of fractions
  30. top has more subdivisions
  31. C : equivalence of fractions
  32. bottom has more subdivisions
  33. */
  34. let gameSquareTwo = {
  35. create: function () {
  36. // CONTROL VARIABLES
  37. self = this;
  38. this.numBlocksA = 0; // Subdivision of top figure (A)
  39. this.numBlocksB = 0; // Subdivision of bottom figure (B)
  40. this.selectedA = 0; // Number of selected blocks for A
  41. this.selectedB = 0; // Number of selected blocks for B
  42. this.hasClickedA = false; // Check if player clicked blocks from A
  43. this.hasClickedB = false; // Check if player clicked blocks from B
  44. this.animateA = false; // Animate blocks from A
  45. this.animateB = false; // Animate blocks from B
  46. this.result = false; // Check if selected blocks are correct
  47. this.ending = null;
  48. this.delay = 0; // Counter used in the animations
  49. this.endDelay = 60; // Maximum value for the counter
  50. // BACKGROUND AND KID
  51. // Add background image
  52. game.add.image(0, 0, 'bgimage');
  53. // Add clouds
  54. game.add.image(300, 100, 'cloud');
  55. game.add.image(660, 80, 'cloud');
  56. game.add.image(110, 85, 'cloud').scale.setTo(0.8);
  57. // Add floor of grass
  58. for (let i = 0; i < 9; i++) { game.add.image(i * 100, 501, 'floor'); }
  59. // Calls function that loads navigation icons
  60. iconSettings.func_addIcons(true, true,
  61. true, true, false,
  62. true, false,
  63. 'difficulty', false);
  64. //Add kid
  65. this.kid = game.add.sprite(100, 470, 'kid_lost');
  66. this.kid.scale.setTo(0.8);
  67. this.kid.anchor.setTo(0.5, 0.7);
  68. this.kid.animations.add('front', [3, 4, 5]);
  69. this.kid.animations.play('front', 6, false); // play kid animation once
  70. // Group of blocks on A and B
  71. this.blocksA = game.add.group();
  72. this.blocksB = game.add.group();
  73. // Group of shadow on bottom of A and B
  74. this.auxBlocksA = game.add.group();
  75. this.auxBlocksB = game.add.group();
  76. // Width and Height of A and B
  77. this.figureWidth = 400;
  78. const figureHeight = 50;
  79. // Coordinates for A and B
  80. let xA, xB, yA, yB;
  81. if (sublevelType != 'C') { // More subdivisions on B
  82. xA = 230;
  83. yA = 90;
  84. xB = xA;
  85. yB = yA + 3 * figureHeight + 30;
  86. } else { // More subdivisions on A
  87. xB = 230;
  88. yB = 90;
  89. xA = xB;
  90. yA = yB + 3 * figureHeight + 30;
  91. }
  92. // Possible points for A
  93. const points = [2, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20];
  94. // Random index for 'points'
  95. const randomIndex = game.rnd.integerInRange((levelDifficulty - 1) * 2 + 1, (levelDifficulty - 1) * 2 + 3);
  96. // number of subdivisions of A and B (blocks)
  97. this.numBlocksA = points[randomIndex];
  98. this.numBlocksB = this.func_getRndDivisor(this.numBlocksA);
  99. if (debugMode) {
  100. console.log("----------");
  101. console.log("Difficulty " + levelDifficulty + ", ini " + ((levelDifficulty - 1) * 2 + 1) + ", end " + ((levelDifficulty - 1) * 2 + 3));
  102. console.log("Rpoint " + randomIndex + ", val " + this.numBlocksA);
  103. console.log("total blocks A " + this.numBlocksA + ", total blocks B ");
  104. }
  105. // CREATING TOP FIGURE (A)
  106. let blockWidth = this.figureWidth / this.numBlocksA; // width of each block in A
  107. let lineColor = colors.darkGreen;
  108. let fillColor = colors.lightGreen;
  109. let fillColorAux = colors.lighterGreen;
  110. // Create blocks
  111. for (let i = 0; i < this.numBlocksA; i++) {
  112. const x = xA + i * blockWidth;
  113. // Blocks
  114. let block = game.add.graphics(x, yA);
  115. block.anchor.setTo(0.5, 0.5);
  116. block.lineStyle(2, lineColor);
  117. block.beginFill(fillColor);
  118. block.drawRect(0, 0, blockWidth, figureHeight);
  119. block.alpha = 0.5;
  120. block.endFill();
  121. block.inputEnabled = true;
  122. block.input.useHandCursor = true;
  123. block.events.onInputDown.add(this.func_clickSquare, { figure: 'A', index: i, xA: xA, xB: xB });
  124. block.events.onInputOver.add(this.func_overSquare, { figure: 'A', index: i, xA: xA, xB: xB });
  125. block.events.onInputOut.add(this.func_outSquare, { figure: 'A', index: i });
  126. this.blocksA.add(block);
  127. // Auxiliar blocks
  128. const yAux = yA + figureHeight + 10; // on the bottom of A
  129. block = game.add.graphics(x, yAux);
  130. block.anchor.setTo(0.5, 0.5);
  131. block.lineStyle(1, lineColor);
  132. block.beginFill(fillColorAux);
  133. block.drawRect(0, 0, blockWidth, figureHeight);
  134. block.alpha = (sublevelType == 'A') ? 0.2 : 0; // Only visible in sublevel A, but used as parameter is all
  135. this.auxBlocksA.add(block);
  136. }
  137. // 'total blocks' label for A : on the side of A
  138. let xLabel = xA + this.figureWidth + 30;
  139. let yLabel = yA + figureHeight / 2;
  140. this.labelA = game.add.text(xLabel, yLabel, this.numBlocksA, textStyles.valueLabelBlue2);
  141. this.labelA.anchor.setTo(0.5, 0.41);
  142. // 'selected blocks/fraction' label for A : at the bottom of A
  143. yLabel = yA + figureHeight + 34;
  144. this.fractionA = game.add.text(xLabel, yLabel, "", textStyles.valueLabelBlue2);
  145. this.fractionA.anchor.setTo(0.5, 0.41);
  146. this.fractionA.alpha = 0;
  147. this.fractionLineA = game.add.sprite(xLabel, yLabel + 3, 'fractionLine');
  148. this.fractionLineA.anchor.setTo(0.5, 0.5);
  149. this.fractionLineA.alpha = 0;
  150. // CREATING BOTTOM FIGURE (B)
  151. blockWidth = this.figureWidth / this.numBlocksB; // width of each block in B
  152. lineColor = colors.darkRed_;
  153. fillColor = colors.lightRed;
  154. fillColorAux = colors.lighterRed;
  155. // Blocks and auxiliar blocks
  156. for (let i = 0; i < this.numBlocksB; i++) {
  157. const x = xB + i * blockWidth;
  158. // Blocks
  159. let block = game.add.graphics(x, yB);
  160. block.anchor.setTo(0.5, 0.5);
  161. block.lineStyle(2, lineColor);
  162. block.beginFill(fillColor);
  163. block.drawRect(0, 0, blockWidth, figureHeight);
  164. block.endFill();
  165. block.inputEnabled = true;
  166. block.input.useHandCursor = true;
  167. block.events.onInputDown.add(this.func_clickSquare, { figure: 'B', index: i, xA: xA, xB: xB });
  168. block.events.onInputOver.add(this.func_overSquare, { figure: 'B', index: i, xA: xA, xB: xB });
  169. block.events.onInputOut.add(this.func_outSquare, { figure: 'B', index: i });
  170. this.blocksB.add(block);
  171. // Auxiliar blocks
  172. let yAux = yB + figureHeight + 10; // on the bottom of B
  173. block = game.add.graphics(x, yAux);
  174. block.anchor.setTo(0.5, 0.5);
  175. block.lineStyle(1, lineColor);
  176. block.beginFill(fillColorAux);
  177. block.drawRect(0, 0, blockWidth, figureHeight);
  178. block.alpha = (sublevelType == 'A') ? 0.2 : 0; // Only visible in sublevel A, but used as parameter is all
  179. this.auxBlocksB.add(block);
  180. }
  181. // Label block B
  182. xLabel = xB + this.figureWidth + 30;
  183. yLabel = yB + figureHeight / 2;
  184. this.labelB = game.add.text(xLabel, yLabel, this.numBlocksB, textStyles.valueLabelBlue2);
  185. this.labelB.anchor.setTo(0.5, 0.41);
  186. // Label fraction
  187. yLabel = yB + figureHeight + 34;
  188. this.fractionB = game.add.text(xLabel, yLabel, "", textStyles.valueLabelBlue2);
  189. this.fractionB.anchor.setTo(0.5, 0.41);
  190. this.fractionB.alpha = 0;
  191. this.fractionLineB = game.add.sprite(xLabel, yLabel + 3, 'fractionLine');
  192. this.fractionLineB.anchor.setTo(0.5, 0.5);
  193. this.fractionLineB.alpha = 0;
  194. // OUTPUT ICONS AND TEXT
  195. // Ok image
  196. this.okImg = game.add.image(game.world.centerX, game.world.centerY, 'h_ok');
  197. this.okImg.anchor.setTo(0.5);
  198. this.okImg.visible = false;
  199. // Error image
  200. this.errorImg = game.add.image(game.world.centerX, game.world.centerY, 'h_error');
  201. this.errorImg.anchor.setTo(0.5);
  202. this.errorImg.visible = false;
  203. // Invalid selection text
  204. this.warningTextA = game.add.text(game.world.centerX, game.world.centerY - 225, "", textStyles.overtitle);
  205. this.warningTextA.anchor.setTo(0.5, 0.5);
  206. this.warningTextB = game.add.text(game.world.centerX, game.world.centerY - 45, "", textStyles.overtitle);
  207. this.warningTextB.anchor.setTo(0.5, 0.5);
  208. // TIMER
  209. // Set a timer for the current level
  210. this.totalTime = 0;
  211. this.timer = game.time.create(false);
  212. this.timer.loop(1000, this.func_updateCounter, this);
  213. this.timer.start();
  214. },
  215. update: function () {
  216. // If clicked A, animate A blocks
  217. if (this.animateA) {
  218. // Lower selected blocks
  219. for (let i = 0; i < this.selectedA; i++) {
  220. this.blocksA.children[i].y += 2;
  221. }
  222. // After fully lowering blocks, set fraction value
  223. if (this.blocksA.children[0].y >= this.auxBlocksA.children[0].y) {
  224. this.fractionA.alpha = 1;
  225. this.fractionA.setText(this.selectedA + "\n" + this.numBlocksA);
  226. this.fractionLineA.alpha = 1;
  227. this.animateA = false;
  228. }
  229. }
  230. // If clicked B, animate B blocks
  231. if (this.animateB) {
  232. // Lower selected blocks
  233. for (let i = 0; i < this.selectedB; i++) {
  234. this.blocksB.children[i].y += 2;
  235. }
  236. // Sets fraction value
  237. if (this.blocksB.children[0].y >= this.auxBlocksB.children[0].y) {
  238. this.fractionB.alpha = 1;
  239. this.fractionB.setText(this.selectedB + "\n" + this.numBlocksB);
  240. this.fractionLineB.alpha = 1;
  241. this.animateB = false;
  242. }
  243. }
  244. // if A and B are already clicked
  245. if (this.hasClickedA && this.hasClickedB && !this.ending) {
  246. this.timer.stop();
  247. // Wait a bit before showing result
  248. this.delay++;
  249. // After delay is over, check result
  250. if (this.delay > this.endDelay) {
  251. // fractions are equivalent : correct
  252. if ((this.selectedA / this.numBlocksA) == (this.selectedB / this.numBlocksB)) {
  253. if (audioStatus) sound.okSound.play();
  254. this.okImg.visible = true;
  255. this.result = true; // player answer is correct
  256. mapCanMove = true; // allow character to move to next level in map state
  257. completedLevels++;
  258. if (debugMode) console.log("completedLevels = " + completedLevels);
  259. // fractions are not equivalent : incorrect
  260. } else {
  261. if (audioStatus) sound.errorSound.play();
  262. this.errorImg.visible = true;
  263. this.result = false; // player answer is incorrect
  264. mapCanMove = false; // doesnt allow character to move to next level in map state
  265. }
  266. this.func_postScore();
  267. this.hasClickedA = false;
  268. this.hasClickedB = false;
  269. // reset delay values for next delay
  270. this.delay = 0;
  271. this.endDelay = 100;
  272. this.ending = true;
  273. }
  274. }
  275. // Wait a bit and go to map state
  276. if (this.ending) {
  277. this.delay++;
  278. if (this.delay >= this.endDelay) {
  279. game.state.start('map');
  280. }
  281. }
  282. },
  283. func_overSquare: function () {
  284. if (!self.hasClickedA && this.figure == "A") {
  285. // If over fraction 'n/n' shows warning message not allowing it
  286. if (this.index == self.numBlocksA - 1) {
  287. self.warningTextA.setText(lang.error_msg);
  288. self.warningTextB.setText("");
  289. } else {
  290. self.warningTextA.setText("");
  291. self.warningTextB.setText("");
  292. // selected blocks become fully visible
  293. for (let i = 0; i < self.numBlocksA; i++) {
  294. self.blocksA.children[i].alpha = (i <= this.index) ? 1 : 0.5;
  295. }
  296. self.fractionA.x = this.xA + ((this.index + 1) * (self.figureWidth / self.numBlocksA)) + 25;
  297. self.fractionA.alpha = 1;
  298. self.fractionA.setText(this.index + 1);
  299. }
  300. }
  301. if (!self.hasClickedB && this.figure == "B") {
  302. // If over fraction 'n/n' shows warning message not allowing it
  303. if (this.index == self.numBlocksB - 1) {
  304. self.warningTextA.setText("");
  305. self.warningTextB.setText(lang.error_msg);
  306. } else {
  307. self.warningTextA.setText("");
  308. self.warningTextB.setText("");
  309. // selected blocks become fully visible
  310. for (let i = 0; i < self.numBlocksB; i++) {
  311. self.blocksB.children[i].alpha = (i <= this.index) ? 1 : 0.5;
  312. }
  313. self.fractionB.x = this.xB + ((this.index + 1) * (self.figureWidth / self.numBlocksB)) + 25;
  314. self.fractionB.alpha = 1;
  315. self.fractionB.setText(this.index + 1);
  316. }
  317. }
  318. },
  319. func_outSquare: function () {
  320. // On level type A
  321. if (!self.hasClickedA && this.figure == "A") {
  322. for (let i = 0; i <= this.index; i++) {
  323. self.blocksA.children[i].alpha = 0.5;
  324. }
  325. self.fractionA.alpha = 0;
  326. }
  327. // On level type B
  328. if (!self.hasClickedB && this.figure == "B") {
  329. for (let i = 0; i <= this.index; i++) {
  330. self.blocksB.children[i].alpha = 0.5;
  331. }
  332. self.fractionB.alpha = 0;
  333. }
  334. },
  335. func_clickSquare: function () {
  336. // On level type A
  337. if (!self.hasClickedA && this.figure == "A" && this.index != self.numBlocksA - 1) {
  338. for (let i = 0; i < self.numBlocksA; i++) {
  339. // desable block input
  340. self.blocksA.children[i].inputEnabled = false;
  341. // turn auxiliar blocks invisible
  342. if (i > this.index) self.auxBlocksA.children[i].alpha = 0;
  343. }
  344. // turn value label invisible
  345. self.labelA.alpha = 0;
  346. if (audioStatus) sound.beepSound.play();
  347. // Save number of selected blocks
  348. self.selectedA = this.index + 1;
  349. // set fraction x position
  350. self.fractionA.x = this.xA + (self.selectedA * (self.figureWidth / self.numBlocksA)) + 25;
  351. self.fractionLineA.x = self.fractionA.x
  352. self.hasClickedA = true;
  353. self.animateA = true;
  354. }
  355. // On level type B
  356. if (!self.hasClickedB && this.figure == "B" && this.index != self.numBlocksB - 1) {
  357. for (let i = 0; i < self.numBlocksB; i++) {
  358. // desable block input
  359. self.blocksB.children[i].inputEnabled = false;
  360. // turn auxiliar blocks invisible
  361. if (i > this.index) self.auxBlocksB.children[i].alpha = 0;
  362. }
  363. // turn value label invisible
  364. self.labelB.alpha = 0;
  365. if (audioStatus) sound.beepSound.play();
  366. // Save number of selected blocks
  367. self.selectedB = this.index + 1;
  368. // Set fraction x position
  369. self.fractionB.x = this.xB + (self.selectedB * (self.figureWidth / self.numBlocksB)) + 25;
  370. self.fractionLineB.x = self.fractionB.x
  371. self.hasClickedB = true;
  372. self.animateB = true;
  373. }
  374. },
  375. func_getRndDivisor: function (number) { //Get random divisor for a number
  376. let div = []; //Divisors found
  377. let p = 0; //current dividor index
  378. for (let i = 2; i < number; i++) {
  379. if (number % i == 0) {
  380. div[p] = i;
  381. p++;
  382. }
  383. }
  384. let x = game.rnd.integerInRange(0, p - 1);
  385. return div[x];
  386. },
  387. func_getRndDivisor: function (number) { //Get random divisor for a number
  388. let validDivs = []; // Divisors found
  389. for (let div = 2; div < number; div++) {
  390. // if 'number' can be divided by 'div', add to list of 'validDivs'
  391. if (number % div == 0) validDivs.push(div);
  392. }
  393. const randIndex = game.rnd.integerInRange(0, validDivs.length - 1);
  394. return validDivs[randIndex];
  395. },
  396. // Game information
  397. func_updateCounter: function () {
  398. this.totalTime++;
  399. },
  400. func_postScore: function () {
  401. let abst = "numBlocksA: " + this.numBlocksA
  402. + ", valueA: " + this.selectedA
  403. + ", numBlocksB: " + this.numBlocksB
  404. + ", valueB: " + this.selectedB;
  405. let hr = new XMLHttpRequest();
  406. // Create some variables we need to send to our PHP file
  407. let url = "php/save.php";
  408. let vars = "s_ip=" + hip
  409. + "&s_name=" + playerName
  410. + "&s_lang=" + langString
  411. + "&s_game=" + levelShape
  412. + "&s_mode=" + levelType;
  413. vars += "&s_oper=Equal"
  414. + "&s_leve=" + levelDifficulty
  415. + "&s_posi=" + mapPosition
  416. + "&s_resu=" + this.result
  417. + "&s_time=" + this.totalTime
  418. + "&s_deta=" + abst;
  419. hr.open("POST", url, true);
  420. hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  421. hr.onreadystatechange = function () {
  422. if (debugMode) console.log(hr);
  423. if (hr.readyState == 4 && hr.status == 200) {
  424. let return_data = hr.responseText;
  425. if (debugMode) console.log(return_data);
  426. }
  427. }
  428. // Send the data to PHP now... and wait for response to update the status div
  429. hr.send(vars); // Actually execute the request
  430. if (debugMode) console.log("processing...");
  431. if (debugMode) console.log(vars);
  432. }
  433. };