当前位置: 首页 > news >正文

“2048”游戏网页版html+css+js

“2048”游戏网页版html+css+js

 别忘了请点个赞+收藏+关注支持一下博主喵!!!

   2048 游戏是一个非常流行的数字拼图游戏,玩家通过移动方块使相同数字的方块合并,最终达到 2048 或更高分数。本教程将详细介绍如何使用 HTML、CSS 和 JavaScript 创建一个简单的 2048 游戏网页。。

  项目结构如下:(懒得搭vue了)

2048-game/
├── index.html
├── styles.css
└── script.js

1. index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"> <!-- 设置文档的字符编码为 UTF-8 --><meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 使页面在移动设备上适配屏幕宽度 --><title>2048 Game</title> <!-- 页面标题 --><link rel="stylesheet" href="styles.css"> <!-- 引入外部 CSS 文件 -->
</head>
<body><div class="game-container"> <!-- 游戏容器,用于包裹整个游戏界面 --><div class="score-container">0</div> <!-- 分数显示区域 --><div class="grid-container"> <!-- 网格容器,用于包裹 4x4 的游戏网格 --><div class="grid-row"> <!-- 每一行的网格 --><div class="grid-cell"></div> <!-- 每一个网格单元 --><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div></div><button id="restart-button">Restart</button> <!-- 重新开始按钮 --></div><script src="script.js"></script> <!-- 引入外部 JavaScript 文件 -->
</body>
</html>

2. styles.css

