Advertisement
Guest User

Untitled

a guest
Mar 20th, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.81 KB | None | 0 0
  1. type Pair = [number, number];
  2. type Entity = {
  3. dimensions: Pair;
  4. pos: Pair;
  5. img: HTMLImageElement;
  6. collider: number;
  7. };
  8. type GameState = {
  9. keyCode: number | null;
  10. player: Entity;
  11. enemy: Entity;
  12. };
  13.  
  14. function game() {
  15. //SETUP
  16. let canvas = document.getElementById("canvas") as HTMLCanvasElement;
  17. let context = canvas.getContext("2d")!;
  18. canvas.width = 750;
  19. canvas.height = 500;
  20.  
  21. let playerImg = new Image();
  22. playerImg.src = "/assets/player.png";
  23.  
  24. let enemyImg = new Image();
  25. enemyImg.src = "/assets/enemy.png";
  26.  
  27. document.addEventListener("keydown", e => {
  28. gs.keyCode = e.keyCode;
  29. });
  30.  
  31. document.addEventListener("keyup", () => {
  32. gs.keyCode = null;
  33. });
  34.  
  35. let gs: GameState = {
  36. keyCode: null,
  37. player: {
  38. pos: [100, 100],
  39. img: playerImg,
  40. collider: 20.0,
  41. dimensions: [50, 50]
  42. },
  43. enemy: {
  44. pos: [400, 300],
  45. img: enemyImg,
  46. collider: 75,
  47. dimensions: [150, 150]
  48. }
  49. };
  50.  
  51. const runLoop = () => {
  52. requestAnimationFrame(() => loop(gs, context, runLoop));
  53. };
  54. runLoop();
  55. }
  56.  
  57. function loop(gs: GameState, ctx: CanvasRenderingContext2D, done: Function) {
  58. //next version click on a spot and it moves to there?
  59.  
  60. ctx.clearRect(0, 0, 750, 500);
  61. gs.player.pos = nextPlayerPosition(gs);
  62.  
  63. //TRIG PART
  64.  
  65. //knowing 2/3 points (player & enemy) we can find the right angle point
  66. let ra: Pair = [gs.player.pos[0], gs.enemy.pos[1]];
  67.  
  68. //then we can figure out the opposite and adjacent lengths
  69. let oppositeL = Math.max(gs.player.pos[1], ra[1]) - Math.min(gs.player.pos[1], ra[1]);
  70. let adjacentL = Math.max(gs.enemy.pos[0], ra[0]) - Math.min(gs.enemy.pos[0], ra[0]);
  71.  
  72. //from these we can reverse tan fn to get the alpha angle (angle at the enemys side)
  73. const alpha = Math.atan(oppositeL / adjacentL);
  74. //using alpha we can figure out the beta, the angle on the players side
  75. const beta = Math.PI - Math.PI / 2 - alpha;
  76.  
  77. //Have the player face the right angle so we can use the beta radians
  78. const hozRotation = gs.player.pos[1] < gs.enemy.pos[1] ? Math.PI : 0;
  79. //then use the beta to face the enemy
  80. const latRotation = beta * (gs.player.pos[1] < gs.enemy.pos[1] ? -1 : 1);
  81.  
  82. const collided = collisionDectection(gs.player, gs.enemy);
  83. renderRightTriangle(ctx, gs, ra);
  84. renderEntity(ctx, gs.player, hozRotation + latRotation);
  85. renderEntity(ctx, gs.enemy, 0);
  86. renderCollider(ctx, gs.player.pos, gs.player.collider, collided);
  87. renderCollider(ctx, gs.enemy.pos, gs.enemy.collider, collided);
  88. done();
  89. }
  90.  
  91. function renderEntity(ctx: CanvasRenderingContext2D, entity: Entity, rotation: number) {
  92. const offsets: Pair = [entity.dimensions[0] / 2, entity.dimensions[1] / 2];
  93. ctx.save();
  94. ctx.translate(entity.pos[0], entity.pos[1]);
  95. ctx.rotate(rotation);
  96. ctx.drawImage(entity.img, -offsets[0], -offsets[1], entity.dimensions[0], entity.dimensions[1]);
  97. ctx.restore();
  98. }
  99.  
  100. function renderCollider(
  101. ctx: CanvasRenderingContext2D,
  102. coord: Pair,
  103. radius: number,
  104. collided: boolean
  105. ) {
  106. ctx.save();
  107. ctx.beginPath();
  108. ctx.strokeStyle = collided ? "red" : "green";
  109. ctx.arc(coord[0], coord[1], radius, 0, Math.PI * 2);
  110. ctx.stroke();
  111. ctx.closePath();
  112. ctx.restore();
  113. }
  114.  
  115. function renderRightTriangle(ctx: CanvasRenderingContext2D, gs: GameState, ra: Pair) {
  116. ctx.save();
  117. ctx.beginPath();
  118. ctx.strokeStyle = "red";
  119. ctx.moveTo(gs.player.pos[0], gs.player.pos[1]);
  120. ctx.lineTo(ra[0], ra[1]);
  121. ctx.stroke();
  122. ctx.moveTo(gs.enemy.pos[0], gs.enemy.pos[1]);
  123. ctx.lineTo(ra[0], ra[1]);
  124. ctx.stroke();
  125. ctx.moveTo(gs.enemy.pos[0], gs.enemy.pos[1]);
  126. ctx.lineTo(gs.player.pos[0], gs.player.pos[1]);
  127. ctx.stroke();
  128. ctx.closePath();
  129. ctx.restore();
  130. }
  131.  
  132. function collisionDectection(a: Entity, b: Entity): boolean {
  133. //find the hypotenuse length between
  134. //check if hyp length > a.col + b.col
  135. const deltaX = a.pos[0];
  136. const deltaY = b.pos[1];
  137. const oppositeL = Math.max(a.pos[1], deltaY) - Math.min(a.pos[1], deltaY);
  138. const adjacentL = Math.max(b.pos[0], deltaX) - Math.min(b.pos[0], deltaX);
  139. //Pythagorus to get the hypotenuse
  140. const hypotenuseL = Math.sqrt(Math.pow(oppositeL, 2) + Math.pow(adjacentL, 2));
  141. const collided = hypotenuseL < a.collider + b.collider;
  142. return collided;
  143. }
  144.  
  145. function nextPlayerPosition(gs: GameState): Pair {
  146. const changes = movement.get(gs.keyCode || 0) || [0, 0];
  147. return [gs.player.pos[0] + changes[0], gs.player.pos[1] + changes[1]];
  148. }
  149.  
  150. const UP = 38;
  151. const DOWN = 40;
  152. const LEFT = 37;
  153. const RIGHT = 39;
  154. const speed = 2;
  155. const movement = new Map<number, Pair>([
  156. [UP, [0, -speed]],
  157. [DOWN, [0, speed]],
  158. [LEFT, [-speed, 0]],
  159. [RIGHT, [speed, 0]]
  160. ]);
  161.  
  162. game();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement