js实现简单的俄罗斯方块小游戏

开始

1. 创建一个宽为 200px,高为 360px 的背景容器

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>俄罗斯方块</title>
  <style>
    .container {
    
      position: relative;
      width: 200px;
      height: 360px;
      background-color: #000;
    }
  </style>
</head>

<body>
  <!-- 背景容器 -->
  <div class="container"></div>
</body>

</html>

2. 在该容器上创建一个 20 * 20 的块元素

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>俄罗斯方块</title>
  <style>
    .container {
    
      position: relative;
      width: 200px;
      height: 360px;
      background-color: #000;
    }

    .activity-model {
    
      width: 20px;
      height: 20px;
      background-color: cadetblue;
      border: 1px solid #eeeeee;
      box-sizing: border-box;
      position: absolute;
    }
  </style>
</head>

<body>
  <!-- 背景容器 -->
  <div class="container">
    <!-- 块元素 -->
    <div class="activity-model"></div>
  </div>
</body>

</html>

3. 控制该元素的移动,每次移动 20px

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>俄罗斯方块</title>
  <style>
    .container {
    
      position: relative;
      width: 200px;
      height: 360px;
      background-color: #000;
    }

    .activity-model {
    
      width: 20px;
      height: 20px;
      background-color: cadetblue;
      border: 1px solid #eeeeee;
      box-sizing: border-box;
      position: absolute;
    }
  </style>
</head>

<body>
  <!-- 背景容器 -->
  <div class="container">
    <!-- 块元素 -->
    <div class="activity-model"></div>
  </div>
  <script>
    // 常量
    // 每次移动的距离 步长
    const STEP = 20

    init()
    // 入口方法
    function init() {
    
      onKeyDown()
    }

    // 监听用户的键盘事件
    function onKeyDown() {
    
      document.onkeydown = event => {
    
        switch (event.keyCode) {
    
          case 38: // 上
            move(0, -1)
            break;
          case 39: // 右
            move(1, 0)
            break;
          case 40: // 下
            move(0, 1)
            break;
          case 37: // 左
            move(-1, 0)
            break;
          default:
            break;
        }
      }
    }

    // 移动
    function move(x, y) {
    
      // 控制块元素进行移动
      const activityModelEle = document.getElementsByClassName("activity-model")[0]
      activityModelEle.style.top = parseInt(activityModelEle.style.top || 0) + y * STEP + "px"
      activityModelEle.style.left = parseInt(activityModelEle.style.left || 0) + x * STEP + "px"
    }
  </script>
</body>

</html>

构建 L 形状的模型

1. 将容器进行分割,分割为 18 行,10 列。行高,列高均为20

在这里插入图片描述

// 常量
// 每次移动的距离 步长
const STEP = 20
// 分割容器
// 18行 10列
const ROW_COUNT = 18, COL_COUNT = 10

2. 以 16宫格 为基准,定义 L 形状的 4 个方块的位置

// 分割容器
// 18行 10列
const ROW_COUNT = 18, COL_COUNT = 10
// 创建每个模型的数据源
const MODELS = [
  // 第1个模型数据源(L型)
  {
   
    0: {
   
      row: 2,
      col: 0
    },
    1: {
   
      row: 2,
      col: 1
    },
    2: {
   
      row: 2,
      col: 2
    },
    3: {
   
      row: 1,
      col: 2
    }
  }]

3. 创建 L 型模型,根据 16 宫格中的数据将模型渲染到页面上

// 分割容器
// 18行 10列
const ROW_COUNT = 18, COL_COUNT = 10
// 创建每个模型的数据源
const MODELS = [
  // 第1个模型数据源(L型)
  {
   
    0: {
   
      row: 2,
      col: 0
    },
    1: {
   
      row: 2,
      col: 1
    },
    2: {
   
      row: 2,
      col: 2
    },
    3: {
   
      row: 1,
      col: 2
    }
  }]
// 变量
// 当前使用的模型
let currentModel = {
   }
init()
// 入口方法
function init() {
   
  createModel()
  onKeyDown()
}

// 根据模型使用的数据创建对应的块元素
function createModel() {
   
  // 确定当前使用哪一个模型
  currentModel = MODELS[0]
  // 生成对应数量的块元素
  for (const key in currentModel) {
   
    const divEle = document.createElement('div')
    divEle.className = "activity-model"
    document.getElementById("container").appendChild(divEle)
  }
  // 定位块元素位置
  locationBlocks()
}

