Advertisement
Crenox

Pong - HTML5 Game Programming Tutorial [Javascript]

Jul 12th, 2014
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.47 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang = "en">
  3. <head>
  4. <meta charset = "UTF 8">
  5. <title>Pong</title>
  6.  
  7. <!-- Basic styling, centering the canvas -->
  8. <style>
  9. canvas
  10. {
  11. display: block;
  12. position: absolute;
  13. margin: auto;
  14. top: 0;
  15. bottom: 0;
  16. left: 0;
  17. right: 0;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22. <script>
  23.  
  24. /*
  25. * Constants
  26. */
  27. var WIDTH = 700, HEIGHT = 600, pi = Math.PI;
  28. var UpArrow = 38, DownArrow = 40;
  29.  
  30. /*
  31. * Game Elements
  32. */
  33. var canvas, ctx, keystate;
  34. var player, ai, ball;
  35.  
  36. player =
  37. {
  38. x: null,
  39. y: null,
  40. width: 20,
  41. height: 100,
  42.  
  43. /*
  44. * Update the position depending on pressed keys
  45. */
  46. update: function()
  47. {
  48. if (keystate[UpArrow]) this.y -= 7;
  49. if (keystate[DownArrow]) this.y += 7;
  50. // keep the paddle inside of the canvas
  51. this.y = Math.max(Math.min(this.y, HEIGHT - this.height), 0);
  52. },
  53.  
  54. /*
  55. * Draw the player paddle to the canvas
  56. */
  57. draw: function()
  58. {
  59. ctx.fillRect(this.x, this.y, this.width, this.height);
  60. }
  61. };
  62.  
  63. ai =
  64. {
  65. x: null,
  66. y: null,
  67. width: 20,
  68. height: 100,
  69.  
  70. /*
  71. * Update the position depending on the ball position
  72. */
  73. update: function()
  74. {
  75. // calculate ideal position
  76. var desty = ball.y - (this.height - ball.side) * 0.5;
  77. // ease the movement towards the ideal position
  78. this.y += (desty - this.y) * 0.1;
  79. // keep the paddle inside of the canvas
  80. this.y = Math.max(Math.min(this.y, HEIGHT - this.height), 0);
  81. },
  82.  
  83. /*
  84. * Draw the ai paddle to the canvas
  85. */
  86. draw: function()
  87. {
  88. ctx.fillRect(this.x, this.y, this.width, this.height);
  89. }
  90. };
  91.  
  92. ball =
  93. {
  94. x: null,
  95. y: null,
  96. vel: null,
  97. side: 20,
  98. speed: 12,
  99.  
  100. serve: function(side)
  101. {
  102. // set the x and y position
  103. var r = Math.random();
  104. this.x = side === 1 ? player.x + player.width : ai.x - this.side;
  105. this.y = (HEIGHT - this.side)* r;
  106.  
  107. // calculate out-angle, higher/lower on the y-axis =>
  108. // steeper angle
  109. var phi = 0.1 * pi * (1 - 2 * r);
  110. // set velocity direction and magnitude
  111. this.vel =
  112. {
  113. x: side * this.speed * Math.cos(phi),
  114. y: this.speed * Math.sin(phi)
  115. }
  116. }
  117.  
  118. /*
  119. * Update the ball position and keep it within the canvas
  120. */
  121. update: function()
  122. {
  123. // update position with current velocity
  124. this.x += this.vel.x;
  125. this.y += this.vel.y;
  126.  
  127. // checks if out out of the canvas in the y direction
  128. if (0 > this.y || this.y + this.side > HEIGHT)
  129. {
  130. // calculate and add the right offset, i.e. how far
  131. // inside of the canvas the ball is
  132. var offset = this.vel.y < 0 ? 0 - this.y : HEIGHT - (this.y + this.side);
  133. this.y += 2 * offset;
  134. // mirror the y velocity
  135. this.vel.y *= -1;
  136. }
  137.  
  138. // helper function to check intesectiont between two
  139. // axis aligned bounding boxex (AABB)
  140. var AABBIntersect = function(ax, ay, aw, ah, bx, by, bw, bh)
  141. {
  142. return ax < bx + bw && ay < by + bh && bx < ax + aw && by < ay + ah;
  143. };
  144.  
  145. // check against target paddle to check collision in x direction
  146. var pdle = this.vel.x < 0 ? player : ai;
  147. if (AABBIntersect(pdle.x, pdle.y, pdle.width, pdle.height, this.x, this.y, this.side, this.side))
  148. {
  149. // set the x position and calculate relfection angle
  150. this.x = pdle === player ? player.x + player.width : ai.x - this.side;
  151. var n = (this.y + this.side - pdle.y) / (pdle.height + this.side);
  152. var phi = 0.25 * pi * (2 * n - 1); // pi / 4 = 45
  153. // calculate smash value and update velocity
  154. var smash = Math.abs(phi) > 0.2 * pi ? 1.5 : 1;
  155. this.vel.x = smash * (pdle === player ? 1 : -1) * this.speed * Math.cos(phi);
  156. this.vel.y = smash * this.speed * Math.sin(phi);
  157. }
  158.  
  159. // reset the ball when ball outside of the canvas in the x direction
  160. if (0 > this.x + this.side || this.x > WIDTH)
  161. {
  162. this.serve(pdle === player ? 1 : -1);
  163. }
  164. },
  165.  
  166. /*
  167. * Draw the ball to the canvas
  168. */
  169. draw: function()
  170. {
  171. ctx.fillRect(this.x, this.y, this.side, this.side);
  172. }
  173. };
  174.  
  175. /*
  176. * Starts the game
  177. */
  178. function main()
  179. {
  180. // create, initiate and append game canvas
  181. canvas = document.createElement("canvas");
  182. canvas.width = WIDTH;
  183. canvas.height = HEIGHT;
  184. ctx = canvas.getContext("2d");
  185. document.body.appendChild(canvas);
  186.  
  187. keystate = {};
  188. // keep track of keyboard presses
  189. document.addEventListener("keydown", function(evt)
  190. {
  191. keystate[evt.keyCode] = true;
  192. });
  193.  
  194. document.addEventListener("keyup", function(evt)
  195. {
  196. delete keystate[evt.keyCode];
  197. });
  198.  
  199. init(); // initiate game ibjects
  200.  
  201. // game loop function
  202. var loop = function()
  203. {
  204. update();
  205. draw();
  206.  
  207. window.requestAnimationFrame(loop, canvas);
  208. };
  209.  
  210. window.requestAnimationFrame(loop, canvas);
  211. }
  212.  
  213. /*
  214. * Initiate game objects and set start positions
  215. */
  216.  
  217. function init()
  218. {
  219. player.x = player.width;
  220. player.y = (HEIGHT - player.height) / 2;
  221.  
  222. ai.x = WIDTH - (player.width + ai.width);
  223. ai.y = (HEIGHT - ai.height) / 2;
  224.  
  225. ball.serve(1);
  226. }
  227.  
  228. /*
  229. * Update all game objects
  230. */
  231.  
  232. function update()
  233. {
  234. ball.update();
  235. player.update();
  236. ai.update();
  237. }
  238.  
  239. /*
  240. * Clear canvas and draw all game objects and net
  241. */
  242. function draw()
  243. {
  244. ctx.fillRect(0, 0, WIDTH, HEIGHT);
  245.  
  246. ctx.save();
  247.  
  248. ctx.fillStyle = "#fff";
  249.  
  250. ball.draw();
  251. player.draw();
  252. ai.draw();
  253.  
  254. // draw the net
  255. var w = 4;
  256. var x = (WIDTH - w) * 0.5;
  257. var y = 0;
  258. var step = HEIGHT / 20; // how many net segments
  259. while(y < HEIGHT)
  260. {
  261. ctx.fillRect(x, y + step * 0.25, w, step * 0.5);
  262. y += step;
  263. }
  264.  
  265. ctx.restore();
  266. }
  267.  
  268. // start and run the game
  269. main();
  270. </script>
  271. </body>
  272. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement