Josh Bruce Online

Tetris Game Documentation

Overview

A modern implementation of the classic Tetris game featuring sophisticated mobile touch controls, Firebase leaderboards, and responsive design. Built with HTML5 Canvas and vanilla JavaScript for optimal performance.

Technical Architecture

Core Technologies

File Structure

tetris/
├── index.html           # Main game application
├── cnfg.js             # Firebase configuration
├── tetrisInstructions.png  # Control instructions image
└── tetrisfavicon.ico   # Game favicon

Game Implementation

Core Game Constants

const COLS = 10;
const ROWS = 20;
const BLOCK_SIZE = 32;
const COLORS = {
    I: '#43A3B7',  // Cyan
    O: '#F6BD44',  // Yellow
    T: '#6F41B1',  // Purple
    S: '#4CA84C',  // Green
    Z: '#E14331',  // Red
    J: '#4D86F7',  // Blue
    L: '#DC6C33'   // Orange
};

Tetromino Shapes

const SHAPES = {
    I: [[0,0,0,0], [1,1,1,1], [0,0,0,0], [0,0,0,0]],
    J: [[1,0,0], [1,1,1], [0,0,0]],
    L: [[0,0,1], [1,1,1], [0,0,0]],
    O: [[1,1], [1,1]],
    S: [[0,1,1], [1,1,0], [0,0,0]],
    Z: [[1,1,0], [0,1,1], [0,0,0]],
    T: [[0,1,0], [1,1,1], [0,0,0]]
};

Advanced Features

7-Bag Randomizer

Implements fair piece distribution to prevent long droughts:

function fillBag() {
    const pieces = ['I', 'J', 'L', 'O', 'S', 'T', 'Z'];
    const shuffled = pieces.sort(() => Math.random() - 0.5);
    bag.push(...shuffled);
}

Collision Detection

Efficient boundary and block collision checking:

function isValidMove(piece, x, y) {
    for (let row = 0; row < piece.shape.length; row++) {
        for (let col = 0; col < piece.shape[row].length; col++) {
            if (piece.shape[row][col]) {
                const newX = x + col;
                const newY = y + row;
                
                if (newX < 0 || newX >= COLS || newY >= ROWS) return false;
                if (newY >= 0 && board[newY][newX]) return false;
            }
        }
    }
    return true;
}

Line Clearing Algorithm

function clearLines() {
    let linesCleared = 0;
    
    for (let y = ROWS - 1; y >= 0; y--) {
        if (board[y].every(cell => cell !== 0)) {
            board.splice(y, 1);
            board.unshift(Array(COLS).fill(0));
            linesCleared++;
            y++; // Check the same row again
        }
    }
    
    if (linesCleared > 0) {
        score += [100, 250, 500, 1000][linesCleared - 1];
        updateScore();
    }
}

Control Systems

Keyboard Controls

Advanced Mobile Touch Controls

Sophisticated zone-based touch system:

canvas.addEventListener('touchstart', (e) => {
    e.preventDefault();
    const rect = canvas.getBoundingClientRect();
    const touch = e.touches[0];
    const x = touch.clientX - rect.left;
    const y = touch.clientY - rect.top;
    
    const centerX = rect.width / 2;
    const centerY = rect.height / 2;
    
    if (y < centerY) {
        // Top half - rotate
        rotatePiece();
    } else if (x < centerX) {
        // Bottom-left - move left
        movePiece(-1);
        // Start continuous movement
        touchHoldInterval = setInterval(() => movePiece(-1), 100);
    } else {
        // Bottom-right - move right
        movePiece(1);
        touchHoldInterval = setInterval(() => movePiece(1), 100);
    }
});

Touch Control Features

Visual Design

Responsive Layout

Three-column desktop layout with mobile stack:

@media (max-width: 768px) {
    body {
        flex-direction: column;
        padding: 20px;
    }
    
    .game-container {
        width: 100%;
        height: 85vh;
        margin-bottom: 40px;
    }
}

Rounded Block Rendering

Modern aesthetic with rounded corners:

function drawBlock(x, y, color) {
    const padding = 1;
    const blockX = x * BLOCK_SIZE + padding;
    const blockY = y * BLOCK_SIZE + padding;
    const blockSize = BLOCK_SIZE - padding * 2;
    const radius = 4;
    
    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.moveTo(blockX + radius, blockY);
    ctx.arcTo(blockX + blockSize, blockY, blockX + blockSize, blockY + blockSize, radius);
    // ... additional rounded corner drawing
    ctx.fill();
}

