Mini-Tetris

by velo_ninja

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple Tetris</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="game-container">
        <h1>Tetris</h1>
        <canvas id="gameCanvas" width="240" height="480"></canvas>
        <div class="sidebar">
            <p>Score: <span id="score">0</span></p>
            <p>Level: <span id="level">1</span></p>
            <p>Next Piece:</p>
            <canvas id="nextPieceCanvas" width="120" height="120"></canvas>
            <button id="startButton">Start Game</button>
            <p class="instructions">Use Arrow Keys to Move</p>
            <p class="instructions">Up Arrow: Rotate</p>
            <p class="instructions">Down Arrow: Soft Drop</p>
            <p class="instructions">Spacebar: Hard Drop</p>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

CSS

body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background-color: #2c3e50; /* Dark background */
    font-family: 'Press Start 2P', cursive; /* A retro gaming font would be cool */
    color: #ecf0f1; /* Light text color */
    margin: 0;
    overflow: hidden;
}

.game-container {
    display: flex;
    flex-direction: row;
    gap: 30px;
    background-color: #34495e; /* Slightly lighter background for the container */
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
    border: 2px solid #7f8c8d;
}

h1 {
    text-align: center;
    color: #e67e22; /* Orange title */
    margin-bottom: 20px;
    text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
}

canvas {
    background-color: #000;
    border: 5px solid #2980b9; /* Blue border for the game area */
    display: block;
    margin: 0 auto;
}

.sidebar {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    padding: 10px;
    border-left: 2px solid #7f8c8d;
}

.sidebar p {
    margin: 5px 0;
    font-size: 1.1em;
}

.sidebar #nextPieceCanvas {
    background-color: #1a1a1a;
    border: 2px solid #2980b9;
    margin-top: 10px;
}

button {
    background-color: #27ae60; /* Green start button */
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 1.2em;
    margin-top: 20px;
    transition: background-color 0.2s ease;
}

button:hover {
    background-color: #2ecc71;
}

.instructions {
    font-size: 0.9em;
    color: #bdc3c7;
    margin-top: 10px;
}

JavaScript

document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    const nextPieceCanvas = document.getElementById('nextPieceCanvas');
    const nextPieceCtx = nextPieceCanvas.getContext('2d');
    const scoreDisplay = document.getElementById('score');
    const levelDisplay = document.getElementById('level');
    const startButton = document.getElementById('startButton');

    const COLS = 10;
    const ROWS = 20;
    const BLOCK_SIZE = 24; // Each block is 24x24 pixels

    canvas.width = COLS * BLOCK_SIZE;
    canvas.height = ROWS * BLOCK_SIZE;

    ctx.scale(BLOCK_SIZE, BLOCK_SIZE);
    nextPieceCtx.scale(BLOCK_SIZE, BLOCK_SIZE);

    let board = [];
    let currentPiece;
    let nextPiece;
    let score = 0;
    let level = 1;
    let dropInterval = 1000; // milliseconds
    let dropCounter = 0;
    let lastTime = 0;
    let gameRunning = false;
    let animationFrameId;

    // Tetromino shapes and colors
    const tetrominos = {
        'I': {
            matrix: [
                [0, 0, 0, 0],
                [1, 1, 1, 1],
                [0, 0, 0, 0],
                [0, 0, 0, 0]
            ],
            color: '#00FFFF' // Cyan
        },
        'J': {
            matrix: [
                [1, 0, 0],
                [1, 1, 1],
                [0, 0, 0]
            ],
            color: '#0000FF' // Blue
        },
        'L': {
            matrix: [
                [0, 0, 1],
                [1, 1, 1],
                [0, 0, 0]
            ],
            color: '#FFA500' // Orange
        },
        'O': {
            matrix: [
                [1, 1],
                [1, 1]
            ],
            color: '#FFFF00' // Yellow
        },
        'S': {
            matrix: [
                [0, 1, 1],
                [1, 1, 0],
                [0, 0, 0]
            ],
            color:...