end.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /******************************
  2. * This file holds game states.
  3. ******************************/
  4. /** [ENDING STATE] Ending screen shown when the player has completed all 4 levels and therefore completed the game.
  5. *
  6. * @namespace
  7. */
  8. const endState = {
  9. ui: undefined,
  10. control: undefined,
  11. character: undefined,
  12. balloon: undefined,
  13. basket: undefined,
  14. /**
  15. * Main code
  16. */
  17. create: function () {
  18. this.control = {
  19. animate: true,
  20. preAnimate: false,
  21. waitUserAction: false,
  22. endUpdate: false,
  23. counter: 0,
  24. direc: 1,
  25. };
  26. this.ui = {
  27. continue: {
  28. button: undefined,
  29. text: undefined,
  30. },
  31. };
  32. renderBackground('end');
  33. self.utils.renderProgressBar();
  34. // Back trees
  35. game.add
  36. .image(-100, context.canvas.height - 200, 'tree_4', 1.05)
  37. .anchor(0, 1);
  38. game.add
  39. .image(360 + 400 + 400, context.canvas.height - 200, 'tree_4', 1.05)
  40. .anchor(0, 1);
  41. self.utils.renderCharacters();
  42. if (this.control.animate) game.animation.play(this.character.animation[0]);
  43. // Front tree
  44. game.add
  45. .image(30 + 200 + 100, context.canvas.height - 30, 'tree_4', 1.275)
  46. .anchor(0, 1);
  47. game.event.add('click', this.events.onInputDown);
  48. game.event.add('mousemove', this.events.onInputOver);
  49. },
  50. /**
  51. * Game loop
  52. */
  53. update: function () {
  54. if (isDebugMode) {
  55. if (debugState.end.skip && debugState.end.stop) {
  56. self.control.animate = false;
  57. }
  58. if (debugState.moodle.emulate) {
  59. moodleVar = debugState.moodle.info;
  60. game.state.start('studentReport');
  61. return;
  62. }
  63. }
  64. self.control.counter++;
  65. // Balloon falling
  66. if (self.control.preAnimate) {
  67. const speedY = 3,
  68. speedX = 2;
  69. if (self.basket.y < context.canvas.height - 240) {
  70. self.balloon.y += speedY;
  71. self.basket.y += speedY;
  72. self.character.y += speedY;
  73. self.balloon.x += speedX;
  74. self.basket.x += speedX;
  75. self.character.x += speedX;
  76. } else {
  77. self.control.preAnimate = false;
  78. self.control.animate = true;
  79. game.animation.play(self.character.animation[0]);
  80. }
  81. }
  82. if (gameName == 'circleOne') {
  83. if (self.control.counter % 40 === 0) {
  84. self.balloon.x += 5 * self.control.direc;
  85. self.control.direc *= -1;
  86. }
  87. }
  88. // Character running
  89. if (self.control.animate) {
  90. if (self.character.x <= 1550) {
  91. self.character.x += 4;
  92. } else {
  93. self.control.animate = false;
  94. game.animation.stop(self.character.animation[0]);
  95. self.character.alpha = 0;
  96. self.control.waitUserAction = true;
  97. self.utils.renderEndUI();
  98. }
  99. }
  100. if (!moodle && self.control.endLevel) {
  101. completedLevels = 0;
  102. game.state.start('menu');
  103. }
  104. game.render.all();
  105. },
  106. utils: {
  107. renderProgressBar: () => {
  108. const x0 = 300;
  109. const y0 = 20;
  110. // Bar content
  111. for (let i = 0; i < 4; i++) {
  112. game.add.image(
  113. context.canvas.width - x0 + 37.5 * i,
  114. y0,
  115. 'progress_bar_tile'
  116. );
  117. }
  118. // Bar wrapper
  119. game.add.geom.rect(
  120. context.canvas.width - x0 + 1,
  121. y0 + 1,
  122. 149, //150, //149,
  123. 34, //35, //34,
  124. 'transparent',
  125. 1,
  126. colors.blue,
  127. 3
  128. );
  129. // percentage label
  130. game.add.text(
  131. context.canvas.width - x0 + 160,
  132. y0 + 33,
  133. '100%',
  134. textStyles.h2_
  135. ).align = 'left';
  136. // Difficulty label
  137. game.add.text(
  138. context.canvas.width - x0 - 10,
  139. y0 + 33,
  140. game.lang.difficulty + ' ' + gameDifficulty,
  141. textStyles.h2_
  142. ).align = 'right';
  143. },
  144. renderCharacters: () => {
  145. gameList[gameId].assets.end.building();
  146. self.character = gameList[gameId].assets.end.character();
  147. self.character.animation =
  148. gameList[gameId].assets.end.characterAnimation();
  149. if (gameName === 'circleOne') {
  150. self.control.preAnimate = true;
  151. self.control.animate = false;
  152. // Balloon
  153. self.balloon = game.add.image(0, -350, 'balloon', 1.5);
  154. self.balloon.anchor(0.5, 0.5);
  155. self.basket = game.add.image(0, -150, 'balloon_basket', 1.5);
  156. self.basket.anchor(0.5, 0.5);
  157. self.character.curFrame = 6;
  158. }
  159. },
  160. renderEndUI: () => {
  161. const btnY = context.canvas.height / 2;
  162. let btnTextFont = textStyles.btn;
  163. // Continue Button
  164. if (!moodle) {
  165. self.ui.continue.button = game.add.geom.rect(
  166. context.canvas.width / 2,
  167. btnY,
  168. 600,
  169. 100,
  170. colors.green
  171. );
  172. self.ui.continue.button.anchor(0.5, 0.5);
  173. } else {
  174. btnTextFont = { ...btnTextFont, fill: colors.blue };
  175. }
  176. // Continue button text
  177. self.ui.continue.text = game.add.text(
  178. context.canvas.width / 2,
  179. btnY + 16,
  180. moodle ? game.lang.submit : game.lang.back_to_menu,
  181. btnTextFont
  182. );
  183. // Title
  184. const font = { ...textStyles.btnLg };
  185. font.fill = colors.blue;
  186. game.add.text(
  187. context.canvas.width / 2,
  188. btnY - 100,
  189. game.lang.congratulations,
  190. font
  191. );
  192. },
  193. },
  194. events: {
  195. /**
  196. * Called by mouse click event
  197. *
  198. * @param {object} mouseEvent contains the mouse click coordinates
  199. */
  200. onInputDown: function (mouseEvent) {
  201. const x = game.math.getMouse(mouseEvent).x;
  202. const y = game.math.getMouse(mouseEvent).y;
  203. if (!moodle && self.control.waitUserAction) {
  204. if (game.math.isOverIcon(x, y, self.ui.continue.button)) {
  205. if (audioStatus) game.audio.popSound.play();
  206. self.control.endLevel = true;
  207. }
  208. }
  209. },
  210. /**
  211. * Called by mouse move event
  212. *
  213. * @param {object} mouseEvent contains the mouse move coordinates
  214. */
  215. onInputOver: function (mouseEvent) {
  216. const x = game.math.getMouse(mouseEvent).x;
  217. const y = game.math.getMouse(mouseEvent).y;
  218. if (!moodle && self.control.waitUserAction) {
  219. if (game.math.isOverIcon(x, y, self.ui.continue.button)) {
  220. // If pointer is over icon
  221. document.body.style.cursor = 'pointer';
  222. self.ui.continue.button.scale =
  223. self.ui.continue.button.initialScale * 1.1;
  224. self.ui.continue.text.style = textStyles.btnLg;
  225. } else {
  226. // If pointer is not over icon
  227. self.ui.continue.button.scale =
  228. self.ui.continue.button.initialScale * 1;
  229. document.body.style.cursor = 'auto';
  230. self.ui.continue.text.style = textStyles.btn;
  231. }
  232. }
  233. },
  234. },
  235. };