Touch Control Hints

Fading overlay system for mobile users:

if (window.innerWidth <= 768 && !gameOver) {
    const gameTime = Date.now() - gameStartTime;
    const fadeOutStart = 3000; // Start fading after 3 seconds
    const fadeOutDuration = 2000; // Fade over 2 seconds
    
    let opacity = 1;
    if (gameTime > fadeOutStart) {
        opacity = Math.max(0, 1 - (gameTime - fadeOutStart) / fadeOutDuration);
    }
    
    if (opacity > 0) {
        // Draw control hint overlay
        drawControlHints(opacity);
    }
}

Firebase Leaderboard

Database Integration

firebase.initializeApp(firebaseConfig);

const leaderboardRef = firebase.database().ref('leaderboard');

leaderboardRef.orderByChild('score').on('value', (snapshot) => {
    const entries = {};
    
    snapshot.forEach((child) => {
        const entry = child.val();
        const name = entry.name;
        const score = entry.score;
        
        // Keep highest score per player
        if (!entries[name] || score > entries[name]) {
            entries[name] = score;
        }
    });
    
    // Sort and display leaderboard
    const sorted = Object.entries(entries)
        .map(([name, score]) => ({ name, score }))
        .sort((a, b) => b.score - a.score);
    
    updateLeaderboardDisplay(sorted);
});

Score Submission

function handleGameOver() {
    if (score >= 1000) {
        const name = prompt("Game Over! Enter your name (max 5 characters):");
        
        if (name && name.trim()) {
            const trimmedName = name.trim().substring(0, 5);
            
            // Simple profanity filter
            const bannedWords = ['cock','balls','pussy','fuck','shit','cunt','bitch','penis','ass','piss','slut','whore'];
            const nameLC = trimmedName.toLowerCase();
            const hasBanned = bannedWords.some(word => nameLC.includes(word));
            
            if (!hasBanned || trimmedName === 'Logan W') {
                firebase.database().ref('leaderboard').push({
                    name: trimmedName,
                    score: score,
                    timestamp: firebase.database.ServerValue.TIMESTAMP
                });
            }
        }
    }
}

Leaderboard Display

sorted.forEach((entry, index) => {
    const li = document.createElement('li');
    
    if (index === 0) {
        li.textContent = `1st | ${entry.name} - ${entry.score} 🥇`;
    } else if (index === 1) {
        li.textContent = `2nd | ${entry.name} - ${entry.score} 🥈`;
    } else if (index === 2) {
        li.textContent = `3rd | ${entry.name} - ${entry.score} 🥉`;
    } else {
        li.textContent = `${index + 1}. ${entry.name} - ${entry.score}`;
    }
    
    list.appendChild(li);
});

Performance Optimizations

Efficient Game Loop

function gameLoop(time = 0) {
    if (gameOver) return;
    
    const deltaTime = time - lastTime;
    lastTime = time;
    
    dropCounter += deltaTime;
    if (dropCounter > 1000) {
        dropPiece();
        dropCounter = 0;
    }
    
    draw();
    requestAnimationFrame(gameLoop);
}

Touch Event Optimization

Canvas Optimization

Game Balance

Scoring System

Difficulty Progression

Accessibility Features

Visual Accessibility

Motor Accessibility

Browser Compatibility

Supported Browsers

Required Features

Security Considerations

Input Validation

Data Protection

Future Enhancements

Planned Features

  1. Power-ups: Special abilities and bonuses
  2. Multiplayer: Real-time competitive play
  3. Themes: Customizable visual themes
  4. Sound: Audio effects and music
  5. Statistics: Advanced player analytics

Technical Improvements

  1. WebGL Rendering: Hardware-accelerated graphics
  2. Service Worker: Offline gameplay capability
  3. Progressive Web App: Full PWA implementation
  4. Advanced Analytics: Player behavior tracking
  5. A/B Testing: Feature optimization

Troubleshooting

Common Issues

  1. Touch Controls Not Working: Ensure device supports touch events
  2. Leaderboard Not Loading: Check Firebase connection
  3. Performance Issues: Verify browser Canvas support
  4. Mobile Display Problems: Check viewport meta tag

Debug Information

Conclusion

This Tetris implementation represents a sophisticated modern take on the classic game, featuring advanced mobile controls, real-time leaderboards, and optimized performance. The combination of faithful gameplay mechanics with contemporary web technologies creates an engaging and accessible gaming experience across all devices.

Technical Rating: 9.0/10