致敬1024程序员节:用JavaScript编写一个简单的1024小游戏

引言

在每年的10月24日,我们都会庆祝程序员节,这是一个向所有辛勤工作、创造出无数令人惊叹应用和系统的程序员们致敬的日子。为了纪念这个特殊的日子,我们将通过编写一个简单的1024小游戏来向所有程序员们表示敬意。本文将详细解释如何使用JavaScript编写这个小游戏,并对代码进行分段讲解。

1. HTML 结构

在HTML部分,我们首先需要创建一个容器来放置游戏方块。代码如下:

html 复制代码
<div class="game-container"></div>

2. CSS 样式

接下来,我们需要为游戏面板和方块设置样式。代码如下:

css 复制代码
.game-container {
    display: flex;
    flex-wrap: wrap;
    width: 408px;
    height: 408px;
    border: 1px solid black;
}
.game-tile {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100px;
    height: 100px;
    border: 1px solid black;
}
.tile-2 {
    background-color: #eee4da;
}

.tile-4 {
    background-color: #ede0c8;
}

.tile-8 {
    background-color: #f2b179;
}

.tile-16 {
    background-color: #f59563;
}

.tile-32 {
    background-color: #f67c5f;
}

.tile-64 {
    background-color: #f65e3b;
}

.tile-128 {
    background-color: #edcf72;
}

.tile-256 {
    background-color: #edcc61;
}

.tile-512 {
    background-color: #edc850;
}

.tile-1024 {
    background-color: #edc53f;
}

3. JavaScript部分

初始化游戏面板和方块

代码如下:

javascript 复制代码
// 创建游戏面板
const gameContainer = document.querySelector('.game-container');
const tiles = [];

// 生成游戏方块并添加到面板中
for (let i = 0; i < 16; i++) {
    const tile = document.createElement('div');
    tile.classList.add('game-tile');
    tiles.push(tile);
    gameContainer.appendChild(tile);
}

游戏数据初始化和更新

接下来,我们需要初始化游戏数据,并实现生成新方块和更新游戏面板的功能。代码如下:

javascript 复制代码
let board = Array(16).fill(0);
function generateRandomTile() {
 // ...
}
function updateBoard() {
 // ...
}

方块移动和合并

为了使游戏能够响应玩家的操作,我们需要实现方块的移动和合并功能。代码如下:

javascript 复制代码
function moveLeft() {
 // ...
}
function moveRight() {
 // ...
}
function moveUp() {
 // ...
}
function moveDown() {
 // ...
}

键盘事件监听

为了让玩家能够通过键盘操作游戏,我们需要监听键盘事件,并根据按键来调用相应的移动函数。代码如下:

javascript 复制代码
function handleKeyDown(event) {
 // ...
}
document.addEventListener('keydown', handleKeyDown);

游戏初始化

最后,我们需要初始化游戏。代码如下:

javascript 复制代码
generateRandomTile();
generateRandomTile();
updateBoard();

完整代码

html 复制代码
<!DOCTYPE html>
<html>

<head>
  <title>1024 Game</title>
  <style>
    .game-container {
      display: flex;
      flex-wrap: wrap;
      width: 408px;
      height: 408px;
      border: 1px solid black;
    }

    .game-tile {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100px;
      height: 100px;
      border: 1px solid black;
      font-size: 24px;
    }

    .tile-2 {
      background-color: #eee4da;
    }

    .tile-4 {
      background-color: #ede0c8;
    }

    .tile-8 {
      background-color: #f2b179;
    }

    .tile-16 {
      background-color: #f59563;
    }

    .tile-32 {
      background-color: #f67c5f;
    }

    .tile-64 {
      background-color: #f65e3b;
    }

    .tile-128 {
      background-color: #edcf72;
    }

    .tile-256 {
      background-color: #edcc61;
    }

    .tile-512 {
      background-color: #edc850;
    }

    .tile-1024 {
      background-color: #edc53f;
    }
  </style>
</head>

