Advertisement
EmilySamantha80

JavaScript Pong

Oct 27th, 2017
552
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="utf-8" />
  5.         <meta name="viewport" content="width=device-width, initial-scale=1" />
  6.         <script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
  7.         <title>ESH Pong</title>
  8.     </head>
  9.     <body style="overflow:hidden;width:100%;height:100%;">
  10.         <div id="gameBoard" style="position:absolute;">
  11.         </div>
  12.         <script type="text/javascript">
  13.             // When the page finishes loading, start things up
  14.             $(document).ready(function () {
  15.                 // Let's begin!
  16.                 eshPong.start();
  17.             });
  18.  
  19.             // Create the "namespace" for eshPong
  20.             // Functions declared with namespace.fname = function() {} will be public. Functions created with the function keyword are private.
  21.             (function (eshPong, $, undefined) {
  22.                 // Whether the game is in progress or not. Setting this to false stops the automatic movement of the ball and the CPU paddle
  23.                 var inGame = false;
  24.  
  25.                 // Holds the balls that are on the board. We're only using one right now
  26.                 var balls = new Array();
  27.  
  28.                 // Holds the paddles that are on the board.
  29.                 var paddles = new Array();
  30.  
  31.                 // Default configuration
  32.                 var config = {
  33.                     boardWidth: window.innerWidth - 10,         // Game board width
  34.                     boardHeight: window.innerHeight - 10,       // Game board height
  35.                     boardBackgroundColor: "#EEEEEE",            // Game board background color
  36.                     boardBorderColor: "blue",                   // Game board border color
  37.                     boardBorderWidth: "5px",                    // Game board border width
  38.                     boardBorderStyle: "solid",                  // Game board border style
  39.                     debugMessageColor: "black",                 // Debug message color
  40.                     goalBuffer: 20,                             // Pixels between the wall and the paddle
  41.                     ballWidth: 40,                              // Ball width
  42.                     ballHeight: 40,                             // Ball height
  43.                     ballBackgroundColor: "green",               // Ball background color
  44.                     ballBorderColor: "black",                   // Ball border color
  45.                     ballBorderWidth: "1px",                     // Ball border width
  46.                     ballBorderStyle: "solid",                   // Ball border style
  47.                     paddleWidth: 10,                            // Paddle width
  48.                     paddleHeight: 200,                          // Paddle height
  49.                     paddleBackgroundColor: "red",               // Paddle background color
  50.                     paddleBorderColor: "black",                 // Paddle border color
  51.                     paddleBorderWidth: "1px",                   // Paddle border width
  52.                     paddleBorderStyle: "solid",                 // Paddle border style
  53.                     stepX: -10,                                 // Number of pixels the ball moves horizontally in each step
  54.                     stepY: 0,                                   // Number of pixels the ball moves vertically in each step (this will be between -10 and 10 dynamically depending on where the ball hits the paddle)
  55.                     stepInterval: 10,                           // Number of ms between ball steps
  56.                     cpuPaddleStep: 7,                           // Number of pixels the CPU paddle moves vertically in each step
  57.                     cpuPaddleStepInterval: 10,                  // Number of ms between paddle steps
  58.                 }
  59.  
  60.                 // Holds the player scores
  61.                 var score = new Array();
  62.  
  63.                 // Holds the debug messages that are displayed on the screen
  64.                 var message = "";
  65.  
  66.                 // Proves Eugene wrong that setTimeout() to the same function doesn't create memory issues
  67.                 function testSetTimeout(a) {
  68.                     $("body").html(a);
  69.                     var v = new Array();
  70.                     for (var i = 0; i < 20000; i++)
  71.                         v.push("abcdefghijklmnopqrstuvwxyz");
  72.                     setTimeout(function () { testSetTimeout(a + 1); }, 0);
  73.                 }
  74.  
  75.                 // Kick off the game
  76.                 eshPong.start = function () {
  77.                     // Uncomment the following to test setTimeout() memory usage
  78.                     // testSetTimeout(0);return;
  79.  
  80.                     //Initialize the score
  81.                     score.push(0);
  82.                     score.push(0);
  83.  
  84.                     writeDebug("ESH Pong v1.0");
  85.                     writeDebug("(c)2017 Emily Heiner (emilysamantha80@gmail.com)");
  86.                     writeDebug("Works best in IE/Edge");
  87.  
  88.                     // Reset the board, starting the game
  89.                     resetBoard();
  90.                 }
  91.  
  92.                 // Writes a message to the screen
  93.                 function writeDebug(msg) {
  94.                     message = msg + "<br/>" + message;
  95.                     var debug = $("#debugMessage");
  96.                     if (debug.length) {
  97.                         debug.html('').html(message);
  98.                     }
  99.                 }
  100.  
  101.                 // Resets the board and kicks off a new round
  102.                 function resetBoard() {
  103.                     // Kill the automatic ball and paddle movement
  104.                     inGame = false;
  105.  
  106.                     // Get the game board
  107.                     var board = $("#gameBoard");
  108.                     // Clear the game board
  109.                     board.html('');
  110.                     // Reset is properties
  111.                     board.css("position", "absolute");
  112.                     board.css("top", 0);
  113.                     board.css("left", 0);
  114.                     board.css("width", config.boardWidth);
  115.                     board.css("height", config.boardHeight);
  116.                     board.css("backgroundColor", config.boardBackgroundColor);
  117.                     board.css("borderWidth", config.boardBorderWidth);
  118.                     board.css("borderStyle", config.boardBorderStyle);
  119.                     board.css("borderColor", config.boardBorderColor);
  120.  
  121.                     // Create the div to hold debug messages
  122.                     var debug = $("<div/>");
  123.                     debug.css("position", "absolute");
  124.                     debug.css("top", 2);
  125.                     debug.css("left", 2);
  126.                     debug.css("width", "100%");
  127.                     debug.css("height", "100%");
  128.                     debug.attr("id", "debugMessage");
  129.                     debug.css("color", config.debugMessageColor)
  130.                     // Set the debug div contents to the debug messages
  131.                     debug.html(message);
  132.                     // Place the debug div on the board
  133.                     board.append(debug);
  134.  
  135.                     // Create and place the balls on the screen
  136.                     createBalls();
  137.                     // Create and place the paddles on the screen
  138.                     createPaddles();
  139.  
  140.                     // Kick off the automatic movement of balls and paddles after a specified time
  141.                     writeDebug("Get Ready...");
  142.                     setTimeout(function () { inGame = true; writeDebug("GO!"); moveBalls(); moveCpuPaddle(); }, 1000);
  143.  
  144.                 }
  145.  
  146.                 // Check if the ball hit a paddle
  147.                 function detectHit() {
  148.                     // Loop through the balls
  149.                     for (var i = 0; i < balls.length; i++) {
  150.                         var ball = balls[i]; // The ball we're working with
  151.                         var lpaddle = paddles[0]; // Player paddle
  152.                         var rpaddle = paddles[1]; // CPU paddle
  153.  
  154.                         // Find the midpoint of both paddles
  155.                         var midLPaddle = parseInt(lpaddle.y + (lpaddle.height / 2));
  156.                         var midRPaddle = parseInt(rpaddle.y + (rpaddle.height / 2));
  157.  
  158.                         // Check if the ball is past the left paddle
  159.                         if (ball.x <= config.goalBuffer + lpaddle.width) {
  160.                             // Check if the ball did not hit the paddle
  161.                             if ((ball.y < lpaddle.y - ball.height || ball.y > lpaddle.y + lpaddle.height)) {
  162.                                 // The ball missed the paddle
  163.                                 score[1]++;
  164.                                 writeDebug("CPU Win: " + score[0] + " to " + score[1]);
  165.                                 resetBoard();
  166.                             } else {
  167.                                 // The ball hit the paddle
  168.                                 if (ball.y >= midLPaddle) {
  169.                                     // The ball hit below the middle of the paddle. Calculate the angle based on where it hit on the paddle
  170.                                     // TODO: Figure out why I need the +3 at the end to make the numbers work
  171.                                     var step = parseInt(Math.abs(((ball.y - midLPaddle) / (lpaddle.height / 2)) * 10)) + 3;
  172.                                     //writeDebug("LPADDLE-STEP: " + step);
  173.                                     ball.stepY = step;
  174.                                 } else {
  175.                                     // The ball hit above the middle of the paddle. Calculate the angle based on where it hit on the paddle
  176.                                     var step = parseInt(-Math.abs(((ball.y - midLPaddle) / (lpaddle.height / 2)) * 10));
  177.                                     //writeDebug("LPADDLE-STEP: " + step);
  178.                                     ball.stepY = step;
  179.                                 }
  180.                             }
  181.                         }
  182.                         // Check if the ball is past the right paddle
  183.                         else if (ball.x >= config.boardWidth - config.goalBuffer - rpaddle.width - ball.width) {
  184.                             // Check if the ball did not hit the paddle
  185.                             if ((ball.y < rpaddle.y - ball.height || ball.y > rpaddle.y + lpaddle.height)) {
  186.                                 // The ball missed the paddle
  187.                                 score[0]++;
  188.                                 writeDebug("Player Win: " + score[0] + " to " + score[1]);
  189.                                 resetBoard();
  190.                             } else {
  191.                                 // The ball hit the paddle
  192.                                 if (ball.y >= midRPaddle) {
  193.                                     // The ball hit below the middle of the paddle. Calculate the angle based on where it hit on the paddle
  194.                                     // TODO: Figure out why I need the +3 at the end to make the numbers work
  195.                                     var step = parseInt(Math.abs(((ball.y - midRPaddle) / (rpaddle.height / 2)) * 10)) + 3;
  196.                                     //writeDebug("RPADDLE-STEP: " + step);
  197.                                     ball.stepY = step;
  198.                                 } else {
  199.                                     // The ball hit above the middle of the paddle. Calculate the angle based on where it hit on the paddle
  200.                                     var step = parseInt(-Math.abs(((ball.y - midRPaddle) / (rpaddle.height / 2)) * 10));
  201.                                     //writeDebug("RPADDLE-STEP: " + step);
  202.                                     ball.stepY = step;
  203.                                 }
  204.                             }
  205.                         }
  206.  
  207.                     }
  208.                 }
  209.  
  210.                 // Moves the CPU paddle
  211.                 function moveCpuPaddle(num) {
  212.                     // Time how long the function takes to have the interval be as close as possible to the correct interval
  213.                     var start = new Date().getTime();
  214.  
  215.                     // Get the ball, of which we only care about the first one
  216.                     var ball = balls[0];
  217.                     // Get the CPU paddle
  218.                     var paddle = paddles[1];
  219.  
  220.                     //Find the middle of the paddle
  221.                     var midPaddle = parseInt(paddle.y + (paddle.height / 2));
  222.  
  223.                     //Move the paddle
  224.                     if (ball.stepY > 0 && ball.y > paddle.y + ball.height) {
  225.                         // Move down
  226.                         //writeDebug("UP/Ball:" + ball.y + "/Paddle:" + paddle.y);
  227.                         paddle.y += config.cpuPaddleStep;
  228.                     } else if (ball.stepY < 0 && ball.y < paddle.y + paddle.height - ball.height) {
  229.                         // Move up
  230.                         //writeDebug("DOWN/Ball:" + ball.y + "/Paddle:" + paddle.y);
  231.                         paddle.y -= config.cpuPaddleStep;
  232.                     }
  233.  
  234.                     //Keep the paddle in bounds
  235.                     if (paddle.y < 0)
  236.                         paddle.y = 0;
  237.                     else if (paddle.y + paddle.height > config.boardHeight)
  238.                         paddle.y = config.boardHeight - paddle.height;
  239.  
  240.                     // Elapsed time since the start of the function
  241.                     var elapsed = new Date().getTime() - start;
  242.  
  243.                     //Move the paddle
  244.                     $("#" + paddle.id).animate({
  245.                         top: paddle.y,
  246.                     }, {
  247.                             duration: config.cpuPaddleStepInterval - elapsed,
  248.                             easing: "linear",
  249.                             complete: function () {
  250.                                 // Check if a round is in progress. Keep it going if it is
  251.                                 if (inGame)
  252.                                     moveCpuPaddle();
  253.                             }
  254.                         });
  255.                 }
  256.  
  257.                 // Moves the balls around
  258.                 function moveBalls() {
  259.                     // Time how long the function takes to have the interval be as close as possible to the correct interval
  260.                     var start = new Date().getTime();
  261.  
  262.                     // Loop through each ball
  263.                     for (var i = 0; i < balls.length; i++) {
  264.                         //Get the current ball
  265.                         var ball = balls[i];
  266.  
  267.                         //Process X movement
  268.                         if (ball.stepX < 0) {
  269.                             // Ball is traveling to the left
  270.                             if (ball.x < config.goalBuffer + paddles[0].width) {
  271.                                 // Ball hit the left wall. Reverse the direction
  272.                                 ball.stepX = ball.stepX * -1;
  273.                                 // Since we hit the edge, place the ball at the edge of the paddle
  274.                                 ball.x = config.goalBuffer + paddles[0].width;
  275.                             } else {
  276.                                 // Move the ball
  277.                                 ball.x = ball.x + ball.stepX;
  278.                             }
  279.                         } else {
  280.                             // Ball is traveling to the right
  281.                             if (ball.x > config.boardWidth - config.goalBuffer - paddles[1].width - ball.width) {
  282.                                 // Ball hit the right wall. Reverse the direction
  283.                                 ball.stepX = ball.stepX * -1;
  284.                                 // Since we hit the edge, place the ball at the edge of the paddle.
  285.                                 ball.x = config.boardWidth - config.goalBuffer - paddles[1].width - ball.width;
  286.                             } else {
  287.                                 // Move the ball
  288.                                 ball.x = ball.x + ball.stepX;
  289.                             }
  290.                         }
  291.  
  292.                         //Process Y movement
  293.                         if (ball.stepY < 0) {
  294.                             // Ball is traveling up
  295.                             if (ball.y < 0) {
  296.                                 // Hit the top wall, reverse the direction
  297.                                 ball.stepY = ball.stepY * -1;
  298.                             }
  299.                         } else {
  300.                             // Ball is traveling down
  301.                             if (ball.y > config.boardHeight - ball.height) {
  302.                                 // Hit the bottom wall, reverse the direction
  303.                                 ball.stepY = ball.stepY * -1;
  304.                             }
  305.                         }
  306.                         // Move the ball
  307.                         ball.y = ball.y + ball.stepY;
  308.  
  309.                         var elapsed = new Date().getTime() - start;
  310.  
  311.                         //Move the ball
  312.                         $("#" + ball.id).animate({
  313.                             left: ball.x,
  314.                             top: ball.y
  315.                         }, {
  316.                                 duration: config.stepInterval - elapsed,
  317.                                 easing: "linear",
  318.                                 complete: function () {
  319.                                     // Check if a round is in progress. Run the hit detection and keep it going if it is
  320.                                     if (inGame) {
  321.                                         detectHit();
  322.                                         moveBalls();
  323.                                     }
  324.                                 }
  325.                             });
  326.                     }
  327.  
  328.                 }
  329.  
  330.                 // Defines and creates the paddles
  331.                 function createPaddles() {
  332.                     // Clear out the paddle array
  333.                     paddles = new Array();
  334.  
  335.                     // Define the first paddle
  336.                     var paddle = {
  337.                         x: parseInt(config.goalBuffer - (config.paddleWidth / 2)),
  338.                         y: 0,
  339.                         width: config.paddleWidth,
  340.                         height: config.paddleHeight,
  341.                         backgroundColor: config.paddleBackgroundColor,
  342.                         borderWidth: config.paddleBorderWidth,
  343.                         borderStyle: config.paddleBorderStyle,
  344.                         borderColor: config.paddleBorderColor,
  345.                         id: null,
  346.                     }
  347.                     // Put the first paddle in the paddle array
  348.                     paddles.push(paddle);
  349.  
  350.                     // Define the second paddle
  351.                     var paddle = {
  352.                         x: config.boardWidth - config.goalBuffer - config.paddleWidth,
  353.                         y: parseInt((config.boardHeight / 2) - (config.paddleHeight / 2)),
  354.                         width: 10,
  355.                         height: 200,
  356.                         backgroundColor: config.paddleBackgroundColor,
  357.                         borderWidth: config.paddleBorderWidth,
  358.                         borderStyle: config.paddleBorderStyle,
  359.                         borderColor: config.paddleBorderColor,
  360.                         id: null,
  361.                     }
  362.                     // Put the second paddle in the array
  363.                     paddles.push(paddle);
  364.  
  365.                     // Create each paddle on the screen
  366.                     for (var i = 0; i < paddles.length; i++) {
  367.                         // Create the paddle and save the ID of the paddle
  368.                         paddles[i].id = createPaddle(i);
  369.                     }
  370.  
  371.                     // Track the left paddle with the mouse vertical movement
  372.                     $(document).on('mousemove', function (e) {
  373.                         // Move the paddle
  374.                         $("#" + paddles[0].id).css("top", e.pageY - (config.paddleHeight / 2));
  375.                         // Save the location of the paddle
  376.                         paddles[0].y = e.pageY - (config.paddleHeight / 2);
  377.                     });
  378.                 }
  379.  
  380.                 // Create a paddle and show it on the screen
  381.                 function createPaddle(loc) {
  382.                     // Get the paddle we're working with
  383.                     var paddle = paddles[loc];
  384.  
  385.                     // Create the paddle div and set its properties
  386.                     var paddleDiv = $("<div/>");
  387.                     paddleDiv.css("top", paddle.y);
  388.                     paddleDiv.css("left", paddle.x);
  389.                     paddleDiv.css("width", paddle.width);
  390.                     paddleDiv.css("height", paddle.height);
  391.                     paddleDiv.css("backgroundColor", paddle.backgroundColor);
  392.                     paddleDiv.css("borderWidth", paddle.borderWidth);
  393.                     paddleDiv.css("borderStyle", paddle.borderStyle);
  394.                     paddleDiv.css("borderColor", paddle.borderColor);
  395.                     paddleDiv.css("position", "absolute");
  396.                     paddleDiv.attr("id", "paddle_" + loc);
  397.                     // Place the paddle on the game board
  398.                     $("#gameBoard").append(paddleDiv);
  399.                     // Return the paddle ID
  400.                     return paddleDiv.attr("id");
  401.  
  402.                 }
  403.  
  404.                 // Defines and creates the balls
  405.                 function createBalls() {
  406.                     // Clear out the ball array
  407.                     balls = new Array();
  408.  
  409.                     // Define the first ball
  410.                     var ball = {
  411.                         x: parseInt((config.boardWidth / 2) - (config.ballWidth / 2)),
  412.                         y: parseInt((config.boardHeight / 2) - (config.ballHeight / 2)),
  413.                         width: config.ballWidth,
  414.                         height: config.ballHeight,
  415.                         stepX: config.stepX,
  416.                         stepY: config.stepY,
  417.                         backgroundColor: config.ballBackgroundColor,
  418.                         borderWidth: config.ballBorderWidth,
  419.                         borderStyle: config.ballBorderStyle,
  420.                         borderColor: config.ballBorderColor,
  421.                         id: null,
  422.                     }
  423.  
  424.                     // Put the ball into the array
  425.                     balls.push(ball);
  426.  
  427.                     // Create each ball on the screen
  428.                     for (var i = 0; i < balls.length; i++) {
  429.                         // Create the ball and save the ID of the paddle
  430.                         balls[i].id = createBall(i);
  431.                     }
  432.                 }
  433.  
  434.                 // Create a ball and show it on the screen
  435.                 function createBall(loc) {
  436.                     // Get the ball we're working with
  437.                     var ball = balls[loc];
  438.  
  439.                     // Create the ball div and set its properties
  440.                     var ballDiv = $("<div/>");
  441.                     ballDiv.css("top", ball.y);
  442.                     ballDiv.css("left", ball.x);
  443.                     ballDiv.css("width", ball.width);
  444.                     ballDiv.css("height", ball.height);
  445.                     ballDiv.css("backgroundColor", ball.backgroundColor);
  446.                     ballDiv.css("borderWidth", ball.borderWidth);
  447.                     ballDiv.css("borderStyle", ball.borderStyle);
  448.                     ballDiv.css("borderColor", ball.borderColor);
  449.                     ballDiv.css("position", "absolute");
  450.                     ballDiv.css("will-change", "transform");
  451.                     ballDiv.attr("id", "ball_" + loc);
  452.                     // Place the ball on the game board
  453.                     $("#gameBoard").append(ballDiv);
  454.                     // Return the ball ID
  455.                     return ballDiv.attr("id");
  456.                 }
  457.  
  458.             }(window.eshPong = window.eshPong || {}, jQuery));
  459.         </script>
  460.     </body>
  461. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement