map.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /******************************
  2. * This file holds game states.
  3. ******************************/
  4. /** [MAP STATE] Screen that shows the 4 generated levels in a map (and the level where the player is currently in).
  5. *
  6. * @namespace
  7. */
  8. const mapState = {
  9. /**
  10. * Main code
  11. */
  12. create: function () {
  13. // Background color
  14. game.add.geom.rect(
  15. 0,
  16. 0,
  17. context.canvas.width,
  18. context.canvas.height,
  19. undefined,
  20. 0,
  21. colors.blueBg,
  22. 1
  23. );
  24. // Calls function that loads navigation icons
  25. // FOR MOODLE
  26. if (moodle) {
  27. navigationIcons.add(
  28. false,
  29. false,
  30. false, // Left icons
  31. false,
  32. false, // Right icons
  33. false,
  34. false
  35. );
  36. } else {
  37. navigationIcons.add(
  38. true,
  39. true,
  40. false, // Left icons
  41. false,
  42. false, // Right icons
  43. 'customMenu',
  44. false
  45. );
  46. }
  47. this.points = {
  48. x: [90, 204, 318, 432, 546, 660],
  49. y: [486, 422, 358, 294, 230, 166],
  50. };
  51. const rocks = {
  52. x: [156, 275, 276, 441, 452, 590, 712],
  53. y: [309, 543, 259, 156, 419, 136, 316],
  54. type: [1, 1, 2, 1, 2, 2, 2],
  55. };
  56. const trees = {
  57. x: [105, 214, 354, 364, 570, 600, 740, 779],
  58. y: [341, 219, 180, 520, 550, 392, 488, 286],
  59. type: [2, 4, 3, 4, 1, 2, 4, 4],
  60. };
  61. const offsetH = gameFrame().y;
  62. const offsetW = gameFrame().x * 2.5;
  63. for (let i = 0, cur = this.points; i < cur.x.length; i++) {
  64. cur.x[i] += offsetW;
  65. cur.y[i] += offsetH;
  66. }
  67. for (let i = 0, cur = rocks; i < cur.x.length; i++) {
  68. cur.x[i] += offsetW;
  69. cur.y[i] += offsetH;
  70. }
  71. for (let i = 0, cur = trees; i < cur.x.length; i++) {
  72. cur.x[i] += offsetW;
  73. cur.y[i] += offsetH;
  74. }
  75. // Map
  76. game.add.image(offsetW, offsetH + 40, 'bgmap');
  77. // Progress bar
  78. const percentText = completedLevels * 25;
  79. if (completedLevels >= 4)
  80. game.add.geom.rect(
  81. context.canvas.width - 240,
  82. 10,
  83. 4 * 37.5,
  84. 35,
  85. undefined,
  86. 0,
  87. colors.greenNeon,
  88. 0.5
  89. );
  90. else
  91. game.add.geom.rect(
  92. context.canvas.width - 240,
  93. 10,
  94. completedLevels * 37.5,
  95. 35,
  96. undefined,
  97. 0,
  98. colors.yellow,
  99. 0.9
  100. );
  101. game.add.geom.rect(
  102. context.canvas.width - 240 + 1,
  103. 11,
  104. 149,
  105. 34,
  106. colors.blue,
  107. 3,
  108. undefined,
  109. 1
  110. ); // Box
  111. game.add.text(
  112. context.canvas.width - 240 + 160,
  113. 38,
  114. percentText + '%',
  115. textStyles.h2_blueDark
  116. ).align = 'left';
  117. game.add.text(
  118. context.canvas.width - 240 - 10,
  119. 38,
  120. game.lang.difficulty + ' ' + gameDifficulty,
  121. textStyles.h2_blueDark
  122. ).align = 'right';
  123. // Map positions
  124. if (gameType == 'squareOne') {
  125. // Garage
  126. game.add
  127. .image(this.points.x[0], this.points.y[0], 'garage', 0.4)
  128. .anchor(0.5, 1);
  129. // Farm
  130. game.add
  131. .image(this.points.x[5], this.points.y[5], 'farm', 0.6)
  132. .anchor(0.1, 0.7);
  133. } else {
  134. // House
  135. game.add
  136. .image(this.points.x[0], this.points.y[0], 'house', 0.7)
  137. .anchor(0.7, 0.8);
  138. // School
  139. game.add
  140. .image(this.points.x[5], this.points.y[5], 'school', 0.35)
  141. .anchor(0.2, 0.7);
  142. }
  143. // Rocks and bushes
  144. for (let i in rocks.type) {
  145. if (rocks.type[i] == 1) {
  146. game.add.image(rocks.x[i], rocks.y[i], 'rock', 0.32).anchor(0.5, 0.95);
  147. } else {
  148. game.add.image(rocks.x[i], rocks.y[i], 'bush', 0.4).anchor(0.5, 0.95);
  149. }
  150. }
  151. // Trees
  152. for (let i in trees.type) {
  153. game.add
  154. .image(trees.x[i], trees.y[i], 'tree' + trees.type[i], 0.6)
  155. .anchor(0.5, 0.95);
  156. }
  157. // Map positions
  158. for (let i = 1; i < this.points.x.length - 1; i++) {
  159. const aux =
  160. i < mapPosition || (mapMove && i == mapPosition)
  161. ? 'place_on'
  162. : 'place_off';
  163. // Map road positions - game levels
  164. game.add
  165. .image(this.points.x[i], this.points.y[i], aux, 0.3)
  166. .anchor(0.5, 0.5);
  167. // Map road signs - game level number
  168. game.add
  169. .image(this.points.x[i] - 20, this.points.y[i] - 60, 'sign', 0.4)
  170. .anchor(0.5, 1);
  171. game.add.text(
  172. this.points.x[i] - 20,
  173. this.points.y[i] - 79,
  174. i,
  175. textStyles.h2_white
  176. );
  177. }
  178. // Game Character
  179. if (gameType == 'squareOne') {
  180. if (gameOperation == 'Plus') {
  181. this.character = game.add.sprite(
  182. this.points.x[mapPosition],
  183. this.points.y[mapPosition],
  184. 'tractor',
  185. 0,
  186. 0.5
  187. );
  188. this.character.animation = ['green_tractor', [0, 1, 2, 3, 4], 3];
  189. } else {
  190. this.character = game.add.sprite(
  191. this.points.x[mapPosition],
  192. this.points.y[mapPosition],
  193. 'tractor',
  194. 10,
  195. 0.5
  196. );
  197. this.character.animation = ['red_tractor', [10, 11, 12, 13, 14], 3];
  198. }
  199. this.character.rotate = -30; // 25 anticlock
  200. } else {
  201. this.character = game.add.sprite(
  202. this.points.x[mapPosition],
  203. this.points.y[mapPosition],
  204. 'kid_run',
  205. 0,
  206. 0.4
  207. );
  208. this.character.animation = ['kid', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3];
  209. }
  210. this.character.anchor(0.5, 1);
  211. game.animation.play(this.character.animation[0]);
  212. this.count = 0;
  213. const speed = 60;
  214. const xA = this.points.x[mapPosition];
  215. const yA = this.points.y[mapPosition];
  216. const xB = this.points.x[mapPosition + 1];
  217. const yB = this.points.y[mapPosition + 1];
  218. self.speedX = (xB - xA) / speed;
  219. self.speedY = (yA - yB) / speed;
  220. game.event.add('click', this.onInputDown);
  221. game.event.add('mousemove', this.onInputOver);
  222. },
  223. /**
  224. * Game loop
  225. */
  226. update: function () {
  227. let endUpdate = false;
  228. self.count++;
  229. if (self.count > 60) {
  230. // Wait 1 second before moving or staring a game
  231. if (mapMove) {
  232. // Move character on screen for 1 second
  233. self.character.x += self.speedX;
  234. self.character.y -= self.speedY;
  235. if (Math.ceil(self.character.x) >= self.points.x[mapPosition + 1]) {
  236. // Reached next map position
  237. mapMove = false;
  238. mapPosition++; // Set new next position
  239. }
  240. }
  241. if (!mapMove) {
  242. endUpdate = true;
  243. }
  244. }
  245. game.render.all();
  246. if (endUpdate) {
  247. game.animation.stop(self.character.animation[0]);
  248. self.loadGame();
  249. }
  250. },
  251. /**
  252. * Calls game state
  253. */
  254. loadGame: function () {
  255. if (mapPosition <= 4) game.state.start('' + gameType);
  256. else game.state.start('end');
  257. },
  258. /**
  259. * Called by mouse click event
  260. *
  261. * @param {object} mouseEvent contains the mouse click coordinates
  262. */
  263. onInputDown: function (mouseEvent) {
  264. const x = game.math.getMouse(mouseEvent).x;
  265. const y = game.math.getMouse(mouseEvent).y;
  266. navigationIcons.onInputDown(x, y);
  267. },
  268. /**
  269. * Called by mouse move event
  270. *
  271. * @param {object} mouseEvent contains the mouse move coordinates
  272. */
  273. onInputOver: function (mouseEvent) {
  274. const x = game.math.getMouse(mouseEvent).x;
  275. const y = game.math.getMouse(mouseEvent).y;
  276. navigationIcons.onInputOver(x, y);
  277. },
  278. };
  279. /** [ENDING STATE] Ending screen shown when the player has completed all 4 levels and therefore completed the game.
  280. *
  281. * @namespace
  282. */
  283. const endState = {
  284. /**
  285. * Main code
  286. */
  287. create: function () {
  288. self.preAnimate = false;
  289. self.animate = true;
  290. // Background color
  291. game.add.geom.rect(
  292. 0,
  293. 0,
  294. context.canvas.width,
  295. context.canvas.height,
  296. undefined,
  297. 0,
  298. colors.blueBg,
  299. 1
  300. );
  301. // Background
  302. game.add.image(0, 0, 'bgimage', 2.2);
  303. // Clouds
  304. game.add.image(640, 100, 'cloud');
  305. game.add.image(1280, 80, 'cloud');
  306. game.add.image(300, 85, 'cloud', 0.8);
  307. // Floor
  308. for (let i = 0; i < context.canvas.width / 100; i++) {
  309. game.add.image(i * 100, context.canvas.height - 100, 'floor');
  310. }
  311. // Progress bar
  312. game.add.geom.rect(
  313. 660,
  314. 10,
  315. 4 * 37.5,
  316. 35,
  317. undefined,
  318. 0,
  319. colors.greenNeon,
  320. 0.5
  321. ); // Progress
  322. game.add.geom.rect(661, 11, 149, 34, colors.blue, 3, undefined, 1); // Box
  323. game.add.text(820, 38, '100%', textStyles.h2_blueDark).align = 'left';
  324. game.add.text(
  325. 650,
  326. 38,
  327. game.lang.difficulty + ' ' + gameDifficulty,
  328. textStyles.h2_blueDark
  329. ).align = 'right';
  330. game.add.image(360, 545, 'tree4', 0.7).anchor(0, 1);
  331. // Level character
  332. switch (gameType) {
  333. case 'circleOne':
  334. this.preAnimate = true;
  335. this.animate = false;
  336. // School
  337. game.add.image(600, 222, 'school', 0.7);
  338. // Kid
  339. this.character = game.add.sprite(0, -152, 'kid_run', 0, 0.7);
  340. this.character.anchor(0.5, 0.5);
  341. this.character.animation = [
  342. 'move',
  343. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
  344. 3,
  345. ];
  346. // Balloon
  347. this.balloon = game.add.image(0, -260, 'balloon');
  348. this.balloon.anchor(0.5, 0.5);
  349. this.basket = game.add.image(0, -150, 'balloon_basket');
  350. this.basket.anchor(0.5, 0.5);
  351. break;
  352. case 'squareTwo':
  353. // School
  354. game.add.image(600, 222, 'school', 0.7);
  355. // Kid
  356. this.character = game.add.sprite(0, 460, 'kid_run', 6, 0.7);
  357. this.character.anchor(0.5, 0.5);
  358. this.character.animation = [
  359. 'move',
  360. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
  361. 3,
  362. ];
  363. break;
  364. case 'squareOne':
  365. // Farm
  366. game.add.image(650, 260, 'farm', 1.1);
  367. // Tractor
  368. this.character = game.add.sprite(0, 490, 'tractor', 0, 0.7);
  369. this.character.anchor(0.5, 0.5);
  370. if (gameOperation == 'Plus') {
  371. this.character.animation = ['move', [0, 1, 2, 3, 4], 4];
  372. } else {
  373. this.character.curFrame = 10;
  374. this.character.animation = ['move', [10, 11, 12, 13, 14], 4];
  375. }
  376. break;
  377. }
  378. if (this.animate) game.animation.play(this.character.animation[0]);
  379. game.add.image(30, 585, 'tree4', 0.85).anchor(0, 1);
  380. },
  381. /**
  382. * Game loop
  383. */
  384. update: function () {
  385. // Balloon falling
  386. if (self.preAnimate) {
  387. if (self.character.y < 460) {
  388. self.balloon.y += 2;
  389. self.basket.y += 2;
  390. self.character.y += 2;
  391. self.balloon.x++;
  392. self.basket.x++;
  393. self.character.x++;
  394. } else {
  395. self.preAnimate = false;
  396. self.animate = true;
  397. game.animation.play(self.character.animation[0]);
  398. }
  399. }
  400. // Character running
  401. if (self.animate) {
  402. if (self.character.x <= 700) {
  403. self.character.x += 2;
  404. } else {
  405. self.animate = false;
  406. game.animation.stop(self.character.animation[0]);
  407. // FOR MOODLE
  408. if (!moodle) {
  409. completedLevels = 0;
  410. game.state.start('menu');
  411. } else {
  412. // FOR MOODLE
  413. parent.location.reload(true);
  414. }
  415. }
  416. }
  417. game.render.all();
  418. },
  419. };