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

用Deepseek写扫雷uniapp小游戏

扫雷作为Windows系统自带的经典小游戏,承载了许多人的童年回忆。本文将详细介绍如何使用Uniapp框架从零开始实现一个完整的扫雷游戏,包含核心算法、交互设计和状态管理。无论你是Uniapp初学者还是有一定经验的开发者,都能从本文中获得启发。

一、游戏设计思路

1.1 游戏规则回顾

扫雷游戏的基本规则非常简单:

  • 游戏区域由方格组成,部分方格下藏有地雷

  • 玩家点击方格可以揭开它

  • 如果揭开的是地雷,游戏结束

  • 如果揭开的是空白格子,会显示周围8格中的地雷数量

  • 玩家可以通过标记来标识可能的地雷位置

  • 当所有非地雷方格都被揭开时,玩家获胜

1.2 技术实现要点

基于上述规则,我们需要实现以下核心功能:

  1. 游戏棋盘的数据结构

  2. 随机布置地雷的算法

  3. 计算每个格子周围地雷数量的方法

  4. 点击和长按的交互处理

  5. 游戏状态管理(进行中、胜利、失败)

  6. 计时和剩余地雷数的显示

二、Uniapp实现详解

2.1 项目结构

我们创建一个单独的页面minesweeper/minesweeper.vue来实现游戏,主要包含三个部分:

  • 模板部分:游戏界面布局

  • 脚本部分:游戏逻辑实现

  • 样式部分:游戏视觉效果

2.2 核心代码解析

