Josh Bruce Online

🅱️ong - Enhanced Pong Game with Administrative Controls Documentation

Overview

“🅱️ong” is an enhanced version of the classic Pong arcade game featuring timed gameplay, dynamic paddle controls, and administrative override capabilities. The game includes a 90-second countdown timer, horizontal paddle movement mechanics, and Firebase integration for remote management, creating a modern twist on the timeless two-player competitive experience.

Technical Architecture

Core Technologies

File Structure

pong/
└── index.html    # Complete Pong game with Firebase integration (320 lines)

Game Mechanics and Design

Classic Pong Foundation

#pong {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #000;        /* Classic black playing field */
}

.paddle {
  position: absolute;
  width: 20px;
  height: 100px;
  background-color: #fff;        /* White paddles */
}

.ball {
  position: absolute;
  width: 20px;
  height: 20px;
  background-color: #fff;
  border-radius: 50%;            /* Circular ball */
}

Enhanced Visual Elements

#scores {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font-size: 24px;
  font-family: "Helvetica", Arial, sans-serif;
  font-weight: bold;
}

#countdown {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font-size: 20px;
  font-family: "Helvetica", Arial, sans-serif;
}

Game Physics and Movement

Ball Physics System

let ballSpeed = 12;             /* Initial ball speed */
let ballXSpeed = ballSpeed;     /* Horizontal velocity */
let ballYSpeed = ballSpeed;     /* Vertical velocity */

function moveBall() {
  ballXPosition += ballXSpeed;
  ballYPosition += ballYSpeed;

  // Wall collision detection
  if (ballYPosition <= 0 || ballYPosition >= pong.offsetHeight - ball.offsetHeight) {
    ballYSpeed *= -1;           /* Reverse vertical direction */
  }

  // Paddle collision detection
  if (collision(leftPaddle, ball) || collision(rightPaddle, ball)) {
    // Position adjustment for accurate collision
    if (ballXSpeed > 0) {
      ballXPosition = rightPaddle.offsetLeft - ball.offsetWidth;
    } else {
      ballXPosition = leftPaddle.offsetLeft + leftPaddle.offsetWidth;
    }
    ballXSpeed *= -1;           /* Reverse horizontal direction */
  }
}

Advanced Collision Detection

function collision(paddle, ball) {
  const paddleRect = paddle.getBoundingClientRect();
  const ballRect = ball.getBoundingClientRect();

  return (
    paddleRect.bottom > ballRect.top &&
    paddleRect.top < ballRect.bottom &&
    paddleRect.right > ballRect.left &&
    paddleRect.left < ballRect.right
  );
}

Enhanced Paddle Control System

Multi-Dimensional Paddle Movement

const paddleSpeed = 10;         /* Vertical movement speed */
const paddleXSpeed = 5;         /* Horizontal movement speed */

function movePaddles() {
  // Left paddle controls (W/S for vertical, A/D for horizontal)
  if (keysDown.w) {
    paddleLeftPosition -= paddleSpeed;
  }
  if (keysDown.s) {
    paddleLeftPosition += paddleSpeed;
  }
  
  // Horizontal movement only after countdown ends
  if (secondsLeft <= 0) {
    if (keysDown.a) {
      paddleLeftXPosition -= paddleXSpeed;
    }
    if (keysDown.d) {
      paddleLeftXPosition += paddleXSpeed;
    }
  }

  // Right paddle controls (Arrow keys)
  if (keysDown.ArrowUp) {
    paddleRightPosition -= paddleSpeed;
  }
  if (keysDown.ArrowDown) {
    paddleRightPosition += paddleSpeed;
  }
  
  // Horizontal movement only after countdown ends
  if (secondsLeft <= 0) {
    if (keysDown.ArrowLeft) {
      paddleRightXPosition -= paddleXSpeed;
    }
    if (keysDown.ArrowRight) {
      paddleRightXPosition += paddleXSpeed;
    }
  }
}

Boundary Constraint System

// Restrict paddle movement within game area
paddleLeftPosition = Math.max(Math.min(paddleLeftPosition, pong.offsetHeight - leftPaddle.offsetHeight), 0);
paddleLeftXPosition = Math.max(Math.min(paddleLeftXPosition, pong.offsetWidth - leftPaddle.offsetWidth), 0);
paddleRightPosition = Math.max(Math.min(paddleRightPosition, pong.offsetHeight - rightPaddle.offsetHeight), 0);
paddleRightXPosition = Math.max(Math.min(paddleRightXPosition, pong.offsetWidth - rightPaddle.offsetWidth), 0);

Timed Gameplay System

90-Second Game Duration

const gameDuration = 90;        /* Game duration in seconds */
let secondsLeft = gameDuration;
let gameStarted = false;
let countdownInterval;

function startGame() {
  if (!gameStarted) {
    countdownInterval = setInterval(updateCountdown, 1000);
    gameStarted = true;
  }
}

function updateCountdown() {
  secondsLeft--;
  if (secondsLeft <= 0) {
    clearInterval(countdownInterval);
    gameStarted = true;
    ballSpeed = 8;              /* Reduce ball speed after countdown */
    enablePaddleControl();
    requestAnimationFrame(update);
  }

  // Format time display (MM:SS)
  const minutes = Math.floor(secondsLeft / 60);
  const seconds = secondsLeft % 60;
  countdownDisplay.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
}

