网页版的俄罗斯方块

1、新建一个txt文件

2、打开后将代码复制进去保存

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>俄罗斯方块</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>
  
    <div class="game-container">
        <div id="game-board"></div>
        <div class="sidebar">
            <div class="score-board">
                <h2>得分: <span id="score">0</span></h2>
            </div>
            <div class="next-piece-board">
                <h2>下一个方块</h2>
                <div id="next-piece"></div>
            </div>
            <div class="controls">
                <h2>操作说明</h2>
                <p>左箭头: 左移</p>
                <p>右箭头: 右移</p>
                <p>下箭头: 下落</p>
                <p>上箭头: 旋转</p>
                <div class="control-buttons">
                    <button id="left-btn">左移</button>
                    <button id="right-btn">右移</button>
                    <button id="down-btn">下落</button>
                    <button id="rotate-btn">旋转</button>
                </div>
            </div>
        </div>
    </div>
    <script src="script.js"></script>


</body>

</html>
<style>
body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
}

.game-container {
    display: flex;
    gap: 20px;
}

#game-board {
    display: grid;
    grid-template-columns: repeat(10, 20px);
    grid-template-rows: repeat(20, 20px);
    gap: 1px;
    background-color: #333;
    width: fit-content;
}

.cell {
    width: 20px;
    height: 20px;
    background-color: #000;
}

.cell.filled {
    background-color: #0f0;
}

.sidebar {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.score-board,
.next-piece-board,
.controls {
    background-color: #fff;
    padding: 10px;
    border-radius: 5px;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}

#next-piece {
    display: grid;
    grid-template-columns: repeat(4, 20px);
    grid-template-rows: repeat(4, 20px);
    gap: 1px;
    background-color: #333;
    width: fit-content;
}

.control-buttons {
    display: flex;
    gap: 10px;
}

.control-buttons button {
    padding: 5px 10px;
    cursor: pointer;
}

</style>
<script>
// 游戏板尺寸
const ROWS = 20;
const COLS = 10;

// 方块形状
const SHAPES = [
    [[1, 1, 1, 1]],
    [[1, 1], [1, 1]],
    [[1, 1, 0], [0, 1, 1]],
    [[0, 1, 1], [1, 1, 0]],
    [[1, 1, 1], [0, 1, 0]],
    [[1, 1, 1], [1, 0, 0]],
    [[1, 1, 1], [0, 0, 1]]
];

// 获取游戏板元素
const gameBoard = document.getElementById('game-board');
const nextPieceBoard = document.getElementById('next-piece');
const scoreElement = document.getElementById('score');

// 创建游戏板
function createBoard() {
    for (let row = 0; row < ROWS; row++) {
        for (let col = 0; col < COLS; col++) {
            const cell = document.createElement('div');
            cell.classList.add('cell');
            gameBoard.appendChild(cell);
        }
    }
}

// 创建下一个方块显示区域
function createNextPieceBoard() {
    for (let row = 0; row < 4; row++) {
        for (let col = 0; col < 4; col++) {
            const cell = document.createElement('div');
            cell.classList.add('cell');
            nextPieceBoard.appendChild(cell);
        }
    }
}

// 获取指定位置的单元格
function getCell(row, col, board) {
    return board.children[row * (board === gameBoard ? COLS : 4) + col];
}

// 随机生成一个方块
function randomShape() {
    const shapeIndex = Math.floor(Math.random() * SHAPES.length);
    return SHAPES[shapeIndex];
}

// 当前方块
let currentShape;
let currentX;
let currentY;
// 下一个方块
let nextShape;
// 得分
let score = 0;

// 生成新方块
function newShape() {
    currentShape = nextShape || randomShape();
    nextShape = randomShape();
    drawNextPiece();
    currentX = Math.floor(COLS / 2) - Math.floor(currentShape[0].length / 2);
    currentY = 0;
    if (!canMove(currentShape, currentX, currentY)) {
        // 游戏结束
        alert('游戏结束!最终得分: ' + score);
        location.reload();
    }
}

// 检查方块是否可以移动到指定位置
function canMove(shape, x, y) {
    for (let row = 0; row < shape.length; row++) {
        for (let col = 0; col < shape[row].length; col++) {
            if (shape[row][col]) {
                const newX = x + col;
                const newY = y + row;
                if (newX < 0 || newX >= COLS || newY >= ROWS || (newY >= 0 && getCell(newY, newX, gameBoard).classList.contains('filled'))) {
                    return false;
                }
            }
        }
    }
    return true;
}

// 绘制方块
function drawShape() {
    for (let row = 0; row < currentShape.length; row++) {
        for (let col = 0; col < currentShape[row].length; col++) {
            if (currentShape[row][col]) {
                const x = currentX + col;
                const y = currentY + row;
                if (y >= 0) {
                    getCell(y, x, gameBoard).classList.add('filled');
                }
            }
        }
    }
}