2.2.1 游戏数据初始化
data() {return {rows: 10,       // 行数cols: 10,       // 列数mines: 15,      // 地雷数board: [],      // 游戏棋盘数据remainingMines: 0, // 剩余地雷数time: 0,        // 游戏时间timer: null,    // 计时器gameOver: false, // 游戏是否结束gameOverMessage: '', // 结束消息firstClick: true // 是否是第一次点击}
}
2.2.2 游戏初始化方法
startGame(rows, cols, mines) {this.rows = rows;this.cols = cols;this.mines = mines;this.remainingMines = mines;this.time = 0;this.gameOver = false;this.firstClick = true;// 初始化棋盘数据结构this.board = Array(rows).fill().map(() => Array(cols).fill().map(() => ({mine: false,          // 是否是地雷revealed: false,      // 是否已揭开flagged: false,       // 是否已标记neighborMines: 0,     // 周围地雷数exploded: false       // 是否爆炸(踩中地雷)})));
}
2.2.3 地雷布置算法
placeMines(firstRow, firstCol) {let minesPlaced = 0;// 随机布置地雷,但避开第一次点击位置及周围while (minesPlaced < this.mines) {const row = Math.floor(Math.random() * this.rows);const col = Math.floor(Math.random() * this.cols);if (!this.board[row][col].mine && Math.abs(row - firstRow) > 1 && Math.abs(col - firstCol) > 1) {this.board[row][col].mine = true;minesPlaced++;}}// 计算每个格子周围的地雷数for (let row = 0; row < this.rows; row++) {for (let col = 0; col < this.cols; col++) {if (!this.board[row][col].mine) {let count = 0;// 检查周围8个格子for (let r = Math.max(0, row - 1); r <= Math.min(this.rows - 1, row + 1); r++) {for (let c = Math.max(0, col - 1); c <= Math.min(this.cols - 1, col + 1); c++) {if (this.board[r][c].mine) count++;}}this.board[row][col].neighborMines = count;}}}
}

 2.2.4 格子揭示逻辑

revealCell(row, col) {// 第一次点击时布置地雷if (this.firstClick) {this.placeMines(row, col);this.startTimer();this.firstClick = false;}// 点击到地雷if (this.board[row][col].mine) {this.board[row][col].exploded = true;this.gameOver = true;this.gameOverMessage = '游戏结束!你踩到地雷了!';this.revealAllMines();return;}// 递归揭示空白区域this.revealEmptyCells(row, col);// 检查是否获胜if (this.checkWin()) {this.gameOver = true;this.gameOverMessage = '恭喜你赢了!';}
}
2.2.5 递归揭示空白区域
revealEmptyCells(row, col) {// 边界检查if (row < 0 || row >= this.rows || col < 0 || col >= this.cols || this.board[row][col].revealed || this.board[row][col].flagged) {return;}this.board[row][col].revealed = true;// 如果是空白格子,递归揭示周围的格子if (this.board[row][col].neighborMines === 0) {for (let r = Math.max(0, row - 1); r <= Math.min(this.rows - 1, row + 1); r++) {for (let c = Math.max(0, col - 1); c <= Math.min(this.cols - 1, col + 1); c++) {if (r !== row || c !== col) {this.revealEmptyCells(r, c);}}}}
}

2.3 界面实现

游戏界面主要分为三个部分:

  1. 游戏信息区:显示标题、剩余地雷数和用时

  2. 游戏棋盘:由方格组成的扫雷区域

  3. 控制区:难度选择按钮和游戏结束提示

<view class="game-board"><view v-for="(row, rowIndex) in board" :key="rowIndex" class="row"><view v-for="(cell, colIndex) in row" :key="colIndex" class="cell":class="{'revealed': cell.revealed,'flagged': cell.flagged,'mine': cell.revealed && cell.mine,'exploded': cell.exploded}"@click="revealCell(rowIndex, colIndex)"@longpress="toggleFlag(rowIndex, colIndex)"><!-- 显示格子内容 --><text v-if="cell.revealed && !cell.mine && cell.neighborMines > 0">{{ cell.neighborMines }}</text><text v-else-if="cell.flagged">🚩</text><text v-else-if="cell.revealed && cell.mine">💣</text></view></view>
</view>

三、关键技术与优化点

3.1 性能优化

  1. 延迟布置地雷:只在第一次点击后才布置地雷,确保第一次点击不会踩雷,提升用户体验

  2. 递归算法优化:在揭示空白区域时使用递归算法,但要注意边界条件,避免无限递归

3.2 交互设计

  1. 长按标记:使用@longpress事件实现标记功能,符合移动端操作习惯

  2. 视觉反馈:为不同类型的格子(普通、已揭示、标记、地雷、爆炸)设置不同的样式

3.3 状态管理

  1. 游戏状态:使用gameOvergameOverMessage管理游戏结束状态

  2. 计时器:使用setInterval实现游戏计时功能,注意在组件销毁时清除计时器

四、扩展思路

这个基础实现还可以进一步扩展:

  1. 本地存储:使用uni.setStorage保存最佳成绩

  2. 音效增强:添加点击、标记、爆炸等音效

  3. 动画效果:为格子添加翻转动画,增强视觉效果

  4. 自定义难度:允许玩家自定义棋盘大小和地雷数量

  5. 多平台适配:优化在不同平台(H5、小程序、App)上的显示效果

五、总结

通过本文的介绍,我们完整实现了一个基于Uniapp的扫雷游戏,涵盖了从数据结构设计、核心算法实现到用户交互处理的全部流程。这个项目不仅可以帮助理解Uniapp的开发模式,也是学习游戏逻辑开发的好例子。读者可以根据自己的需求进一步扩展和完善这个游戏。

完整代码

<template><view class="minesweeper-container"><view class="game-header"><text class="title">扫雷游戏</text><view class="game-info"><text>剩余: {{ remainingMines }}</text><text>时间: {{ time }}</text></view></view><view class="game-board"><view v-for="(row, rowIndex) in board" :key="rowIndex" class="row"><view v-for="(cell, colIndex) in row" :key="colIndex" class="cell":class="{'revealed': cell.revealed,'flagged': cell.flagged,'mine': cell.revealed && cell.mine,'exploded': cell.exploded}"@click="revealCell(rowIndex, colIndex)"@longpress="toggleFlag(rowIndex, colIndex)"><text v-if="cell.revealed && !cell.mine && cell.neighborMines > 0">{{ cell.neighborMines }}</text><text v-else-if="cell.flagged">🚩</text><text v-else-if="cell.revealed && cell.mine">💣</text></view></view></view><view class="game-controls"><button @click="startGame(10, 10, 15)">初级 (10×10, 15雷)</button><button @click="startGame(15, 15, 40)">中级 (15×15, 40雷)</button><button @click="startGame(20, 20, 99)">高级 (20×20, 99雷)</button></view><view v-if="gameOver" class="game-over"><text>{{ gameOverMessage }}</text><button @click="startGame(rows, cols, mines)">再玩一次</button></view></view>
</template><script>
export default {data() {return {rows: 10,cols: 10,mines: 15,board: [],remainingMines: 0,time: 0,timer: null,gameOver: false,gameOverMessage: '',firstClick: true}},created() {this.startGame(10, 10, 15);},methods: {startGame(rows, cols, mines) {this.rows = rows;this.cols = cols;this.mines = mines;this.remainingMines = mines;this.time = 0;this.gameOver = false;this.firstClick = true;clearInterval(this.timer);// 初始化棋盘this.board = Array(rows).fill().map(() => Array(cols).fill().map(() => ({mine: false,revealed: false,flagged: false,neighborMines: 0,exploded: false})));},placeMines(firstRow, firstCol) {let minesPlaced = 0;while (minesPlaced < this.mines) {const row = Math.floor(Math.random() * this.rows);const col = Math.floor(Math.random() * this.cols);// 确保第一次点击的位置和周围没有地雷if (!this.board[row][col].mine && Math.abs(row - firstRow) > 1 && Math.abs(col - firstCol) > 1) {this.board[row][col].mine = true;minesPlaced++;}}// 计算每个格子周围的地雷数for (let row = 0; row < this.rows; row++) {for (let col = 0; col < this.cols; col++) {if (!this.board[row][col].mine) {let count = 0;for (let r = Math.max(0, row - 1); r <= Math.min(this.rows - 1, row + 1); r++) {for (let c = Math.max(0, col - 1); c <= Math.min(this.cols - 1, col + 1); c++) {if (this.board[r][c].mine) count++;}}this.board[row][col].neighborMines = count;}}}},revealCell(row, col) {if (this.gameOver || this.board[row][col].revealed || this.board[row][col].flagged) {return;}// 第一次点击时放置地雷并开始计时if (this.firstClick) {this.placeMines(row, col);this.startTimer();this.firstClick = false;}// 点击到地雷if (this.board[row][col].mine) {this.board[row][col].exploded = true;this.gameOver = true;this.gameOverMessage = '游戏结束!你踩到地雷了!';this.revealAllMines();clearInterval(this.timer);return;}// 递归揭示空白区域this.revealEmptyCells(row, col);// 检查是否获胜if (this.checkWin()) {this.gameOver = true;this.gameOverMessage = '恭喜你赢了!';clearInterval(this.timer);}},revealEmptyCells(row, col) {if (row < 0 || row >= this.rows || col < 0 || col >= this.cols || this.board[row][col].revealed || this.board[row][col].flagged) {return;}this.board[row][col].revealed = true;if (this.board[row][col].neighborMines === 0) {// 如果是空白格子,递归揭示周围的格子for (let r = Math.max(0, row - 1); r <= Math.min(this.rows - 1, row + 1); r++) {for (let c = Math.max(0, col - 1); c <= Math.min(this.cols - 1, col + 1); c++) {if (r !== row || c !== col) {this.revealEmptyCells(r, c);}}}}},toggleFlag(row, col) {if (this.gameOver || this.board[row][col].revealed) {return;}if (this.board[row][col].flagged) {this.board[row][col].flagged = false;this.remainingMines++;} else if (this.remainingMines > 0) {this.board[row][col].flagged = true;this.remainingMines--;}},startTimer() {clearInterval(this.timer);this.timer = setInterval(() => {this.time++;}, 1000);},revealAllMines() {for (let row = 0; row < this.rows; row++) {for (let col = 0; col < this.cols; col++) {if (this.board[row][col].mine) {this.board[row][col].revealed = true;}}}},checkWin() {for (let row = 0; row < this.rows; row++) {for (let col = 0; col < this.cols; col++) {if (!this.board[row][col].mine && !this.board[row][col].revealed) {return false;}}}return true;}},beforeDestroy() {clearInterval(this.timer);}
}
</script><style>
.minesweeper-container {padding: 20px;display: flex;flex-direction: column;align-items: center;
}.game-header {margin-bottom: 20px;text-align: center;
}.game-header .title {font-size: 24px;font-weight: bold;margin-bottom: 10px;
}.game-info {display: flex;justify-content: space-around;width: 100%;
}.game-board {border: 2px solid #333;margin-bottom: 20px;
}.row {display: flex;
}.cell {width: 30px;height: 30px;border: 1px solid #ccc;display: flex;justify-content: center;align-items: center;background-color: #ddd;font-weight: bold;
}.cell.revealed {background-color: #fff;
}.cell.flagged {background-color: #ffeb3b;
}.cell.mine {background-color: #f44336;
}.cell.exploded {background-color: #d32f2f;
}.game-controls {display: flex;flex-direction: column;gap: 10px;width: 100%;max-width: 300px;
}.game-over {margin-top: 20px;text-align: center;font-size: 18px;font-weight: bold;
}button {margin-top: 10px;padding: 10px;background-color: #4CAF50;color: white;border: none;border-radius: 5px;cursor: pointer;
}button:active {background-color: #3e8e41;
}
</style>

 

相关文章:

用Deepseek写扫雷uniapp小游戏

扫雷作为Windows系统自带的经典小游戏&#xff0c;承载了许多人的童年回忆。本文将详细介绍如何使用Uniapp框架从零开始实现一个完整的扫雷游戏&#xff0c;包含核心算法、交互设计和状态管理。无论你是Uniapp初学者还是有一定经验的开发者&#xff0c;都能从本文中获得启发。 …...

宝塔面板部署 Laravel 项目无法访问静态资源的解决方法

提示:“奔跑吧邓邓子” 的常见问题专栏聚焦于各类技术领域常见问题的解答。涵盖操作系统(如 CentOS、Linux 等)、开发工具(如 Android Studio)、服务器软件(如 Zabbix、JumpServer、RocketMQ 等)以及远程桌面、代码克隆等多种场景。针对如远程桌面无法复制粘贴、Kuberne…...

C/C++中的条件编译指令#if

#if 是 C/C 中的预处理指令&#xff0c;用于条件编译。它允许根据预定义的条件来决定是否编译某段代码。#if 通常与 #define、#ifdef、#ifndef、#else 和 #endif 等指令一起使用。 基本语法 #if 条件表达式// 如果条件表达式为真&#xff0c;编译这部分代码 #else// 如果条件…...

【设计模式】策略模式(Strategy Pattern)详解

策略模式&#xff08;Strategy Pattern&#xff09;详解 一、策略模式的定义 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一组算法&#xff0c;将每个算法封装起来&#xff0c;并使它们可以相互替换&#xff0c;从而让算法的…...

Eclipse IDE for ModusToolbox™ 3.4环境通过JLINK调试CYT4BB

使用JLINK在Eclipse IDE for ModusToolbox™ 3.4环境下调试CYT4BB&#xff0c;配置是难点。总结一下在IDE中配置JLINK调试中遇到的坑&#xff0c;以及如何一步一步解决遇到的问题。 1. JFLASH能够正常下载程序 首先要保证通过JFLASH(我使用的J-Flash V7.88c版本)能够通过JLIN…...

修改git在提交代码时的名称

在git中&#xff0c;如果想修改提交代码作者的名字&#xff0c;可以进行以下操作&#xff1a; 1.在桌面或者文件夹内右击鼠标&#xff0c;点开Git Bash here。 2.进入后&#xff0c;通过git config user.name 回车查看当前名称。 3.通过git config --global user.name "…...

前端显示no data(没有数据,一片空白)

◎浏览器查看显示 message: "Request failed with status code 404", name: "AxiosError", code: "ERR_BAD_REQUEST" ◎后端gateway 模块显示: 无需验证&#xff0c;通行。/business/admin/save 显示正确的路径&#xff0c;但是没有返回结果…...

CCF编程能力等级认证GESP—C++7级—20250322

CCF编程能力等级认证GESP—C7级—20250322 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)图上移动等价消除 单选题&#xff08;每题 2 分&#xff0c;共 …...

【Linux】深入解析Linux命名管道(FIFO):原理、实现与实战应用

本文承接上文匿名管道&#xff1a;【Linux】深度解析Linux进程间通信&#xff1a;匿名管道原理、实战与高频问题排查-CSDN博客 深入探讨Linux进程间通信&#xff08;IPC&#xff09;&#xff0c;以匿名管道为核心&#xff0c;详细阐述其通信目的、实现前提及机制。涵盖数据传输…...

第十四届蓝桥杯省赛电子类单片机学习记录(客观题)

01.一个8位的DAC转换器&#xff0c;供电电压为3.3V&#xff0c;参考电压2.4V&#xff0c;其ILSB产生的输出电压增量是&#xff08;D&#xff09;V。 A. 0.0129 B. 0.0047 C. 0.0064 D. 0.0094 解析&#xff1a; ILSB&#xff08;最低有效位&#xff09;的电压增量计算公式…...

Python高效编程技巧与AI专用库:NumPy/Pandas数据处理与Matplotlib/Seaborn可视化实战

Python高效编程技巧与AI专用库&#xff1a;NumPy/Pandas数据处理与Matplotlib/Seaborn可视化实战 引言&#xff1a;Python高效AI开发的核心技能栈 在AI项目中&#xff0c;数据处理和可视化占据了70%以上的工作量。低效的代码会导致模型训练缓慢&#xff0c;而糟糕的数据可视化…...

vim的一般操作(分屏操作) 和 Makefile 和 gdb

目录 一. vim的基本概念 二. vim基础操作 2.1 插入模式 aio 2.2 [插入模式]切换至[正常模式] Esc 2.3[正常模式]切换至[末行模式] shift ; 2.4 替换模式 Shift R 2.5 视图&#xff08;可视&#xff09;模式 (可以快速 删除//注释 或者 增加//注释) ctrl v 三&…...

生成器的应用 async与await实现

生成器配合使用函数 yield 将暂停执行代码,同时把函数返回值传递出去 function s(){console.log(ss); } function * f(){/*当 next() 调用时从头开始执行直到yield 开始检查后面的表达式现在是一个函数,那么首先执行函数当函数执行完毕,有返回值下面相当于 yield undefined*/…...

Apache Shiro 统一化实现多端登录(PC端移动端)

Apache Shiro 是一个强大且易用的Java安全框架&#xff0c;提供了身份验证、授权、密码学和会话管理等功能。它被广泛用于保护各种类型的应用程序&#xff0c;包括Web应用、桌面应用、RESTful服务、移动端应用和大型企业级应用。 需求背景 在当今数字化浪潮的推动下&#xff…...

NAT—地址转换(实战篇)

一、实验拓扑&#xff1a; 二、实验需求&#xff1a; 1.实现内网主机访问外网 2.实现外网客户端能够访问内网服务器 三、实验思路 1.配置NAT地址池实现内网地址转换成公网地址&#xff0c;实现内网主机能够访问外网。 2.配置NAT Sever实现公网地址映射内网服务器地址&…...

用HTML和CSS生成炫光动画卡片

这个效果结合了渐变、旋转和悬浮效果的炫酷动画示例&#xff0c;使用HTML和CSS实现。 一、效果 二、实现 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&quo…...

Vue 3 + Composition API + Vite + Pinia + Element Plus 构建项目的完整指南

以下是使用 Vue 3 + Composition API + Vite + Pinia + Element Plus 构建项目的完整指南,包含 TypeScript 支持配置: 1. 创建项目 使用 Vite 初始化项目 npm create vite@latest my-vue-app -- --template vue-ts如果不需要 TypeScript,使用 --template vue 进入项目目录…...

FPGA_YOLO(三)

上一篇讲的是完全映射&#xff0c;也就是block中的所包含的所有的卷积以及归一&#xff0c;池化卷积 举例总共6个等都在pl侧进行处理&#xff08;写一个top 顶层 里面conv 1 bn1 relu1 pool1 conv1*1 conv 2 bn2 relu2 pool2 conv1*1 ....总共6个 &#xff09;&#xff0c;…...

使用 SQL CTE(公共表表达式)优化数据查询的实践

目录 一、背景 二、什么是 CTE&#xff1f; 三、CTE 的基本结构 四、示例分析 五、CTE 的作用 六、优势分析 一、背景 在数据分析和数据库管理中&#xff0c;SQL 查询的效率和可读性是至关重要的。随着数据量的不断增加&#xff0c;复杂的查询变得越来越难以管理和理解。…...

旅游CMS选型:WordPress、Joomla与Drupal对比

内容概要 在旅游行业数字化转型进程中&#xff0c;内容管理系统&#xff08;CMS&#xff09;的选择直接影响网站运营效率与用户体验。WordPress、Joomla和Drupal作为全球主流的开源CMS平台&#xff0c;其功能特性与行业适配性存在显著差异。本文将从旅游企业核心需求出发&…...

全面适配iOS 18.4!通付盾加固产品全面升级,护航App安全上架

引言&#xff1a; 苹果官方新规落地&#xff01; 自2025年4月24日起&#xff0c;所有提交至App Store Connect的应用必须使用Xcode 16或更高版本构建&#xff0c;否则将面临审核驳回风险&#xff01;Beta版iOS 18.4、iPadOS 18.4现已推出&#xff0c;通付盾iOS加固产品率先完成…...

bash 和 pip 是两种完全不同用途的命令,分别用于[系统终端操作]和[Python 包管理]

bash 和 pip 是两种完全不同用途的命令&#xff0c;分别用于 系统终端操作 和 Python 包管理。以下是它们的核心区别、用法及常见场景对比&#xff1a; 1. 本质区别 特性bashpip类型Shell 命令解释器&#xff08;一种脚本语言&#xff09;Python 包管理工具作用执行系统命令、…...

SQL 通用表表达式(CTE )

目录 概念&#xff1a;CTE&#xff1a; Common table Expression CTE 语法 CTE Demo 概念&#xff1a;CTE&#xff1a; Common table Expression 通用表表达式&#xff08;CTE&#xff09;是SQL中用于简化复杂查询的工具&#xff0c;第一次上线于SQL Server 2005。 CTE提供…...

一台电脑最多能接几个硬盘?

在使用电脑时&#xff0c;硬盘空间不够是许多用户都会遇到的问题。无论是摄影师、剪辑师等需要大量存储空间的专业人士&#xff0c;还是游戏玩家、数据备份爱好者&#xff0c;都可能希望通过增加硬盘来扩展存储容量。然而&#xff0c;一台电脑究竟最多能接多少个硬盘&#xff1…...

MATLAB中iscell函数用法

目录 语法 说明 示例 确定数组是否为元胞数组 iscell函数的功能是确定输入是否为元胞数组。 语法 tf iscell(A) 说明 如果 A 是元胞数组&#xff0c;则 tf iscell(A) 返回 1 (true)。否则&#xff0c;将返回 0 (false)。 示例 确定数组是否为元胞数组 创建一个元胞数…...

【玩转全栈】---- Django 基于 Websocket 实现群聊(解决channel连接不了)

学习视频&#xff1a; 14-11 群聊&#xff08;一&#xff09;_哔哩哔哩_bilibili 目录 Websocket 连接不了&#xff1f; 收发数据 断开连接 完整代码 聊天室的实现 聊天室一 聊天室二 settings 配置 consumer 配置 多聊天室 Websocket 连接不了&#xff1f; 基于这篇博客&…...

如何快速解决django报错:cx_Oracle.DatabaseError: ORA-00942: table or view does not exist

我们在使用django连接oracle进行编程时&#xff0c;使用model进行表映射对接oracle数据时&#xff0c;默认表名组成结构为&#xff1a;应用名_类名&#xff08;如&#xff1a;OracleModel_test&#xff09;&#xff0c;故即使我们库中存在表test&#xff0c;运行查询时候&#…...

Selenium之简介

Selenium简介 首先&#xff0c;让我们看看官网是怎么定义的 Selenium是一个支持web浏览器自动化的一系列工具和库的综合项目&#xff0c;提供了扩展来模拟用户和浏览器的交互&#xff0c;用于扩展浏览器分配的分发服务器&#xff1b;用于W3C WebDriver规范的基础架构 其实&a…...

pip 安装某个包之后,Jupyter Lab仍旧显示包冲突;例如:Numba needs NumPy 2.1 or less. Got NumPy 2.2.

异常提示 Numba needs NumPy 2.1 or less. Got NumPy 2.2. --------------------------------------------------------------------------- ImportError Traceback (most recent call last) Cell In[8], line 53 import pywt4 import matplot…...

本地安装git

下载git 通过官网 下载 &#xff1a;Git - Downloading Package 若此页面无法直达&#xff0c;请删掉download/win尝试 2.双击运行安装 选择安装目录&#xff1a; 选择配置&#xff0c;默认不动 git安装目录名 默认即可 Git 的默认编辑器&#xff0c;建议使用默认的 Vim 编辑器…...