menu-scene.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. class MenuScene {
  2. constructor() {
  3. this.playButton = null;
  4. this.deleteSave = null;
  5. this.muteButton = null;
  6. }
  7. init() {
  8. this.playButton = new Button(canvas.width / 2, canvas.height / 2, "Start", () => {
  9. changeState(1);
  10. });
  11. this.deleteSave = new Button(canvas.width / 2, canvas.height - 100, "Delete Save", () => {
  12. if (confirm('Are you sure you want to delete your game save?')) {
  13. deleteGame();
  14. alert("Save deleted.");
  15. window.location.reload();
  16. }
  17. });
  18. this.deleteSave.width = 100;
  19. this.deleteSave.height = 40;
  20. this.deleteSave.fontSize = 18;
  21. this.deleteSave.buttonColor = Color.LightGray;
  22. this.deleteSave.buttonHoverColor = "crimson";
  23. this.deleteSave.textColor = Color.DarkGray;
  24. this.deleteSave.textHoverColor = Color.White;
  25. let startIcon = saveData.mute ? "🔇" : "🔈";
  26. this.muteButton = new Button(canvas.width - 50, 50, startIcon, () => {
  27. if (saveData.mute) {
  28. this.muteButton.text = "🔈";
  29. } else {
  30. this.muteButton.text = "🔇";
  31. }
  32. saveData.mute = !saveData.mute;
  33. sound.isMuted = saveData.mute;
  34. });
  35. this.muteButton.width = 20;
  36. this.muteButton.height = 28;
  37. this.muteButton.fontSize = 18;
  38. this.muteButton.buttonColor = "transparent";
  39. this.muteButton.buttonHoverColor = Color.LightGray;
  40. sound.isMuted = saveData.mute;
  41. }
  42. update(delta) {
  43. if (keys[KeyCode.Enter]) {
  44. changeState(1);
  45. }
  46. this.playButton.update(delta);
  47. this.deleteSave.update(delta);
  48. this.muteButton.update(delta);
  49. }
  50. draw(context) {
  51. this.drawBackground(context);
  52. context.fillStyle = Color.LightBlue;
  53. context.textAlign = "center";
  54. context.font = "48px Trebuchet MS";
  55. context.fillText("P4ck3t", canvas.width / 2, Math.max(70, (canvas.height / 4)));
  56. context.font = "22px Trebuchet MS";
  57. context.fillText("A js13k game entry", canvas.width / 2, Math.max(100, (canvas.height / 4) + 30));
  58. context.fillText("by EyeOfMidas", canvas.width / 2, Math.max(130, (canvas.height / 4) + 60));
  59. this.playButton.draw(context);
  60. this.deleteSave.draw(context);
  61. this.muteButton.draw(context);
  62. }
  63. drawBackground(context) {
  64. context.fillStyle = Color.VeryDarkBlue;
  65. for (let y = 0; y < canvas.height / 128; y++) {
  66. for (let x = 0; x < canvas.width / 128; x++) {
  67. let wobble = (Math.sin((x * 45) + new Date().getTime() / 500));
  68. context.save();
  69. context.translate(x * 128 + (10 * wobble), y * 128 + (20 * wobble));
  70. context.rotate(45 * (Math.PI / 180));
  71. context.beginPath();
  72. context.rect(-(wobble) - 4, -(wobble) - 4, 2 * wobble + 8, 2 * wobble + 8);
  73. context.fill();
  74. context.restore();
  75. }
  76. }
  77. }
  78. onResize() {
  79. this.playButton.x = canvas.width / 2;
  80. this.playButton.y = Math.max(200, canvas.height / 2);
  81. this.deleteSave.x = canvas.width / 2;
  82. this.deleteSave.y = Math.max(333, canvas.height - 100);
  83. this.muteButton.x = canvas.width - 50;
  84. this.muteButton.y = 50;
  85. }
  86. onMouseMove(event) {
  87. this.playButton.isHovered = false;
  88. document.body.style.cursor = "default";
  89. if (this.playButton.isMouseOver(event)) {
  90. this.playButton.isHovered = true;
  91. document.body.style.cursor = "pointer";
  92. }
  93. this.deleteSave.isHovered = false;
  94. if (this.deleteSave.isMouseOver(event)) {
  95. this.deleteSave.isHovered = true;
  96. document.body.style.cursor = "pointer";
  97. }
  98. this.muteButton.isHovered = false;
  99. if (this.muteButton.isMouseOver(event)) {
  100. this.muteButton.isHovered = true;
  101. document.body.style.cursor = "pointer";
  102. }
  103. }
  104. onMouseUp(event) {
  105. event.preventDefault();
  106. if (this.playButton.isMouseOver(event)) {
  107. this.playButton.triggerHandler();
  108. document.body.style.cursor = "default";
  109. }
  110. if (this.deleteSave.isMouseOver(event)) {
  111. this.deleteSave.triggerHandler();
  112. document.body.style.cursor = "default";
  113. }
  114. if (this.muteButton.isMouseOver(event)) {
  115. this.muteButton.triggerHandler();
  116. document.body.style.cursor = "default";
  117. }
  118. }
  119. onTouchEnd(event) {
  120. event.preventDefault();
  121. if (this.playButton.isTouchOver(event)) {
  122. this.playButton.triggerHandler();
  123. document.body.style.cursor = "default";
  124. }
  125. if (this.deleteSave.isTouchOver(event)) {
  126. this.deleteSave.triggerHandler();
  127. document.body.style.cursor = "default";
  128. }
  129. if (this.muteButton.isTouchOver(event)) {
  130. this.muteButton.triggerHandler();
  131. document.body.style.cursor = "default";
  132. }
  133. }
  134. }
  135. class Button {
  136. constructor(x, y, text, handler) {
  137. this.x = x;
  138. this.y = y;
  139. this.width = 200;
  140. this.height = 80;
  141. this.text = text;
  142. this.handler = handler;
  143. this.isHovered = false;
  144. this.buttonColor = Color.DarkBlue;
  145. this.buttonHoverColor = Color.LightGray;
  146. this.textColor = Color.LightBlue;
  147. this.textHoverColor = Color.White;
  148. this.fontSize = 48;
  149. this.fontFamily = "Trebuchet MS";
  150. }
  151. update(delta) {
  152. }
  153. draw(context) {
  154. context.fillStyle = this.buttonColor;
  155. if (this.isHovered) {
  156. context.fillStyle = this.buttonHoverColor;
  157. }
  158. context.textAlign = "center";
  159. context.font = `${this.fontSize}px ${this.fontFamily}`;
  160. let bounds = context.measureText(this.text);
  161. this.width = Math.max(this.width, bounds.width + 8);
  162. context.save();
  163. context.translate(this.x, this.y);
  164. context.beginPath();
  165. context.rect(-this.width / 2, -this.height / 2, this.width, this.height);
  166. context.fill();
  167. context.fillStyle = this.textColor;
  168. if (this.isHovered) {
  169. context.fillStyle = this.textHoverColor;
  170. }
  171. context.fillText(this.text, 0, this.fontSize / 3);
  172. context.restore();
  173. }
  174. isMouseOver(event) {
  175. return event.clientX > this.x - (this.width / 2) && event.clientX < this.x + this.width - (this.width / 2) &&
  176. event.clientY > this.y - (this.height / 2) && event.clientY < this.y + this.height - (this.height / 2);
  177. }
  178. isTouchOver(event) {
  179. let touchX = parseInt(event.changedTouches[0].clientX);
  180. let touchY = parseInt(event.changedTouches[0].clientY);
  181. return touchX > this.x - (this.width / 2) && touchX < this.x + this.width - (this.width / 2) &&
  182. touchY > this.y - (this.height / 2) && touchY < this.y + this.height - (this.height / 2);
  183. }
  184. triggerHandler() {
  185. this.handler();
  186. }
  187. }