// 清除方块
function clearShape() {
    for (let row = 0; row < currentShape.length; row++) {
        for (let col = 0; col < currentShape[row].length; col++) {
            if (currentShape[row][col]) {
                const x = currentX + col;
                const y = currentY + row;
                if (y >= 0) {
                    getCell(y, x, gameBoard).classList.remove('filled');
                }
            }
        }
    }
}

// 绘制下一个方块
function drawNextPiece() {
    // 清除之前的显示
    for (let row = 0; row < 4; row++) {
        for (let col = 0; col < 4; col++) {
            getCell(row, col, nextPieceBoard).classList.remove('filled');
        }
    }
    // 绘制新的下一个方块
    for (let row = 0; row < nextShape.length; row++) {
        for (let col = 0; col < nextShape[row].length; col++) {
            if (nextShape[row][col]) {
                getCell(row, col, nextPieceBoard).classList.add('filled');
            }
        }
    }
}

// 方块下落
function moveDown() {
    clearShape();
    if (canMove(currentShape, currentX, currentY + 1)) {
        currentY++;
    } else {
        // 方块落地,固定方块
        drawShape();
        checkLines();
        newShape();
    }
    drawShape();
}

// 检查并清除满行
function checkLines() {
    let linesCleared = 0;
    for (let row = ROWS - 1; row >= 0; row--) {
        let isLineFull = true;
        for (let col = 0; col < COLS; col++) {
            if (!getCell(row, col, gameBoard).classList.contains('filled')) {
                isLineFull = false;
                break;
            }
        }
        if (isLineFull) {
            linesCleared++;
            // 清除满行
            for (let c = 0; c < COLS; c++) {
                getCell(row, c, gameBoard).classList.remove('filled');
            }
            // 上方方块下移
            for (let r = row; r > 0; r--) {
                for (let c = 0; c < COLS; c++) {
                    const aboveCell = getCell(r - 1, c, gameBoard);
                    const currentCell = getCell(r, c, gameBoard);
                    if (aboveCell.classList.contains('filled')) {
                        currentCell.classList.add('filled');
                    } else {
                        currentCell.classList.remove('filled');
                    }
                }
            }
            row++; // 再次检查当前行
        }
    }
    // 根据清除的行数增加得分
    if (linesCleared > 0) {
        score += linesCleared * 100;
        scoreElement.textContent = score;
    }
}

// 移动方块
function moveLeft() {
    clearShape();
    if (canMove(currentShape, currentX - 1, currentY)) {
        currentX--;
    }
    drawShape();
}

function moveRight() {
    clearShape();
    if (canMove(currentShape, currentX + 1, currentY)) {
        currentX++;
    }
    drawShape();
}

// 旋转方块
function rotateShape() {
    const rotatedShape = [];
    for (let col = 0; col < currentShape[0].length; col++) {
        const newRow = [];
        for (let row = currentShape.length - 1; row >= 0; row--) {
            newRow.push(currentShape[row][col]);
        }
        rotatedShape.push(newRow);
    }
    clearShape();
    if (canMove(rotatedShape, currentX, currentY)) {
        currentShape = rotatedShape;
    }
    drawShape();
}

// 键盘事件处理
document.addEventListener('keydown', function (event) {
    switch (event.key) {
        case 'ArrowLeft':
            moveLeft();
            break;
        case 'ArrowRight':
            moveRight();
            break;
        case 'ArrowDown':
            moveDown();
            break;
        case 'ArrowUp':
            rotateShape();
            break;
    }
});

// 按钮事件处理
document.getElementById('left-btn').addEventListener('click', moveLeft);
document.getElementById('right-btn').addEventListener('click', moveRight);
document.getElementById('down-btn').addEventListener('click', moveDown);
document.getElementById('rotate-btn').addEventListener('click', rotateShape);

// 游戏主循环
function gameLoop() {
    moveDown();
    setTimeout(gameLoop, 500);
}

// 初始化游戏
createBoard();
createNextPieceBoard();
newShape();
gameLoop();


</script>

3、修改文件后缀名为,将txt修改为html

4、打开方式选择浏览器打开,或者打开浏览器直接拖动到里面即可。如果后缀名修改html后,图标显示的是浏览器的图标,直接双击打开即可。

5、效果如下:

相关推荐
To_OC5 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
To_OC5 小时前
LC 17 电话号码的字母组合:我的回溯算法,就是从这道题开窍的
javascript·算法·leetcode
vipbic6 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy6 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志6 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble7 小时前
c端系统,其实更像一个信息展示平台
前端
你怎么知道我是队长8 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
李姆斯8 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜9 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司9 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能