<body>
  <div class="game-container"></div>
  <script>
    // 创建游戏面板
    const gameContainer = document.querySelector('.game-container')
    const tiles = []
    for (let i = 0; i < 16; i++) {
      const tile = document.createElement('div')
      tile.classList.add('game-tile')
      tiles.push(tile)
      gameContainer.appendChild(tile)
    }
    // 初始化游戏数据
    let board = Array(16).fill(0)
    function generateRandomTile() {
      const emptyTiles = board.reduce((acc, curr, index) => {
        if (curr === 0) {
          acc.push(index)
        }
        return acc
      }, [])
      console.log({ emptyTiles })
      if (emptyTiles.length === 0) {
        return false
      }
      const randomIndex =
        emptyTiles[Math.floor(Math.random() * emptyTiles.length)]

      // 随机生成2或4
      board[randomIndex] = Math.random() > 0.5 ? 2 : 4
      return true // 成功生成新方块
    }
    function updateBoard() {
      for (let i = 0; i < 16; i++) {
        tiles[i].innerText = board[i] === 0 ? '' : board[i]
        tiles[i].className = `game-tile tile-${board[i]}`
      }
    }
    function moveLeft() {
      let hasChanged = false
      for (let i = 0; i < 4; i++) {
        const row = board.slice(i * 4, (i + 1) * 4)

        // 合并相同的方块
        for (let j = row.length - 1; j > 0; j--) {
          if (row[j] === row[j - 1]) {
            row[j] *= 2
            row[j - 1] = 0
            hasChanged = true
          }
        }
        // 移动方块
        for (let j = row.length - 1; j > 0; j--) {
          if (row[j - 1] === 0) {
            row[j - 1] = row[j]
            row[j] = 0
            hasChanged = true
          }
        }
        board.splice(i * 4, 4, ...row)
      }
      return hasChanged
    }
    function moveRight() {
      let hasChanged = false
      for (let i = 0; i < 4; i++) {
        const row = board.slice(i * 4, (i + 1) * 4)

        // 合并相同的方块
        for (let j = 0; j < row.length - 1; j++) {
          if (row[j] === row[j + 1]) {
            row[j] *= 2
            row[j + 1] = 0
            hasChanged = true
          }
        }
        // 移动方块
        for (let j = 0; j < row.length - 1; j++) {
          if (row[j + 1] === 0) {
            row[j + 1] = row[j]
            row[j] = 0
            hasChanged = true
          }
        }
        board.splice(i * 4, 4, ...row)
      }
      return hasChanged
    }
    function moveUp() {
      let hasChanged = false
      for (let i = 0; i < 4; i++) {
        const column = [board[i], board[i + 4], board[i + 8], board[i + 12]]

        // 合并相同的方块
        for (let j = column.length - 1; j > 0; j--) {
          if (column[j] === column[j - 1]) {
            column[j] *= 2
            column[j - 1] = 0
            hasChanged = true
          }
        }
        // 移动方块
        for (let j = column.length - 1; j > 0; j--) {
          if (column[j - 1] === 0) {
            column[j - 1] = column[j]
            column[j] = 0
            hasChanged = true
          }
        }
        board[i] = column[0]
        board[i + 4] = column[1]
        board[i + 8] = column[2]
        board[i + 12] = column[3]
      }
      return hasChanged
    }
    function moveDown() {
      let hasChanged = false
      for (let i = 0; i < 4; i++) {
        const column = [board[i], board[i + 4], board[i + 8], board[i + 12]]

        // 合并相同的方块
        for (let j = 0; j < column.length - 1; j++) {
          if (column[j] === column[j + 1]) {
            column[j] *= 2
            column[j + 1] = 0
            hasChanged = true
          }
        }
        // 移动方块
        for (let j = 0; j < column.length - 1; j++) {
          if (column[j + 1] === 0) {
            column[j + 1] = column[j]
            column[j] = 0
            hasChanged = true
          }
        }
        board[i] = column[0]
        board[i + 4] = column[1]
        board[i + 8] = column[2]
        board[i + 12] = column[3]
      }
      return hasChanged
    }
    function handleKeyDown(event) {
      let hasChanged = false
      switch (event.key) {
        case 'ArrowLeft':
          hasChanged = moveLeft()
          break
        case 'ArrowRight':
          hasChanged = moveRight()
          break
        case 'ArrowUp':
          hasChanged = moveUp()
          break
        case 'ArrowDown':
          hasChanged = moveDown()
          break
      }
      if (hasChanged) {
        generateRandomTile()
        updateBoard()
      } else {
        console.log('123456')
      }
    }
    // 初始化游戏
    generateRandomTile()
    generateRandomTile()
    updateBoard()
    // 监听键盘事件
    document.addEventListener('keydown', handleKeyDown)
  </script>
</body>

</html>

效果图

总结

通过以上的代码解释,我们详细了解了如何使用JavaScript编写一个简单的1024小游戏。这个小游戏通过键盘操作来移动方块,合并相同数字的方块,直到达到无法继续移动为止。这个小游戏不仅是对1024程序员节 的致敬,也是对所有辛勤工作、创造出无数令人惊叹应用和系统的程序员们的致敬。让我们一起庆祝1024程序员节,并感谢所有程序员们为我们带来的技术和创新!

相关推荐
2分钟速写快排13 分钟前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60611 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角2 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!2 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰2 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi4 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen4 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马5 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu5 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss
IT_陈寒5 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端