Piece.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import { Point } from "../libraries/spatial/Point.js";
  2. import { Rectangle } from "../libraries/spatial/Rectangle.js";
  3. import { Tween, Easing } from "../libraries/Tween.js";
  4. export class Piece {
  5. constructor(state, type, x = 0, y = 0){
  6. this.position = new Point(x, y);
  7. this.state = state;
  8. this.type = type;
  9. this.rotation = 0
  10. this.targetRotation = 0
  11. this.flip = 1;
  12. this.targetFlip = 1;
  13. this.rotationTweenId = -1;
  14. this.flipTweenId = -1;
  15. }
  16. update(delta) {
  17. }
  18. draw(ctx) {
  19. ctx.fillStyle = "magenta"
  20. ctx.save();
  21. ctx.translate(this.position.x, this.position.y)
  22. ctx.rotate(this.rotation);
  23. ctx.scale(this.flip, 1)
  24. switch(this.type) {
  25. case "L":
  26. this.drawLShape(ctx)
  27. break;
  28. case "S":
  29. this.drawSShape(ctx)
  30. break;
  31. case "U":
  32. this.drawUShape(ctx)
  33. break;
  34. }
  35. ctx.restore();
  36. }
  37. drawLShape(ctx) {
  38. //L Piece
  39. ctx.beginPath();
  40. ctx.rect(-1 * this.state.tileWidth, -2 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  41. ctx.fill();
  42. ctx.beginPath();
  43. ctx.rect(-1 * this.state.tileWidth, -1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  44. ctx.fill();
  45. ctx.beginPath();
  46. ctx.rect(-1 * this.state.tileWidth, 0, this.state.tileWidth, this.state.tileWidth)
  47. ctx.fill();
  48. ctx.beginPath();
  49. ctx.rect(-1 * this.state.tileWidth, 1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  50. ctx.fill();
  51. ctx.beginPath();
  52. ctx.rect(0, 1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  53. ctx.fill();
  54. }
  55. drawSShape(ctx) {
  56. //S Piece
  57. ctx.save();
  58. ctx.translate(- this.state.tileWidth / 2, - this.state.tileWidth / 2)
  59. ctx.beginPath();
  60. ctx.rect(-1 * this.state.tileWidth, -1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  61. ctx.fill();
  62. ctx.beginPath();
  63. ctx.rect(0, -1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  64. ctx.fill();
  65. ctx.beginPath();
  66. ctx.rect(0, 0, this.state.tileWidth, this.state.tileWidth)
  67. ctx.fill();
  68. ctx.beginPath();
  69. ctx.rect(0, 1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  70. ctx.fill();
  71. ctx.beginPath();
  72. ctx.rect(1 * this.state.tileWidth, 1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  73. ctx.fill();
  74. ctx.restore();
  75. }
  76. drawUShape(ctx) {
  77. //U Piece
  78. ctx.save();
  79. ctx.translate(- this.state.tileWidth / 2, 0)
  80. ctx.beginPath();
  81. ctx.rect(-1 * this.state.tileWidth, -1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  82. ctx.fill();
  83. ctx.beginPath();
  84. ctx.rect(-1 * this.state.tileWidth, 0, this.state.tileWidth, this.state.tileWidth)
  85. ctx.fill();
  86. ctx.beginPath();
  87. ctx.rect(0, 0, this.state.tileWidth, this.state.tileWidth)
  88. ctx.fill();
  89. ctx.beginPath();
  90. ctx.rect(1 * this.state.tileWidth, 0, this.state.tileWidth, this.state.tileWidth)
  91. ctx.fill();
  92. ctx.beginPath();
  93. ctx.rect(1 * this.state.tileWidth, -1 * this.state.tileWidth, this.state.tileWidth, this.state.tileWidth)
  94. ctx.fill();
  95. ctx.restore();
  96. }
  97. triggerFlip(tweenManager) {
  98. this.targetFlip *= -1;
  99. let tween = new Tween(this, {flip: this.targetFlip}, 300, Easing.Cubic.EaseOut, () => {
  100. this.flip = this.targetFlip;
  101. });
  102. tweenManager.cancel(this.flipTweenId)
  103. this.flipTweenId = tweenManager.add(tween);
  104. }
  105. triggerRotate(tweenManager) {
  106. this.targetRotation ++;
  107. let tween = new Tween(this, {rotation: this.targetRotation * Math.PI / 2}, 300, Easing.Cubic.EaseOut, () => {
  108. this.targetRotation %= 4;
  109. this.rotation = this.targetRotation * (Math.PI / 2)
  110. });
  111. tweenManager.cancel(this.rotationTweenId)
  112. this.rotationTweenId = tweenManager.add(tween);
  113. }
  114. mouseDown(event, mousePoint, tweenManager) {
  115. let centerBounds = new Rectangle(
  116. this.position.x - this.state.tileWidth,
  117. this.position.y - this.state.tileWidth,
  118. this.state.tileWidth * 2,
  119. this.state.tileWidth * 2,
  120. )
  121. let wideBounds = new Rectangle(
  122. this.position.x - this.state.tileWidth * 2,
  123. this.position.y - this.state.tileWidth * 2,
  124. this.state.tileWidth * 4,
  125. this.state.tileWidth * 4,
  126. )
  127. if(centerBounds.pointWithin(mousePoint)) {
  128. this.triggerRotate(tweenManager)
  129. } else if (wideBounds.pointWithin(mousePoint)) {
  130. this.triggerFlip(tweenManager);
  131. }
  132. }
  133. pointWithin(point) {
  134. let centerBounds = new Rectangle(
  135. this.position.x - this.state.tileWidth,
  136. this.position.y - this.state.tileWidth,
  137. this.state.tileWidth * 2,
  138. this.state.tileWidth * 2,
  139. )
  140. return centerBounds.pointWithin(point)
  141. }
  142. }