Phase-Based Gameplay

Input Management System

Multi-Key Input Handling

const keysDown = {};

window.addEventListener('keydown', function (event) {
  keysDown[event.key] = true;
});

window.addEventListener('keyup', function (event) {
  keysDown[event.key] = false;
});

Control Scheme

Left Player Controls:

Right Player Controls:

Scoring and Reset System

Automatic Scoring

// Check if ball is out of bounds
if (ballXPosition <= 0) {
  // Right player scores
  rightScore++;
  resetBall();
} else if (ballXPosition >= pong.offsetWidth - ball.offsetWidth) {
  // Left player scores
  leftScore++;
  resetBall();
}

// Update score display
leftScoreDisplay.textContent = leftScore;
rightScoreDisplay.textContent = rightScore;

Ball Reset Mechanism

function resetBall() {
  ballXPosition = pong.offsetWidth / 2 - ball.offsetWidth / 2;
  ballYPosition = pong.offsetHeight / 2 - ball.offsetHeight / 2;
  ballSpeed = Math.random() > 0.5 ? -ballSpeed : ballSpeed;  /* Random direction */
  ballXSpeed = ballSpeed;
  ballYSpeed = ballSpeed;
}

Game Loop Architecture

RequestAnimationFrame Implementation

function update() {
  if (gameStarted) {
    movePaddles();
    moveBall();
  }
  requestAnimationFrame(update);    /* Smooth 60fps animation */
}

// Initialize game loop
update();
setTimeout(startGame, 2500);       /* Start game after 2.5 seconds */

Firebase Administrative Control System

Remote Management Configuration

const switchFirebaseConfig = {
  apiKey: "AIzaSyCRPBjKJfKoLO52TqROpQ3I9X-nEL-0btE",
  databaseURL: "https://joshbruceonline-switch-default-rtdb.europe-west1.firebasedatabase.app/",
  authDomain: "joshbruceonline-switch.firebaseapp.com",
  projectId: "joshbruceonline-switch",
  storageBucket: "joshbruceonline-switch.appspot.com",
  messagingSenderId: "592073701037",
  appId: "1:592073701037:web:309eb7bed49885153a7824"
};

const switchApp = firebase.initializeApp(switchFirebaseConfig, 'switch');
const switchDb = switchApp.database();
const switchPageRef = switchDb.ref('pong');
const redirectLinkRef = switchDb.ref('redirectLink');

Real-Time Administrative Override

switchPageRef.on('value', (snapshot) => {
  const isPageActive = snapshot.val();
  if (isPageActive === false) {
    // Get redirect destination
    redirectLinkRef.once('value', (snapshot) => {
      const redirectLink = snapshot.val();
      if (redirectLink) {
        // Redirect to specified URL
        window.location.href = redirectLink;
      } else {
        // Default redirect to backrooms
        window.location.href = 'https://joshbruce.online/backrooms';
      }
    });
  }
});

Administrative Features

Enhanced Game Features

Dynamic Speed Adjustment

// Initial fast ball speed
ballSpeed = 12;

// Reduced speed after countdown for better gameplay
if (secondsLeft <= 0) {
  ballSpeed = 8;
}

Progressive Difficulty

Performance Optimization

Efficient Rendering

Memory Management

// Clean interval management
function startGame() {
  if (!gameStarted) {
    countdownInterval = setInterval(updateCountdown, 1000);
    gameStarted = true;
  }
}

// Proper cleanup when countdown ends
if (secondsLeft <= 0) {
  clearInterval(countdownInterval);
}

Accessibility and User Experience

Visual Design

User Interface

Future Enhancement Opportunities

Gameplay Features

  1. AI Opponent: Computer-controlled paddle for single-player mode
  2. Power-ups: Special abilities and temporary bonuses
  3. Multiple Balls: Increased complexity with multiple simultaneous balls
  4. Variable Speeds: Adjustable game speed settings
  5. Tournament Mode: Multi-game championship system

Technical Improvements

  1. Mobile Support: Touch controls for mobile devices
  2. Sound Effects: Audio feedback for collisions and scoring
  3. Visual Effects: Particle systems and enhanced graphics
  4. Pause Functionality: Game pause and resume capabilities
  5. Replay System: Record and playback game sessions

Social Features

  1. Online Multiplayer: Network-based remote play
  2. Leaderboards: High score tracking and competition
  3. Spectator Mode: Watch other players compete
  4. User Profiles: Player statistics and achievements
  5. Chat System: In-game communication

Code Quality Assessment

Strengths

Areas for Enhancement

Conclusion

🅱️ong represents an excellent enhancement of the classic Pong arcade game, successfully combining nostalgic gameplay with modern web technologies. The timed gameplay mechanics, enhanced paddle controls, and Firebase administrative features create an engaging and manageable gaming experience.

Technical Rating: 8.4/10

The application successfully demonstrates how classic arcade games can be enhanced with modern web technologies while maintaining their essential gameplay characteristics and nostalgic appeal.