网页版的俄罗斯方块

server/2025/2/22 11:49:43/

1、新建一个txt文件
2、打开后将代码复制进去保存

<!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>css">
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>javascript">
// 游戏板尺寸
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、效果如下:
在这里插入图片描述


http://www.ppmy.cn/server/169830.html

相关文章

网络IP跳动问题解决详

一、问题原因分析 DHCP服务器配置问题: DHCP服务器租期设置过短。 DHCP地址池范围过小&#xff0c;导致地址耗尽。 网络中可能存在多个DHCP服务器&#xff0c;导致IP分配冲突。 网络中存在IP地址冲突: 手动配置的IP地址与DHCP分配的地址冲突。 网络中存在未经授权的DHCP服…

深度学习笔记16-VGG-16算法-Pytorch实现人脸识别

目录 前言 一、 前期准备 1. 设置GPU 2. 导入数据 3. 划分数据集 二、调用官方的VGG-16模型 三、 训练模型 1. 编写训练函数 2. 编写测试函数 3. 设置动态学习率 4. 正式训练 四、 结果可视化 1. Loss与Accuracy图 2. 指定图片进行预测 3. 模型评估 五、总结 前言 &#x1f368…

GB28181协议详解

第一部分&#xff1a;协议基础与设备注册 1.1 协议分层架构 层级协议/规范功能说明信令控制层SIP (RFC 3261) GB扩展设备注册、目录订阅、实时点播、云台控制等控制信令媒体传输层RTP/RTCP (RFC 3550) PS封装音视频数据封装传输&#xff0c;支持H.264/H.265/G.711/AAC等编码…

JavaScript系列(79)--Web Worker 高级应用

Web Worker 高级应用 &#x1f504; Web Worker 为JavaScript提供了真正的多线程能力&#xff0c;让我们能够在后台线程中执行复杂的计算而不阻塞主线程。今天让我们深入探讨Web Worker的高级应用。 Web Worker 概述 &#x1f31f; &#x1f4a1; 小知识&#xff1a;Web Work…

JSON格式,C语言自己实现,以及直接调用库函数(一)

JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。以下为你提供不同场景下常见的 JSON 格式示例。 1. 简单对象 JSON 对象是由键值对组成&#xff0c;用花括号 {} 包裹&…

Playwright之---网络管理API

Playwright 提供了强大的 网络管理 API&#xff0c;用于控制和管理浏览器的网络活动。这些 API 允许你模拟网络请求和响应、拦截和修改网络请求、模拟网络条件、以及更多网络层级的操作。它们通常用于自动化测试、抓取数据或模拟不同的网络环境。 Playwright 的 网络管理 API 提…

NASM - win64调用ExitProcess不用提供阴影区的原因

文章目录 NASM - win64调用ExitProcess不用提供阴影区的原因概述笔记结论END NASM - win64调用ExitProcess不用提供阴影区的原因 概述 通常来说&#xff0c;win64位程序调用API时&#xff0c;必须提供阴影区(shadow space), 这是win64 API调用的约定。 但是发现一个特例 Exit…

itemgetter() 是 Python operator 模块中的一个函数,主要用于从 字典、列表、元组等数据结构中取值

如何使用 itemgetter()&#xff1f; itemgetter() 是 Python operator 模块中的一个函数&#xff0c;主要用于从 字典、列表、元组等数据结构中取值。它的作用类似一个自动化的 “取值器”&#xff0c;可以让你更方便地提取数据。 1. itemgetter() 取字典 key 的值 如果你有一…