Introduction :
The Pong game is a classic arcade game that simulates table tennis, where players control paddles to hit a ball back and forth. This implementation uses HTML, CSS, and JavaScript to create a simple and interactive version of Pong that runs directly in a web browser. The game is rendered on an HTML canvas and incorporates basic game mechanics like paddle movement, ball collision detection, and scoring.
Explanation :
Project Structure
HTML
The HTML provides the basic structure of the web page. It includes a <canvas>
element where the game is rendered. The canvas has a specific width and height, defining the playing area for the game. The <head>
section includes metadata and a <style>
block for CSS. The <body>
contains the canvas and the embedded JavaScript script.
CSS
The CSS is minimal and primarily styles the canvas. It sets a black background color for the canvas to create a clear contrast for the game elements (paddles and ball), and centers the canvas horizontally on the page.
JavaScript
The JavaScript contains the core logic of the game. It handles drawing the game elements, updating their positions, and responding to user interactions. Here’s a breakdown of the key components and logic:
Canvas Setup: The JavaScript starts by selecting the canvas element and getting its rendering context. This context (
ctx
) is used to draw on the canvas.Game Elements Initialization: Variables are defined for the paddles and the ball. These include the dimensions and initial positions of the paddles, as well as the size, position, and speed of the ball.
Drawing Functions: Functions are defined to draw the paddles and the ball. The
drawRect
function draws a rectangle (used for paddles), and thedrawCircle
function draws a circle (used for the ball). Another function,draw
, uses these to render the entire game state on the canvas.Update Function: The
update
function handles the game’s logic:- Ball Movement: The ball’s position is updated based on its current speed.
- Collision Detection: The function checks for collisions between the ball and the top/bottom edges of the canvas, as well as the paddles. If a collision is detected, the ball’s direction is reversed.
- Out of Bounds: If the ball goes out of bounds (passes beyond the paddles), it is reset to the center of the canvas.
Reset Ball Position: A function
resetBall
is defined to reposition the ball to the center of the canvas and reverse its direction.User Interaction: The game listens for mouse movements to control the left paddle. A function
calculateMousePos
determines the mouse’s position relative to the canvas, and an event listener updates the left paddle’s position based on the mouse’s Y-coordinate.Game Loop: The
gameLoop
function is the main loop of the game. It continuously calls thedraw
andupdate
functions to keep the game running, usingrequestAnimationFrame
for smooth animations.
Purpose of Functions
drawRect(x, y, width, height, color)
: Draws a rectangle (used for paddles and the background).drawCircle(x, y, radius, color)
: Draws a circle (used for the ball).draw()
: Clears the canvas and draws the current game state, including the paddles and the ball.update()
: Updates the ball’s position, checks for collisions, and handles out-of-bounds scenarios.resetBall()
: Resets the ball to the center of the canvas and reverses its horizontal direction.calculateMousePos(event)
: Calculates the mouse position relative to the canvas to update the left paddle’s position.gameLoop()
: Continuously updates and redraws the game, creating the animation and gameplay.
Conclusion
This Pong game project demonstrates the basics of using HTML5 canvas for game development. It includes fundamental game mechanics like drawing, collision detection, and user interaction handling. The game loop ensures smooth animations and responsive gameplay. This project serves as a solid foundation for more complex game development in the browser using JavaScript.
Source code:
HTML (index.html)
Pong Game
CSS (style.css)
canvas {
background-color: black;
display: block;
margin: 0 auto;
}
JavaScript (app.js)
const canvas = document.getElementById('pongCanvas');
const ctx = canvas.getContext('2d');
// Paddle Variables
const paddleWidth = 10;
const paddleHeight = 100;
let paddle1Y = canvas.height / 2 - paddleHeight / 2;
let paddle2Y = canvas.height / 2 - paddleHeight / 2;
// Ball Variables
const ballSize = 10;
let ballX = canvas.width / 2;
let ballY = canvas.height / 2;
let ballSpeedX = 5;
let ballSpeedY = 5;
// Draw Functions
function drawRect(x, y, width, height, color) {
ctx.fillStyle = color;
ctx.fillRect(x, y, width, height);
}
function drawCircle(x, y, radius, color) {
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
ctx.fill();
}
function draw() {
// Clear Canvas
drawRect(0, 0, canvas.width, canvas.height, 'black');
// Draw Paddles
drawRect(0, paddle1Y, paddleWidth, paddleHeight, 'white');
drawRect(canvas.width - paddleWidth, paddle2Y, paddleWidth, paddleHeight, 'white');
// Draw Ball
drawCircle(ballX, ballY, ballSize, 'white');
}
// Update Function
function update() {
// Move Ball
ballX += ballSpeedX;
ballY += ballSpeedY;
// Ball Collision with Top and Bottom Walls
if (ballY - ballSize < 0 || ballY + ballSize > canvas.height) {
ballSpeedY = -ballSpeedY;
}
// Ball Collision with Paddles
if (ballX - ballSize < paddleWidth && ballY > paddle1Y && ballY < paddle1Y + paddleHeight ||
ballX + ballSize > canvas.width - paddleWidth && ballY > paddle2Y && ballY < paddle2Y + paddleHeight) {
ballSpeedX = -ballSpeedX;
}
// Ball Out of Bounds
if (ballX - ballSize < 0 || ballX + ballSize > canvas.width) {
resetBall();
}
}
// Reset Ball Position
function resetBall() {
ballX = canvas.width / 2;
ballY = canvas.height / 2;
ballSpeedX = -ballSpeedX;
}
// Mouse Move Handler
canvas.addEventListener('mousemove', function(event) {
const mousePos = calculateMousePos(event);
paddle1Y = mousePos.y - paddleHeight / 2;
});
// Calculate Mouse Position
function calculateMousePos(event) {
const rect = canvas.getBoundingClientRect();
const root = document.documentElement;
const mouseX = event.clientX - rect.left - root.scrollLeft;
const mouseY = event.clientY - rect.top - root.scrollTop;
return { x: mouseX, y: mouseY };
}
// Game Loop
function gameLoop() {
draw();
update();
requestAnimationFrame(gameLoop);
}
// Start Game
gameLoop();