// 根据数据源定位块元素的位置
function locationBlocks() {
   
  // 1 拿到所有的块元素
  const eles = document.getElementsByClassName("activity-model")
  for (let i = 0; i < eles.length; i++) {
   
    // 单个块元素
    const activityModelEle = eles[i]
    // 2 找到每个块元素对应的数据 (行、列)
    const blockModel = currentModel[i]
    // 3 根据每个块元素对应的数据来指定块元素的位置
    activityModelEle.style.top = blockModel.row * STEP + "px"
    activityModelEle.style.left = blockModel.col * STEP + "px"
  }
}

控制该模型进行移动

  • 本质是控制 16 宫格 进行移动
// 根据数据源定位块元素的位置
function locationBlocks() {
   
  // 1 拿到所有的块元素
  const eles = document.getElementsByClassName("activity-model")
  for (let i = 0; i < eles.length; i++) {
   
    // 单个块元素
    const activityModelEle = eles[i]
    // 2 找到每个块元素对应的数据 (行、列)
    const blockModel = currentModel[i]
    // 3 根据每个块元素对应的数据来指定块元素的位置
    // 每个块元素的位置由2个值确定:
    //  a. 16 宫格所在的位置
    //  b. 块元素在 16 宫格中的位置 
    activityModelEle.style.top = (currentY + blockModel.row) * STEP + "px"
    activityModelEle.style.left = (currentX + blockModel.col) * STEP + "px"
  }
}

// 移动
function move(x, y) {
   
  // 控制16宫格元素进行移动
  currentX += x
  currentY += y
  // 根据16宫格的位置来重新定位块元素
  locationBlocks()
}

控制模型旋转

在这里插入图片描述

规律

  • 16宫格 的中心点为基准进行旋转
  • 观察上图中旋转后每个块元素发生的位置的变化
  • 以第1,2个L模型为例,可以观察到:
    • 块元素1的坐标(列, 行)变化:(0, 2) -> (1, 0)
    • 块元素2的坐标(列, 行)变化:(1, 2) -> (1, 1)
    • 块元素3的坐标(列, 行)变化:(2, 2) -> (1, 2)
    • 块元素4的坐标(列, 行)变化:(2, 1) -> (2, 2)
  • 其基本变化规律是
    • 移动后的行 = 移动前的列
    • 移动后的列 = 3 - 移动前的行

旋转模型

// 监听用户的键盘事件
function onKeyDown() {
   
  document.onkeydown = event => {
   
    switch (event.keyCode) {
   
      case 38: // 上
        // move(0, -1)
        rotate()
        break;
      case 39: // 右
        move(1, 0)
        
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
俄罗斯方块是一款非常经典的游戏,使用 JavaScriptHTML5 可以很容易地实现。下面是一个简单俄罗斯方块小游戏的示例,你可以基于这个示例进行修改和扩展。 HTML 代码: ```html <!DOCTYPE html> <html> <head> <title>俄罗斯方块</title> <style> #game-board { width: 200px; height: 400px; border: 1px solid black; } </style> </head> <body> <div id="game-board"></div> <script src="tetris.js"></script> </body> </html> ``` JavaScript 代码: ```javascript var gameBoard = document.getElementById("game-board"); var ctx = gameBoard.getContext("2d"); var board = []; for (var row = 0; row < 20; row++) { board[row] = []; for (var col = 0; col < 10; col++) { board[row][col] = 0; } } var pieces = [ // I [ [1, 1, 1, 1] ], // J [ [1, 0, 0], [1, 1, 1] ], // L [ [0, 0, 1], [1, 1, 1] ], // O [ [1, 1], [1, 1] ], // S [ [0, 1, 1], [1, 1, 0] ], // T [ [0, 1, 0], [1, 1, 1] ], // Z [ [1, 1, 0], [0, 1, 1] ] ]; var colors = [ "#00ffff", // I "#0000ff", // J "#ff8000", // L "#ffff00", // O "#00ff00", // S "#8000ff", // T "#ff0000" // Z ]; var currentPiece = { piece: pieces[Math.floor(Math.random() * pieces.length)], row: 0, col: 3 }; function drawSquare(row, col, color) { ctx.fillStyle = color; ctx.fillRect(col * 20, row * 20, 20, 20); } function drawBoard() { for (var row = 0; row < board.length; row++) { for (var col = 0; col < board[row].length; col++) { if (board[row][col] !== 0) { drawSquare(row, col, colors[board[row][col] - 1]); } } } } function drawPiece() { var piece = currentPiece.piece; var row = currentPiece.row; var col = currentPiece.col; for (var r = 0; r < piece.length; r++) { for (var c = 0; c < piece[r].length; c++) { if (piece[r][c] === 1) { drawSquare(row + r, col + c, colors[pieces.indexOf(piece)]); } } } } function can

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值