GameState.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import { Camera } from "../../libraries/Camera.js";
  2. import { Point } from "../../libraries/spatial/Point.js";
  3. import { TweenManager, Tween, Easing } from "../../libraries/Tween.js";
  4. import { Board } from "../Board.js";
  5. import { Global } from "../../libraries/Global.js";
  6. import { Piece } from "../Piece.js";
  7. export class GameState {
  8. constructor(fsm) {
  9. this.stateMachine = fsm;
  10. this.boundEvents = {};
  11. this.camera = new Camera(0, 0);
  12. this.tweenManager = new TweenManager()
  13. this.ballPosition = new Point(0,0);
  14. this.cameraTweenId = -1;
  15. this.frameFocus = 0;
  16. this.tileWidth = 64;
  17. this.boards = [];
  18. this.pieces = [];
  19. }
  20. init() {
  21. this.boundEvents['mousedown'] = this.mouseDown.bind(this);
  22. this.boundEvents['mousemove'] = this.mouseMove.bind(this);
  23. this.boundEvents['touchstart'] = this.touchStart.bind(this);
  24. this.boundEvents['touchmove'] = this.touchMove.bind(this);
  25. this.boundEvents['touchend'] = this.touchEnd.bind(this);
  26. this.boundEvents['mouseup'] = this.mouseUp.bind(this);
  27. this.boundEvents['resize'] = this.resize.bind(this);
  28. this.boundEvents['touch']
  29. for(let key in this.boundEvents) {
  30. window.addEventListener(key, this.boundEvents[key]);
  31. }
  32. this.boards = [];
  33. this.boards.push(new Board(this))
  34. this.boards.push(new Board(this))
  35. this.boards.push(new Board(this))
  36. this.pieces = [];
  37. this.pieces.push(new Piece(this, "L", 0, 0))
  38. this.pieces.push(new Piece(this, "S", 0, 0))
  39. this.pieces.push(new Piece(this, "U", 0, 0))
  40. this.resize()
  41. }
  42. draw(ctx) {
  43. this.camera.drawAtCamera(ctx, () => {
  44. for(let i = 0; i < this.boards.length; i++) {
  45. let board = this.boards[i];
  46. board.draw(ctx);
  47. }
  48. })
  49. let toolbarTop = Global.screenBounds.height / 2;
  50. let toolbarHeight = this.tileWidth * 6;
  51. ctx.save();
  52. ctx.translate(0, toolbarTop);
  53. ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
  54. ctx.beginPath()
  55. ctx.rect(0, 0, Global.screenBounds.width, toolbarHeight)
  56. ctx.fill()
  57. ctx.fillStyle = "black";
  58. ctx.font = "24px Ariel"
  59. ctx.fillText("Toolbar", 0, 24)
  60. for(let i = 0; i < this.pieces.length; i++) {
  61. let piece = this.pieces[i];
  62. piece.draw(ctx);
  63. }
  64. ctx.restore();
  65. ctx.fillStyle = "rgba(40, 40, 220, 0.5)";
  66. ctx.beginPath()
  67. let navTop = toolbarTop + toolbarHeight;
  68. let navHeight = Global.screenBounds.height - navTop;
  69. ctx.rect(0, navTop, Global.screenBounds.width, navHeight)
  70. ctx.fill()
  71. ctx.fillStyle = "black";
  72. ctx.font = "24px Ariel"
  73. ctx.fillText("Nav", 0, navTop + 24)
  74. }
  75. update(delta) {
  76. for(let i = 0; i < this.boards.length; i++) {
  77. let board = this.boards[i];
  78. board.update(delta);
  79. }
  80. for(let i = 0; i < this.pieces.length; i++) {
  81. let piece = this.pieces[i];
  82. piece.update(delta);
  83. }
  84. this.tweenManager.update();
  85. }
  86. mouseDown(event) {
  87. let mousePoint = new Point(event.clientX, event.clientY);
  88. if(mousePoint.y <= Global.screenBounds.center.y) {
  89. let direction = Math.sign(mousePoint.x - Global.screenBounds.center.x)
  90. this.frameFocus += direction
  91. this.frameFocus = Math.max(Math.min(this.boards.length - 1, this.frameFocus), 0)
  92. let tween = new Tween(this.camera.position, {x: this.boards[this.frameFocus].position.x}, 1000, Easing.Cubic.EaseOut);
  93. this.tweenManager.cancel(this.cameraTweenId)
  94. this.cameraTweenId = this.tweenManager.add(tween);
  95. }
  96. if(event.button == 0) {
  97. this.dragStartPoint = mousePoint;
  98. this.draggedPiece = null;
  99. mousePoint.y -= Global.screenBounds.height / 2;
  100. for(let i = 0; i < this.pieces.length; i++) {
  101. let piece = this.pieces[i];
  102. if(piece.pointWithin(mousePoint)) {
  103. this.draggedPiece = piece;
  104. break;
  105. }
  106. }
  107. }
  108. }
  109. touchStart(event) {
  110. let mousePoint = new Point(event.touches[0].clientX, event.touches[0].clientY);
  111. if(event.touches.length == 1) {
  112. this.dragStartPoint = mousePoint;
  113. this.draggedPiece = null;
  114. mousePoint.y -= Global.screenBounds.height / 2;
  115. for(let i = 0; i < this.pieces.length; i++) {
  116. let piece = this.pieces[i];
  117. if(piece.pointWithin(mousePoint)) {
  118. this.draggedPiece = piece;
  119. break;
  120. }
  121. }
  122. }
  123. }
  124. mouseMove(event) {
  125. document.body.style.cursor = "default";
  126. let mousePoint = new Point(event.clientX, event.clientY);
  127. if(this.draggedPiece && !this.dragStartPoint.equals(mousePoint)) {
  128. this.dragStarted = true;
  129. this.draggedPiece.position.x = mousePoint.x
  130. this.draggedPiece.position.y = mousePoint.y - Global.screenBounds.height / 2
  131. }
  132. }
  133. touchMove(event) {
  134. let mousePoint = new Point(event.touches[0].clientX, event.touches[0].clientY);
  135. if(this.draggedPiece && !this.dragStartPoint.equals(mousePoint)) {
  136. this.dragStarted = true;
  137. this.draggedPiece.position.x = mousePoint.x
  138. this.draggedPiece.position.y = mousePoint.y - Global.screenBounds.height / 2
  139. }
  140. }
  141. mouseUp(event) {
  142. if(this.dragStarted) {
  143. this.dragStarted = false;
  144. this.draggedPiece = null;
  145. return
  146. }
  147. this.dragStarted = false;
  148. this.draggedPiece = null;
  149. let mousePoint = new Point(event.clientX, event.clientY);
  150. mousePoint.y -= Global.screenBounds.height / 2;
  151. for(let i = 0; i < this.pieces.length; i++) {
  152. let piece = this.pieces[i];
  153. piece.mouseDown(event, mousePoint, this.tweenManager);
  154. }
  155. }
  156. touchEnd(event) {
  157. if(this.dragStarted) {
  158. this.dragStarted = false;
  159. this.draggedPiece = null;
  160. return
  161. }
  162. this.dragStarted = false;
  163. this.draggedPiece = null;
  164. let mousePoint = new Point(event.clientX, event.clientY);
  165. mousePoint.y -= Global.screenBounds.height / 2;
  166. for(let i = 0; i < this.pieces.length; i++) {
  167. let piece = this.pieces[i];
  168. piece.mouseDown(event, mousePoint, this.tweenManager);
  169. }
  170. }
  171. resize(event) {
  172. let possibleWidth = Math.min(64, Math.floor(Global.screenBounds.width / 11))
  173. let possibleHeight = Math.min(64, Math.floor((Global.screenBounds.height / 2) / 11))
  174. this.tileWidth = Math.min(possibleWidth, possibleHeight);
  175. for(let i = 0; i < this.boards.length; i++) {
  176. let board = this.boards[i];
  177. board.position.x = (14 * this.tileWidth) * i;
  178. if(board == this.boards[this.frameFocus]) {
  179. this.camera.position.x = board.position.x
  180. }
  181. }
  182. let toolbarHeight = this.tileWidth * 6;
  183. this.pieces[0].position.x = Global.screenBounds.width / 4
  184. this.pieces[0].position.y = toolbarHeight / 2
  185. this.pieces[1].position.x = Global.screenBounds.width / 2
  186. this.pieces[1].position.y = toolbarHeight / 2
  187. this.pieces[2].position.x = 3 /4 * Global.screenBounds.width
  188. this.pieces[2].position.y = toolbarHeight / 2
  189. }
  190. enter() {
  191. this.init(this.stateMachine.getState("game"));
  192. }
  193. leave() {
  194. this.board.destroy();
  195. for(let key in this.boundEvents) {
  196. window.removeEventListener(key, this.boundEvents[key]);
  197. }
  198. }
  199. }