网页版的俄罗斯方块

打印 上一主题 下一主题

主题 906|帖子 906|积分 2718

1、新建一个txt文件
2、打开后将代码复制进去保存
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>俄罗斯方块</title>
  7.     <link rel="stylesheet" href="styles.css">
  8. </head>
  9. <body>
  10.   
  11.     <div class="game-container">
  12.         <div id="game-board"></div>
  13.         <div class="sidebar">
  14.             <div class="score-board">
  15.                 <h2>得分: <span id="score">0</span></h2>
  16.             </div>
  17.             <div class="next-piece-board">
  18.                 <h2>下一个方块</h2>
  19.                 <div id="next-piece"></div>
  20.             </div>
  21.             <div class="controls">
  22.                 <h2>操作说明</h2>
  23.                 <p>左箭头: 左移</p>
  24.                 <p>右箭头: 右移</p>
  25.                 <p>下箭头: 下落</p>
  26.                 <p>上箭头: 旋转</p>
  27.                 <div class="control-buttons">
  28.                     <button id="left-btn">左移</button>
  29.                     <button id="right-btn">右移</button>
  30.                     <button id="down-btn">下落</button>
  31.                     <button id="rotate-btn">旋转</button>
  32.                 </div>
  33.             </div>
  34.         </div>
  35.     </div>
  36.     <script src="script.js"></script>
  37. </body>
  38. </html>
  39. <style>
  40. body {
  41.     display: flex;
  42.     justify-content: center;
  43.     align-items: center;
  44.     height: 100vh;
  45.     margin: 0;
  46.     background-color: #f0f0f0;
  47. }
  48. .game-container {
  49.     display: flex;
  50.     gap: 20px;
  51. }
  52. #game-board {
  53.     display: grid;
  54.     grid-template-columns: repeat(10, 20px);
  55.     grid-template-rows: repeat(20, 20px);
  56.     gap: 1px;
  57.     background-color: #333;
  58.     width: fit-content;
  59. }
  60. .cell {
  61.     width: 20px;
  62.     height: 20px;
  63.     background-color: #000;
  64. }
  65. .cell.filled {
  66.     background-color: #0f0;
  67. }
  68. .sidebar {
  69.     display: flex;
  70.     flex-direction: column;
  71.     gap: 20px;
  72. }
  73. .score-board,
  74. .next-piece-board,
  75. .controls {
  76.     background-color: #fff;
  77.     padding: 10px;
  78.     border-radius: 5px;
  79.     box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
  80. }
  81. #next-piece {
  82.     display: grid;
  83.     grid-template-columns: repeat(4, 20px);
  84.     grid-template-rows: repeat(4, 20px);
  85.     gap: 1px;
  86.     background-color: #333;
  87.     width: fit-content;
  88. }
  89. .control-buttons {
  90.     display: flex;
  91.     gap: 10px;
  92. }
  93. .control-buttons button {
  94.     padding: 5px 10px;
  95.     cursor: pointer;
  96. }
  97. </style>
  98. <script>
  99. // 游戏板尺寸
  100. const ROWS = 20;
  101. const COLS = 10;
  102. // 方块形状
  103. const SHAPES = [
  104.     [[1, 1, 1, 1]],
  105.     [[1, 1], [1, 1]],
  106.     [[1, 1, 0], [0, 1, 1]],
  107.     [[0, 1, 1], [1, 1, 0]],
  108.     [[1, 1, 1], [0, 1, 0]],
  109.     [[1, 1, 1], [1, 0, 0]],
  110.     [[1, 1, 1], [0, 0, 1]]
  111. ];
  112. // 获取游戏板元素
  113. const gameBoard = document.getElementById('game-board');
  114. const nextPieceBoard = document.getElementById('next-piece');
  115. const scoreElement = document.getElementById('score');
  116. // 创建游戏板
  117. function createBoard() {
  118.     for (let row = 0; row < ROWS; row++) {
  119.         for (let col = 0; col < COLS; col++) {
  120.             const cell = document.createElement('div');
  121.             cell.classList.add('cell');
  122.             gameBoard.appendChild(cell);
  123.         }
  124.     }
  125. }
  126. // 创建下一个方块显示区域
  127. function createNextPieceBoard() {
  128.     for (let row = 0; row < 4; row++) {
  129.         for (let col = 0; col < 4; col++) {
  130.             const cell = document.createElement('div');
  131.             cell.classList.add('cell');
  132.             nextPieceBoard.appendChild(cell);
  133.         }
  134.     }
  135. }
  136. // 获取指定位置的单元格
  137. function getCell(row, col, board) {
  138.     return board.children[row * (board === gameBoard ? COLS : 4) + col];
  139. }
  140. // 随机生成一个方块
  141. function randomShape() {
  142.     const shapeIndex = Math.floor(Math.random() * SHAPES.length);
  143.     return SHAPES[shapeIndex];
  144. }
  145. // 当前方块
  146. let currentShape;
  147. let currentX;
  148. let currentY;
  149. // 下一个方块
  150. let nextShape;
  151. // 得分
  152. let score = 0;
  153. // 生成新方块
  154. function newShape() {
  155.     currentShape = nextShape || randomShape();
  156.     nextShape = randomShape();
  157.     drawNextPiece();
  158.     currentX = Math.floor(COLS / 2) - Math.floor(currentShape[0].length / 2);
  159.     currentY = 0;
  160.     if (!canMove(currentShape, currentX, currentY)) {
  161.         // 游戏结束
  162.         alert('游戏结束!最终得分: ' + score);
  163.         location.reload();
  164.     }
  165. }
  166. // 检查方块是否可以移动到指定位置
  167. function canMove(shape, x, y) {
  168.     for (let row = 0; row < shape.length; row++) {
  169.         for (let col = 0; col < shape[row].length; col++) {
  170.             if (shape[row][col]) {
  171.                 const newX = x + col;
  172.                 const newY = y + row;
  173.                 if (newX < 0 || newX >= COLS || newY >= ROWS || (newY >= 0 && getCell(newY, newX, gameBoard).classList.contains('filled'))) {
  174.                     return false;
  175.                 }
  176.             }
  177.         }
  178.     }
  179.     return true;
  180. }
  181. // 绘制方块
  182. function drawShape() {
  183.     for (let row = 0; row < currentShape.length; row++) {
  184.         for (let col = 0; col < currentShape[row].length; col++) {
  185.             if (currentShape[row][col]) {
  186.                 const x = currentX + col;
  187.                 const y = currentY + row;
  188.                 if (y >= 0) {
  189.                     getCell(y, x, gameBoard).classList.add('filled');
  190.                 }
  191.             }
  192.         }
  193.     }
  194. }
  195. // 清除方块
  196. function clearShape() {
  197.     for (let row = 0; row < currentShape.length; row++) {
  198.         for (let col = 0; col < currentShape[row].length; col++) {
  199.             if (currentShape[row][col]) {
  200.                 const x = currentX + col;
  201.                 const y = currentY + row;
  202.                 if (y >= 0) {
  203.                     getCell(y, x, gameBoard).classList.remove('filled');
  204.                 }
  205.             }
  206.         }
  207.     }
  208. }
  209. // 绘制下一个方块
  210. function drawNextPiece() {
  211.     // 清除之前的显示
  212.     for (let row = 0; row < 4; row++) {
  213.         for (let col = 0; col < 4; col++) {
  214.             getCell(row, col, nextPieceBoard).classList.remove('filled');
  215.         }
  216.     }
  217.     // 绘制新的下一个方块
  218.     for (let row = 0; row < nextShape.length; row++) {
  219.         for (let col = 0; col < nextShape[row].length; col++) {
  220.             if (nextShape[row][col]) {
  221.                 getCell(row, col, nextPieceBoard).classList.add('filled');
  222.             }
  223.         }
  224.     }
  225. }
  226. // 方块下落
  227. function moveDown() {
  228.     clearShape();
  229.     if (canMove(currentShape, currentX, currentY + 1)) {
  230.         currentY++;
  231.     } else {
  232.         // 方块落地,固定方块
  233.         drawShape();
  234.         checkLines();
  235.         newShape();
  236.     }
  237.     drawShape();
  238. }
  239. // 检查并清除满行
  240. function checkLines() {
  241.     let linesCleared = 0;
  242.     for (let row = ROWS - 1; row >= 0; row--) {
  243.         let isLineFull = true;
  244.         for (let col = 0; col < COLS; col++) {
  245.             if (!getCell(row, col, gameBoard).classList.contains('filled')) {
  246.                 isLineFull = false;
  247.                 break;
  248.             }
  249.         }
  250.         if (isLineFull) {
  251.             linesCleared++;
  252.             // 清除满行
  253.             for (let c = 0; c < COLS; c++) {
  254.                 getCell(row, c, gameBoard).classList.remove('filled');
  255.             }
  256.             // 上方方块下移
  257.             for (let r = row; r > 0; r--) {
  258.                 for (let c = 0; c < COLS; c++) {
  259.                     const aboveCell = getCell(r - 1, c, gameBoard);
  260.                     const currentCell = getCell(r, c, gameBoard);
  261.                     if (aboveCell.classList.contains('filled')) {
  262.                         currentCell.classList.add('filled');
  263.                     } else {
  264.                         currentCell.classList.remove('filled');
  265.                     }
  266.                 }
  267.             }
  268.             row++; // 再次检查当前行
  269.         }
  270.     }
  271.     // 根据清除的行数增加得分
  272.     if (linesCleared > 0) {
  273.         score += linesCleared * 100;
  274.         scoreElement.textContent = score;
  275.     }
  276. }
  277. // 移动方块
  278. function moveLeft() {
  279.     clearShape();
  280.     if (canMove(currentShape, currentX - 1, currentY)) {
  281.         currentX--;
  282.     }
  283.     drawShape();
  284. }
  285. function moveRight() {
  286.     clearShape();
  287.     if (canMove(currentShape, currentX + 1, currentY)) {
  288.         currentX++;
  289.     }
  290.     drawShape();
  291. }
  292. // 旋转方块
  293. function rotateShape() {
  294.     const rotatedShape = [];
  295.     for (let col = 0; col < currentShape[0].length; col++) {
  296.         const newRow = [];
  297.         for (let row = currentShape.length - 1; row >= 0; row--) {
  298.             newRow.push(currentShape[row][col]);
  299.         }
  300.         rotatedShape.push(newRow);
  301.     }
  302.     clearShape();
  303.     if (canMove(rotatedShape, currentX, currentY)) {
  304.         currentShape = rotatedShape;
  305.     }
  306.     drawShape();
  307. }
  308. // 键盘事件处理
  309. document.addEventListener('keydown', function (event) {
  310.     switch (event.key) {
  311.         case 'ArrowLeft':
  312.             moveLeft();
  313.             break;
  314.         case 'ArrowRight':
  315.             moveRight();
  316.             break;
  317.         case 'ArrowDown':
  318.             moveDown();
  319.             break;
  320.         case 'ArrowUp':
  321.             rotateShape();
  322.             break;
  323.     }
  324. });
  325. // 按钮事件处理
  326. document.getElementById('left-btn').addEventListener('click', moveLeft);
  327. document.getElementById('right-btn').addEventListener('click', moveRight);
  328. document.getElementById('down-btn').addEventListener('click', moveDown);
  329. document.getElementById('rotate-btn').addEventListener('click', rotateShape);
  330. // 游戏主循环
  331. function gameLoop() {
  332.     moveDown();
  333.     setTimeout(gameLoop, 500);
  334. }
  335. // 初始化游戏
  336. createBoard();
  337. createNextPieceBoard();
  338. newShape();
  339. gameLoop();
  340. </script>
复制代码
3、修改文件后缀名为,将txt修改为html
4、打开方式选择欣赏器打开,或者打开欣赏器直接拖动到内里即可。假如后缀名修改html后,图标显示的是欣赏器的图标,直接双击打开即可。
5、结果如下:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

去皮卡多

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表