body {display: flex; /* 使用 Flexbox 布局 */justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */height: 100vh; /* 占满整个视窗高度 */margin: 0; /* 移除默认外边距 */background-color: #faf8ef; /* 背景颜色 */font-family: Arial, sans-serif; /* 字体设置 */
}.game-container {width: 500px; /* 容器宽度 */height: 500px; /* 容器高度 */position: relative; /* 相对定位 */background-color: #bbada0; /* 背景颜色 */border-radius: 10px; /* 圆角 */box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3); /* 阴影效果 */
}.score-container {position: absolute; /* 绝对定位 */top: 10px; /* 距离顶部 10px */left: 10px; /* 距离左边 10px */background-color: #eee4da; /* 背景颜色 */padding: 10px; /* 内边距 */border-radius: 5px; /* 圆角 */font-size: 24px; /* 字体大小 */font-weight: bold; /* 加粗字体 */
}.grid-container {width: 400px; /* 网格容器宽度 */height: 400px; /* 网格容器高度 */position: absolute; /* 绝对定位 */top: 50%; /* 距离顶部 50% */left: 50%; /* 距离左边 50% */transform: translate(-50%, -50%); /* 居中对齐 */display: grid; /* 使用 Grid 布局 */grid-template-columns: repeat(4, 100px); /* 4 列,每列 100px */grid-template-rows: repeat(4, 100px); /* 4 行,每行 100px */gap: 10px; /* 网格间距 */
}.grid-cell {background-color: #cdc1b4; /* 背景颜色 */border-radius: 3px; /* 圆角 */display: flex; /* 使用 Flexbox 布局 */justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */font-size: 32px; /* 字体大小 */font-weight: bold; /* 加粗字体 */color: #776e65; /* 文字颜色 */
}/* 不同数字的方块样式 */
.grid-cell.number-2 { background-color: #eee4da; color: #776e65; }
.grid-cell.number-4 { background-color: #ede0c8; color: #776e65; }
.grid-cell.number-8 { background-color: #f2b179; color: #f9f6f2; }
.grid-cell.number-16 { background-color: #f59563; color: #f9f6f2; }
.grid-cell.number-32 { background-color: #f67c5f; color: #f9f6f2; }
.grid-cell.number-64 { background-color: #f65e3b; color: #f9f6f2; }
.grid-cell.number-128 { background-color: #edcf72; color: #f9f6f2; }
.grid-cell.number-256 { background-color: #edcc61; color: #f9f6f2; }
.grid-cell.number-512 { background-color: #edc850; color: #f9f6f2; }
.grid-cell.number-1024 { background-color: #edc53f; color: #f9f6f2; }
.grid-cell.number-2048 { background-color: #edc22e; color: #f9f6f2; }#restart-button {position: absolute; /* 绝对定位 */bottom: 10px; /* 距离底部 10px */left: 50%; /* 距离左边 50% */transform: translateX(-50%); /* 水平居中 */padding: 10px 20px; /* 内边距 */background-color: #8f7a66; /* 背景颜色 */color: #f9f6f2; /* 文字颜色 */border: none; /* 无边框 */border-radius: 5px; /* 圆角 */cursor: pointer; /* 鼠标指针样式 */font-size: 18px; /* 字体大小 */font-weight: bold; /* 加粗字体 */
}#restart-button:hover {background-color: #746655; /* 鼠标悬停时的背景颜色 */
}

3. 最难的script.js

代码分布详解:

1. 获取 DOM 元素

const grid = document.querySelector('.grid-container'); // 获取网格容器
const cells = document.querySelectorAll('.grid-cell'); // 获取所有网格单元
const scoreContainer = document.querySelector('.score-container'); // 获取分数显示区域
const restartButton = document.getElementById('restart-button'); // 获取重新开始按钮

这些代码通过 querySelectorgetElementById 方法获取页面上的各个元素,以便后续操作。

2. 初始化变量

let score = 0; // 初始化分数
let hasWon = false; // 标记是否已经赢得游戏const matrix = [[0, 0, 0, 0], // 初始化 4x4 的矩阵[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]
];const winNumber = 2048; // 赢得游戏的目标数字
  • score:当前得分。
  • hasWon:标记是否已经赢得游戏。
  • matrix:4x4 的二维数组,用于存储游戏中的数字。
  • winNumber:赢得游戏的目标数字,即 2048。

 3. 获取随机空格子

function getRandomEmptyCell() {const emptyCells = []; // 存储所有空格子的坐标for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0) { // 如果格子为空emptyCells.push({ row: i, col: j }); // 将坐标加入空格子列表}}}if (emptyCells.length > 0) { // 如果有空格子const randomIndex = Math.floor(Math.random() * emptyCells.length); // 随机选择一个空格子return emptyCells[randomIndex];}return null; // 没有空格子返回 null
}

这个函数遍历 matrix,找到所有为空的格子,并将它们的坐标存储在 emptyCells 数组中。如果存在空格子,则随机选择一个返回;否则返回 null。 

算法步骤:

  1. 初始化一个空数组 emptyCells,用于存储所有空格子的坐标。
  2. 使用两层嵌套循环遍历 matrix,检查每个格子是否为空(即 matrix[i][j] === 0)。
  3. 如果格子为空,将该格子的坐标 { row: i, col: j } 推入 emptyCells 数组。
  4. 循环结束后,检查 emptyCells 是否有元素。
  5. 如果有空格子,随机选择一个空格子的索引 randomIndex,并返回该空格子的坐标。
  6. 如果没有空格子,返回 null

4. 添加随机方块

function addRandomTile() {const cell = getRandomEmptyCell();if (cell) {const value = Math.random() < 0.9 ? 2 : 4; // 90% 的概率生成 2,10% 的概率生成 4matrix[cell.row][cell.col] = value; // 更新矩阵updateGrid(); // 更新网格显示}
}

这个函数调用 getRandomEmptyCell 获取一个随机的空格子,然后以 90% 的概率生成 2,10% 的概率生成 4,并更新 matrix 和网格显示。 

算法步骤:

  1. 调用 getRandomEmptyCell 获取一个随机的空格子。
  2. 如果找到了空格子:
    • 生成一个随机值 value,90% 的概率生成 2,10% 的概率生成 4。
    • 更新 matrix 中对应位置的值为 value
    • 调用 updateGrid 更新网格显示。

5. 更新网格显示

function updateGrid() {cells.forEach((cell, index) => {const row = Math.floor(index / 4); // 计算当前单元格所在的行const col = index % 4; // 计算当前单元格所在的列const value = matrix[row][col]; // 获取矩阵中的值cell.textContent = value || ''; // 显示值,如果没有值则显示空字符串cell.classList.remove('number-2', 'number-4', 'number-8', 'number-16', 'number-32', 'number-64', 'number-128', 'number-256', 'number-512', 'number-1024', 'number-2048'); // 移除所有样式类if (value !== 0) { // 如果有值,添加对应的样式类cell.classList.add(`number-${value}`);}});
}

这个函数遍历所有 cells,根据 matrix 中的值更新每个单元格的文本内容和样式类。 

算法步骤:

  1. 遍历所有 cells,使用 forEach 方法。
  2. 对于每个 cell,计算其在 matrix 中的行 row 和列 col
  3. 获取 matrix 中对应位置的值 value
  4. 设置 cell 的文本内容为 value,如果没有值则显示为空字符串。
  5. 移除 cell 上的所有样式类。
  6. 如果 value 不为 0,添加对应的样式类 number-${value}

6. 向上移动

function moveUp() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 0; row < 4; row++) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 0; row < 4; row++) {matrix[row][col] = tempCol[row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}

这个函数处理向上移动的操作:

  1. 遍历每一列。
  2. 将每列中的非零值存储到 tempCol 中。
  3. 调用 mergeTiles 合并相同的值。
  4. 更新 matrix
  5. 添加新的方块。
  6. 检查游戏是否结束。

算法步骤:

  1. 遍历每一列 col
  2. 初始化一个空数组 tempCol,用于存储当前列中的非零值。
  3. 使用内层循环遍历当前列的每一行 row,将非零值推入 tempCol
  4. 调用 mergeTiles 合并 tempCol 中的相同值。
  5. 使用内层循环更新 matrix 中当前列的值,从 tempCol 中取值,如果 tempCol 中没有值则设为 0。
  6. 调用 addRandomTile 添加一个新的方块。
  7. 调用 checkGameOver 检查游戏是否结束。

 7. 向下移动

function moveDown() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 3; row >= 0; row--) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 3; row >= 0; row--) {matrix[row][col] = tempCol[3 - row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}

这个函数处理向下移动的操作,与 moveUp 类似,只是方向相反。 

8. 向左移动

function moveLeft() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 0; col < 4; col++) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 0; col < 4; col++) {matrix[row][col] = tempRow[col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}

 这个函数处理向左移动的操作,与 moveUp 类似,只是方向不同。

  1. 遍历每一行 row
  2. 初始化一个空数组 tempRow,用于存储当前行中的非零值。
  3. 使用内层循环遍历当前行的每一列 col,将非零值推入 tempRow
  4. 调用 mergeTiles 合并 tempRow 中的相同值。
  5. 使用内层循环更新 matrix 中当前行的值,从 tempRow 中取值,如果 tempRow 中没有值则设为 0。
  6. 调用 addRandomTile 添加一个新的方块。
  7. 调用 checkGameOver 检查游戏是否结束。

9. 向右移动

function moveRight() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 3; col >= 0; col--) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 3; col >= 0; col--) {matrix[row][col] = tempRow[3 - col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}

这个函数处理向右移动的操作,与 moveLeft 类似,只是方向相反。 

10. 合并相同的值

function mergeTiles(tiles) {for (let i = 0; i < tiles.length - 1; i++) {if (tiles[i] === tiles[i + 1]) { // 如果相邻的两个值相同tiles[i] *= 2; // 合并值tiles.splice(i + 1, 1); // 删除合并后的值score += tiles[i]; // 更新分数scoreContainer.textContent = score; // 更新分数显示if (tiles[i] === winNumber && !hasWon) { // 如果达到目标值且未赢过alert('You Win!'); // 提示胜利hasWon = true; // 标记已赢}}}while (tiles.length < 4) { // 确保列表长度为 4tiles.push(0);}return tiles;
}

这个函数合并 tiles 列表中的相同值:

  1. 遍历 tiles,如果相邻的两个值相同,则合并它们。
  2. 更新分数和分数显示。
  3. 如果达到目标值 2048 且未赢过,则提示胜利。
  4. 确保 tiles 列表长度为 4。

算法步骤:

  1. 遍历 tiles 数组,检查相邻的两个值是否相同。
  2. 如果相邻的两个值相同:
    • 将第一个值乘以 2。
    • 从数组中删除第二个值。
    • 更新分数 score 并更新分数显示。
    • 如果合并后的值等于 winNumber 且未赢过,提示胜利并标记已赢。
  3. 使用 while 循环确保 tiles 数组的长度为 4,不足的部分用 0 填充。
  4. 返回合并后的 tiles 数组。

 11. 检查游戏是否结束

function checkGameOver() {let gameOver = true; // 默认游戏结束for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0 || // 如果有空格子(i < 3 && matrix[i][j] === matrix[i + 1][j]) || // 或者有相邻的相同值(j < 3 && matrix[i][j] === matrix[i][j + 1])) {gameOver = false; // 游戏未结束break;}}if (!gameOver) break;}if (gameOver) {alert('Game Over!'); // 提示游戏结束}
}

这个函数检查游戏是否结束:

  1. 遍历 matrix,检查是否有空格子或相邻的相同值。
  2. 如果有空格子或相邻的相同值,则游戏未结束。
  3. 否则,提示游戏结束。

算法步骤:

  1. 初始化一个布尔变量 gameOver 为 true,默认游戏结束。
  2. 使用两层嵌套循环遍历 matrix,检查每个格子是否为空或有相邻的相同值。
  3. 如果有空格子或有相邻的相同值,将 gameOver 设为 false 并跳出循环。
  4. 如果 gameOver 仍为 true,提示游戏结束。

 12. 重新开始游戏

function restartGame() {matrix.forEach(row => row.fill(0)); // 重置矩阵score = 0; // 重置分数hasWon = false; // 重置胜利标记scoreContainer.textContent = score; // 更新分数显示addRandomTile(); // 添加初始方块addRandomTile(); // 添加初始方块updateGrid(); // 更新网格显示
}

这个函数重置游戏:

  1. 重置 matrix
  2. 重置分数和胜利标记。
  3. 更新分数显示。
  4. 添加两个初始方块。
  5. 更新网格显示。

算法步骤:

  1. 使用 forEach 方法遍历 matrix 的每一行,将每一行的值全部设为 0。
  2. 将分数 score 设为 0。
  3. 将胜利标记 hasWon 设为 false
  4. 更新分数显示。
  5. 调用 addRandomTile 两次,添加两个初始方块。
  6. 调用 updateGrid 更新网格显示。

 13. 监听键盘事件

document.addEventListener('keydown', (event) => {switch (event.key) {case 'ArrowUp': // 上箭头moveUp();break;case 'ArrowDown': // 下箭头moveDown();break;case 'ArrowLeft': // 左箭头moveLeft();break;case 'ArrowRight': // 右箭头moveRight();break;}
});

 这个事件监听器监听键盘事件,根据按键方向调用相应的移动函数

14. 监听重新开始按钮点击事件

restartButton.addEventListener('click', restartGame);

这个事件监听器监听重新开始按钮的点击事件,调用 restartGame 重置游戏。 

15. 初始化游戏

restartGame();

最终代码:

const grid = document.querySelector('.grid-container'); // 获取网格容器
const cells = document.querySelectorAll('.grid-cell'); // 获取所有网格单元
const scoreContainer = document.querySelector('.score-container'); // 获取分数显示区域
const restartButton = document.getElementById('restart-button'); // 获取重新开始按钮let score = 0; // 初始化分数
let hasWon = false; // 标记是否已经赢得游戏const matrix = [[0, 0, 0, 0], // 初始化 4x4 的矩阵[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]
];const winNumber = 2048; // 赢得游戏的目标数字// 获取一个随机的空格子
function getRandomEmptyCell() {const emptyCells = []; // 存储所有空格子的坐标for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0) { // 如果格子为空emptyCells.push({ row: i, col: j }); // 将坐标加入空格子列表}}}if (emptyCells.length > 0) { // 如果有空格子const randomIndex = Math.floor(Math.random() * emptyCells.length); // 随机选择一个空格子return emptyCells[randomIndex];}return null; // 没有空格子返回 null
}// 在随机选择的空格子中添加一个新方块(2 或 4)
function addRandomTile() {const cell = getRandomEmptyCell();if (cell) {const value = Math.random() < 0.9 ? 2 : 4; // 90% 的概率生成 2,10% 的概率生成 4matrix[cell.row][cell.col] = value; // 更新矩阵updateGrid(); // 更新网格显示}
}// 更新 HTML 网格中的方块显示
function updateGrid() {cells.forEach((cell, index) => {const row = Math.floor(index / 4); // 计算当前单元格所在的行const col = index % 4; // 计算当前单元格所在的列const value = matrix[row][col]; // 获取矩阵中的值cell.textContent = value || ''; // 显示值,如果没有值则显示空字符串cell.classList.remove('number-2', 'number-4', 'number-8', 'number-16', 'number-32', 'number-64', 'number-128', 'number-256', 'number-512', 'number-1024', 'number-2048'); // 移除所有样式类if (value !== 0) { // 如果有值,添加对应的样式类cell.classList.add(`number-${value}`);}});
}// 向上移动
function moveUp() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 0; row < 4; row++) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 0; row < 4; row++) {matrix[row][col] = tempCol[row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向下移动
function moveDown() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 3; row >= 0; row--) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 3; row >= 0; row--) {matrix[row][col] = tempCol[3 - row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向左移动
function moveLeft() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 0; col < 4; col++) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 0; col < 4; col++) {matrix[row][col] = tempRow[col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向右移动
function moveRight() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 3; col >= 0; col--) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 3; col >= 0; col--) {matrix[row][col] = tempRow[3 - col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 合并相同的值
function mergeTiles(tiles) {for (let i = 0; i < tiles.length - 1; i++) {if (tiles[i] === tiles[i + 1]) { // 如果相邻的两个值相同tiles[i] *= 2; // 合并值tiles.splice(i + 1, 1); // 删除合并后的值score += tiles[i]; // 更新分数scoreContainer.textContent = score; // 更新分数显示if (tiles[i] === winNumber && !hasWon) { // 如果达到目标值且未赢过alert('You Win!'); // 提示胜利hasWon = true; // 标记已赢}}}while (tiles.length < 4) { // 确保列表长度为 4tiles.push(0);}return tiles;
}// 检查游戏是否结束
function checkGameOver() {let gameOver = true; // 默认游戏结束for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0 || // 如果有空格子(i < 3 && matrix[i][j] === matrix[i + 1][j]) || // 或者有相邻的相同值(j < 3 && matrix[i][j] === matrix[i][j + 1])) {gameOver = false; // 游戏未结束break;}}if (!gameOver) break;}if (gameOver) {alert('Game Over!'); // 提示游戏结束}
}// 重新开始游戏
function restartGame() {matrix.forEach(row => row.fill(0)); // 重置矩阵score = 0; // 重置分数hasWon = false; // 重置胜利标记scoreContainer.textContent = score; // 更新分数显示addRandomTile(); // 添加初始方块addRandomTile(); // 添加初始方块updateGrid(); // 更新网格显示
}// 监听键盘事件
document.addEventListener('keydown', (event) => {switch (event.key) {case 'ArrowUp': // 上箭头moveUp();break;case 'ArrowDown': // 下箭头moveDown();break;case 'ArrowLeft': // 左箭头moveLeft();break;case 'ArrowRight': // 右箭头moveRight();break;}
});// 监听重新开始按钮点击事件
restartButton.addEventListener('click', restartGame);// 初始化游戏
restartGame();

 别忘了请点个赞+收藏+关注支持一下博主喵!!!

累了,水一下吧。。。。。。∗︎˚(* ˃̤൬˂̤ *)˚∗︎

gitee:2048-game: html+css+js设计的一个2048游戏(网页)


http://www.mrgr.cn/news/69411.html

相关文章:

  • Cellebrite VS IOS18Rebooting
  • 如何用re从第1排第2个位置中找到两个数字返回(0,1)
  • mmsegmentation: 安装 并使用自定义数据集进行训练 ·1
  • 《目标检测》——基础理论知识(目标检测的数据集、评价指标:IOU、mAP、非极大抑制NMS)
  • 38配置管理工具(如Ansible、Puppet、Chef)
  • SpringCloud篇(微服务)
  • 2024系统分析师---微服务架构(淘宝押题)
  • 万字长文解读深度学习——GPT、BERT、T5
  • FFmpeg存放压缩后的音视频数据的结构体:AVPacket简介,结构体,函数
  • C++入门(下)
  • 关于c语言内存越界及防范措施
  • C#-密封类、密封方法
  • 发顶会首选:大模型+时间序列!掌握这3大切入点,小白也能轻松上手!
  • 终端会话工具byobu
  • 增强现实技术在零售业中的应用
  • 程序员应该有什么职业素养?
  • 每日一题之二叉树
  • 程序员学长 | 最强总结,机器学习中处理不平衡数据集的五种方法!!
  • 配置多公钥在多平台使用Git
  • 【Steam登录】protobuf协议逆向
  • 字符在线统计字符在线统计
  • Vue3中使用Ant Design Vue的Table组件详解
  • Qt教程(007):资源文件添加
  • 利用 Screen 保持 VSCode 连接远程任务持续运行
  • 使用Docker快速部署FastAPI Web应用
  • 中介者设计模式 软考