Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
- <title>ESH Pong</title>
- </head>
- <body style="overflow:hidden;width:100%;height:100%;">
- <div id="gameBoard" style="position:absolute;">
- </div>
- <script type="text/javascript">
- // When the page finishes loading, start things up
- $(document).ready(function () {
- // Let's begin!
- eshPong.start();
- });
- // Create the "namespace" for eshPong
- // Functions declared with namespace.fname = function() {} will be public. Functions created with the function keyword are private.
- (function (eshPong, $, undefined) {
- // Whether the game is in progress or not. Setting this to false stops the automatic movement of the ball and the CPU paddle
- var inGame = false;
- // Holds the balls that are on the board. We're only using one right now
- var balls = new Array();
- // Holds the paddles that are on the board.
- var paddles = new Array();
- // Default configuration
- var config = {
- boardWidth: window.innerWidth - 10, // Game board width
- boardHeight: window.innerHeight - 10, // Game board height
- boardBackgroundColor: "#EEEEEE", // Game board background color
- boardBorderColor: "blue", // Game board border color
- boardBorderWidth: "5px", // Game board border width
- boardBorderStyle: "solid", // Game board border style
- debugMessageColor: "black", // Debug message color
- goalBuffer: 20, // Pixels between the wall and the paddle
- ballWidth: 40, // Ball width
- ballHeight: 40, // Ball height
- ballBackgroundColor: "green", // Ball background color
- ballBorderColor: "black", // Ball border color
- ballBorderWidth: "1px", // Ball border width
- ballBorderStyle: "solid", // Ball border style
- paddleWidth: 10, // Paddle width
- paddleHeight: 200, // Paddle height
- paddleBackgroundColor: "red", // Paddle background color
- paddleBorderColor: "black", // Paddle border color
- paddleBorderWidth: "1px", // Paddle border width
- paddleBorderStyle: "solid", // Paddle border style
- stepX: -10, // Number of pixels the ball moves horizontally in each step
- 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)
- stepInterval: 10, // Number of ms between ball steps
- cpuPaddleStep: 7, // Number of pixels the CPU paddle moves vertically in each step
- cpuPaddleStepInterval: 10, // Number of ms between paddle steps
- }
- // Holds the player scores
- var score = new Array();
- // Holds the debug messages that are displayed on the screen
- var message = "";
- // Proves Eugene wrong that setTimeout() to the same function doesn't create memory issues
- function testSetTimeout(a) {
- $("body").html(a);
- var v = new Array();
- for (var i = 0; i < 20000; i++)
- v.push("abcdefghijklmnopqrstuvwxyz");
- setTimeout(function () { testSetTimeout(a + 1); }, 0);
- }
- // Kick off the game
- eshPong.start = function () {
- // Uncomment the following to test setTimeout() memory usage
- // testSetTimeout(0);return;
- //Initialize the score
- score.push(0);
- score.push(0);
- writeDebug("ESH Pong v1.0");
- writeDebug("(c)2017 Emily Heiner (emilysamantha80@gmail.com)");
- writeDebug("Works best in IE/Edge");
- // Reset the board, starting the game
- resetBoard();
- }
- // Writes a message to the screen
- function writeDebug(msg) {
- message = msg + "<br/>" + message;
- var debug = $("#debugMessage");
- if (debug.length) {
- debug.html('').html(message);
- }
- }
- // Resets the board and kicks off a new round
- function resetBoard() {
- // Kill the automatic ball and paddle movement
- inGame = false;
- // Get the game board
- var board = $("#gameBoard");
- // Clear the game board
- board.html('');
- // Reset is properties
- board.css("position", "absolute");
- board.css("top", 0);
- board.css("left", 0);
- board.css("width", config.boardWidth);
- board.css("height", config.boardHeight);
- board.css("backgroundColor", config.boardBackgroundColor);
- board.css("borderWidth", config.boardBorderWidth);
- board.css("borderStyle", config.boardBorderStyle);
- board.css("borderColor", config.boardBorderColor);
- // Create the div to hold debug messages
- var debug = $("<div/>");
- debug.css("position", "absolute");
- debug.css("top", 2);
- debug.css("left", 2);
- debug.css("width", "100%");
- debug.css("height", "100%");
- debug.attr("id", "debugMessage");
- debug.css("color", config.debugMessageColor)
- // Set the debug div contents to the debug messages
- debug.html(message);
- // Place the debug div on the board
- board.append(debug);
- // Create and place the balls on the screen
- createBalls();
- // Create and place the paddles on the screen
- createPaddles();
- // Kick off the automatic movement of balls and paddles after a specified time
- writeDebug("Get Ready...");
- setTimeout(function () { inGame = true; writeDebug("GO!"); moveBalls(); moveCpuPaddle(); }, 1000);
- }
- // Check if the ball hit a paddle
- function detectHit() {
- // Loop through the balls
- for (var i = 0; i < balls.length; i++) {
- var ball = balls[i]; // The ball we're working with
- var lpaddle = paddles[0]; // Player paddle
- var rpaddle = paddles[1]; // CPU paddle
- // Find the midpoint of both paddles
- var midLPaddle = parseInt(lpaddle.y + (lpaddle.height / 2));
- var midRPaddle = parseInt(rpaddle.y + (rpaddle.height / 2));
- // Check if the ball is past the left paddle
- if (ball.x <= config.goalBuffer + lpaddle.width) {
- // Check if the ball did not hit the paddle
- if ((ball.y < lpaddle.y - ball.height || ball.y > lpaddle.y + lpaddle.height)) {
- // The ball missed the paddle
- score[1]++;
- writeDebug("CPU Win: " + score[0] + " to " + score[1]);
- resetBoard();
- } else {
- // The ball hit the paddle
- if (ball.y >= midLPaddle) {
- // The ball hit below the middle of the paddle. Calculate the angle based on where it hit on the paddle
- // TODO: Figure out why I need the +3 at the end to make the numbers work
- var step = parseInt(Math.abs(((ball.y - midLPaddle) / (lpaddle.height / 2)) * 10)) + 3;
- //writeDebug("LPADDLE-STEP: " + step);
- ball.stepY = step;
- } else {
- // The ball hit above the middle of the paddle. Calculate the angle based on where it hit on the paddle
- var step = parseInt(-Math.abs(((ball.y - midLPaddle) / (lpaddle.height / 2)) * 10));
- //writeDebug("LPADDLE-STEP: " + step);
- ball.stepY = step;
- }
- }
- }
- // Check if the ball is past the right paddle
- else if (ball.x >= config.boardWidth - config.goalBuffer - rpaddle.width - ball.width) {
- // Check if the ball did not hit the paddle
- if ((ball.y < rpaddle.y - ball.height || ball.y > rpaddle.y + lpaddle.height)) {
- // The ball missed the paddle
- score[0]++;
- writeDebug("Player Win: " + score[0] + " to " + score[1]);
- resetBoard();
- } else {
- // The ball hit the paddle
- if (ball.y >= midRPaddle) {
- // The ball hit below the middle of the paddle. Calculate the angle based on where it hit on the paddle
- // TODO: Figure out why I need the +3 at the end to make the numbers work
- var step = parseInt(Math.abs(((ball.y - midRPaddle) / (rpaddle.height / 2)) * 10)) + 3;
- //writeDebug("RPADDLE-STEP: " + step);
- ball.stepY = step;
- } else {
- // The ball hit above the middle of the paddle. Calculate the angle based on where it hit on the paddle
- var step = parseInt(-Math.abs(((ball.y - midRPaddle) / (rpaddle.height / 2)) * 10));
- //writeDebug("RPADDLE-STEP: " + step);
- ball.stepY = step;
- }
- }
- }
- }
- }
- // Moves the CPU paddle
- function moveCpuPaddle(num) {
- // Time how long the function takes to have the interval be as close as possible to the correct interval
- var start = new Date().getTime();
- // Get the ball, of which we only care about the first one
- var ball = balls[0];
- // Get the CPU paddle
- var paddle = paddles[1];
- //Find the middle of the paddle
- var midPaddle = parseInt(paddle.y + (paddle.height / 2));
- //Move the paddle
- if (ball.stepY > 0 && ball.y > paddle.y + ball.height) {
- // Move down
- //writeDebug("UP/Ball:" + ball.y + "/Paddle:" + paddle.y);
- paddle.y += config.cpuPaddleStep;
- } else if (ball.stepY < 0 && ball.y < paddle.y + paddle.height - ball.height) {
- // Move up
- //writeDebug("DOWN/Ball:" + ball.y + "/Paddle:" + paddle.y);
- paddle.y -= config.cpuPaddleStep;
- }
- //Keep the paddle in bounds
- if (paddle.y < 0)
- paddle.y = 0;
- else if (paddle.y + paddle.height > config.boardHeight)
- paddle.y = config.boardHeight - paddle.height;
- // Elapsed time since the start of the function
- var elapsed = new Date().getTime() - start;
- //Move the paddle
- $("#" + paddle.id).animate({
- top: paddle.y,
- }, {
- duration: config.cpuPaddleStepInterval - elapsed,
- easing: "linear",
- complete: function () {
- // Check if a round is in progress. Keep it going if it is
- if (inGame)
- moveCpuPaddle();
- }
- });
- }
- // Moves the balls around
- function moveBalls() {
- // Time how long the function takes to have the interval be as close as possible to the correct interval
- var start = new Date().getTime();
- // Loop through each ball
- for (var i = 0; i < balls.length; i++) {
- //Get the current ball
- var ball = balls[i];
- //Process X movement
- if (ball.stepX < 0) {
- // Ball is traveling to the left
- if (ball.x < config.goalBuffer + paddles[0].width) {
- // Ball hit the left wall. Reverse the direction
- ball.stepX = ball.stepX * -1;
- // Since we hit the edge, place the ball at the edge of the paddle
- ball.x = config.goalBuffer + paddles[0].width;
- } else {
- // Move the ball
- ball.x = ball.x + ball.stepX;
- }
- } else {
- // Ball is traveling to the right
- if (ball.x > config.boardWidth - config.goalBuffer - paddles[1].width - ball.width) {
- // Ball hit the right wall. Reverse the direction
- ball.stepX = ball.stepX * -1;
- // Since we hit the edge, place the ball at the edge of the paddle.
- ball.x = config.boardWidth - config.goalBuffer - paddles[1].width - ball.width;
- } else {
- // Move the ball
- ball.x = ball.x + ball.stepX;
- }
- }
- //Process Y movement
- if (ball.stepY < 0) {
- // Ball is traveling up
- if (ball.y < 0) {
- // Hit the top wall, reverse the direction
- ball.stepY = ball.stepY * -1;
- }
- } else {
- // Ball is traveling down
- if (ball.y > config.boardHeight - ball.height) {
- // Hit the bottom wall, reverse the direction
- ball.stepY = ball.stepY * -1;
- }
- }
- // Move the ball
- ball.y = ball.y + ball.stepY;
- var elapsed = new Date().getTime() - start;
- //Move the ball
- $("#" + ball.id).animate({
- left: ball.x,
- top: ball.y
- }, {
- duration: config.stepInterval - elapsed,
- easing: "linear",
- complete: function () {
- // Check if a round is in progress. Run the hit detection and keep it going if it is
- if (inGame) {
- detectHit();
- moveBalls();
- }
- }
- });
- }
- }
- // Defines and creates the paddles
- function createPaddles() {
- // Clear out the paddle array
- paddles = new Array();
- // Define the first paddle
- var paddle = {
- x: parseInt(config.goalBuffer - (config.paddleWidth / 2)),
- y: 0,
- width: config.paddleWidth,
- height: config.paddleHeight,
- backgroundColor: config.paddleBackgroundColor,
- borderWidth: config.paddleBorderWidth,
- borderStyle: config.paddleBorderStyle,
- borderColor: config.paddleBorderColor,
- id: null,
- }
- // Put the first paddle in the paddle array
- paddles.push(paddle);
- // Define the second paddle
- var paddle = {
- x: config.boardWidth - config.goalBuffer - config.paddleWidth,
- y: parseInt((config.boardHeight / 2) - (config.paddleHeight / 2)),
- width: 10,
- height: 200,
- backgroundColor: config.paddleBackgroundColor,
- borderWidth: config.paddleBorderWidth,
- borderStyle: config.paddleBorderStyle,
- borderColor: config.paddleBorderColor,
- id: null,
- }
- // Put the second paddle in the array
- paddles.push(paddle);
- // Create each paddle on the screen
- for (var i = 0; i < paddles.length; i++) {
- // Create the paddle and save the ID of the paddle
- paddles[i].id = createPaddle(i);
- }
- // Track the left paddle with the mouse vertical movement
- $(document).on('mousemove', function (e) {
- // Move the paddle
- $("#" + paddles[0].id).css("top", e.pageY - (config.paddleHeight / 2));
- // Save the location of the paddle
- paddles[0].y = e.pageY - (config.paddleHeight / 2);
- });
- }
- // Create a paddle and show it on the screen
- function createPaddle(loc) {
- // Get the paddle we're working with
- var paddle = paddles[loc];
- // Create the paddle div and set its properties
- var paddleDiv = $("<div/>");
- paddleDiv.css("top", paddle.y);
- paddleDiv.css("left", paddle.x);
- paddleDiv.css("width", paddle.width);
- paddleDiv.css("height", paddle.height);
- paddleDiv.css("backgroundColor", paddle.backgroundColor);
- paddleDiv.css("borderWidth", paddle.borderWidth);
- paddleDiv.css("borderStyle", paddle.borderStyle);
- paddleDiv.css("borderColor", paddle.borderColor);
- paddleDiv.css("position", "absolute");
- paddleDiv.attr("id", "paddle_" + loc);
- // Place the paddle on the game board
- $("#gameBoard").append(paddleDiv);
- // Return the paddle ID
- return paddleDiv.attr("id");
- }
- // Defines and creates the balls
- function createBalls() {
- // Clear out the ball array
- balls = new Array();
- // Define the first ball
- var ball = {
- x: parseInt((config.boardWidth / 2) - (config.ballWidth / 2)),
- y: parseInt((config.boardHeight / 2) - (config.ballHeight / 2)),
- width: config.ballWidth,
- height: config.ballHeight,
- stepX: config.stepX,
- stepY: config.stepY,
- backgroundColor: config.ballBackgroundColor,
- borderWidth: config.ballBorderWidth,
- borderStyle: config.ballBorderStyle,
- borderColor: config.ballBorderColor,
- id: null,
- }
- // Put the ball into the array
- balls.push(ball);
- // Create each ball on the screen
- for (var i = 0; i < balls.length; i++) {
- // Create the ball and save the ID of the paddle
- balls[i].id = createBall(i);
- }
- }
- // Create a ball and show it on the screen
- function createBall(loc) {
- // Get the ball we're working with
- var ball = balls[loc];
- // Create the ball div and set its properties
- var ballDiv = $("<div/>");
- ballDiv.css("top", ball.y);
- ballDiv.css("left", ball.x);
- ballDiv.css("width", ball.width);
- ballDiv.css("height", ball.height);
- ballDiv.css("backgroundColor", ball.backgroundColor);
- ballDiv.css("borderWidth", ball.borderWidth);
- ballDiv.css("borderStyle", ball.borderStyle);
- ballDiv.css("borderColor", ball.borderColor);
- ballDiv.css("position", "absolute");
- ballDiv.css("will-change", "transform");
- ballDiv.attr("id", "ball_" + loc);
- // Place the ball on the game board
- $("#gameBoard").append(ballDiv);
- // Return the ball ID
- return ballDiv.attr("id");
- }
- }(window.eshPong = window.eshPong || {}, jQuery));
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement