勇士传说横版卷轴游戏:C#动作游戏源码解析与毕业设计实战
简介这份资源是基于C#开发的「勇士传说」横版卷轴游戏完整源码面向计算机相关专业做毕业设计的学生以及希望入门Unity 2D游戏开发的学习者。项目以经典横版卷轴玩法为核心涵盖角色动画、碰撞检测、地图设计、敌人AI与用户输入处理等模块可作为课程设计或自学练手的实战参考。压缩包共2023个文件约35.45MB以meta、asset资源文件为主配合wav音效、anim动画、cs脚本、prefab预制体、unity场景及controller动画控制器等完整呈现一个可运行的游戏工程结构。目前已有151人学习下载。通过研读源码读者可以理解C#与Unity结合组织游戏项目的目录结构掌握场景管理、游戏对象、图形渲染、音效管理等模块的实现思路并在此基础上自由修改扩展形成自己的作品。1. 勇士传说横版卷轴游戏一份能跑起来的 C# 动作游戏源码如果你正在找一份能直接跑、能改、能写进毕业设计里的横版动作游戏源码这份基于 C# 开发的「勇士传说」项目值得花时间拆一遍。它不是那种只有几行 Demo 的玩具工程而是把角色动画、碰撞检测、敌人 AI、场景切换、音效管理这些横版卷轴游戏的核心模块都串了起来。从文件列表里能看到blueHurt.anim、beeAttack.anim、BoarDead.anim这类动画资源说明角色状态机已经细化到受击、攻击、死亡等具体帧。适合谁一是拿它当毕业设计底稿的开发者二是想从零理解 2D 动作游戏架构的 C# 学习者。下面按「能干什么 → 怎么跑 → 怎么改」的顺序把这份源码拆开讲。2. 项目定位与技术选型为什么是 C# 加 Unity 做横版卷轴2.1 横版卷轴游戏的核心技术需求横版卷轴游戏看起来简单实际上对帧同步、碰撞精度、动画状态切换的要求并不低。玩家控制角色在横向滚动的场景中移动摄像机跟随、敌人巡逻、攻击判定、受击反馈这些环节任何一个出问题都会让手感变得「玄学」。这份源码选择 C# 作为主语言配合 Unity 引擎的 2D 工具链本质上是用一套成熟的组件系统来降低这些模块的耦合度。从动画文件命名能看出设计思路blueWalk.anim负责移动循环blueAttack1/2/3.anim拆成三段连击blueHurt.anim和blueHurt2.anim区分不同受击方向blueDead.anim处理死亡过渡。这种拆分方式意味着角色状态机不是简单的 if-else而是基于动画状态的有向图。对于毕业设计来说这种细粒度拆分既能体现工作量也方便在论文里画状态转移图。2.2 源码包里的模块划分虽然压缩包只给了一个code文件夹但按 C# 游戏项目的常见组织方式里面大概率会包含以下几类脚本。我按实际拆包经验列一下方便你拿到源码后快速定位模块常见文件名职责场景管理GameScene.cs / SceneLoader.cs加载、切换关卡管理场景生命周期玩家控制Player.cs / PlayerController.cs输入响应、移动、跳跃、攻击触发敌人逻辑Enemy.cs / BoarAI.cs / BeeAI.cs巡逻、追击、攻击、死亡动画控制AnimatorManager.cs / SpriteSheet.cs动画状态切换、帧事件碰撞检测CollisionHandler.cs / HitBox.cs攻击判定、受击区域、地形碰撞输入管理InputManager.cs键盘映射、输入缓冲游戏流程GameManager.cs分数、生命、关卡进度音频管理AudioManager.cs音效播放、背景音乐切换资源管理ResourceManager.cs精灵图、动画、预制体加载提示不同开发者对文件名习惯不同拿到源码后先看GameManager.cs和Player.cs这两个文件通常能串起整个项目的调用链。2.3 为什么这类项目适合做毕业设计底稿毕业设计最怕两件事一是工作量不够二是代码太乱没法讲清楚。这份源码的动画资源命名已经暴露了它的模块化程度——每个角色状态都有独立动画文件说明开发者至少做到了「一个状态一个处理」。你在论文里可以围绕状态机、碰撞检测、AI 行为树这三个点展开每个点都能对应到具体代码和动画资源。而且横版卷轴游戏的视觉反馈直观答辩时演示效果好比纯后台系统更容易让评委看懂你做了什么。3. 跑起来之前环境配置与工程导入的完整步骤3.1 Unity 版本选择与项目打开这份源码基于 C# 和 Unity但输入里没有写具体版本号。按横版 2D 项目的常见做法我一般会优先用 Unity 2021 LTS 或 2022 LTS 打开这两个版本对 2D 工具链的支持比较稳定Animation 窗口和 Sprite Editor 的交互也成熟。如果你用的是更新版本打开时可能会提示 API 升级先备份再点确认。操作步骤安装 Unity Hub在 Hub 里安装一个 LTS 版本勾选「2D」模块。把code文件夹整个拷贝到一个不含中文和空格的路径下比如D:\Projects\WarriorLegend。打开 Unity Hub点「Add」→ 选择code文件夹所在的目录。等待 Unity 首次导入资源动画文件.anim会自动关联到 Animator Controller。注意路径里不要有中文否则 Unity 导入.anim文件时可能报「Could not find file」错误这是血泪经验。3.2 场景文件与初始入口Unity 项目启动后在 Project 窗口里找Scenes文件夹双击里面的主场景文件常见命名是Main.unity或Level1.unity。如果找不到 Scenes 文件夹就在 Project 窗口搜索栏输入t:Scene把所有场景文件列出来。通常第一个关卡就是入口场景。打开场景后检查 Hierarchy 窗口里有没有GameManager、Player、Main Camera这三个对象。如果GameManager缺失游戏逻辑不会启动如果Player缺失场景里就没有可控角色。这两个对象是横版卷轴游戏的骨架。3.3 输入系统与按键映射Unity 默认的 Input Manager 在Edit → Project Settings → Input Manager里配置。横版动作游戏常见映射是左右移动A / D 或方向键左右跳跃Space攻击J 或鼠标左键暂停Esc如果源码用的是新 Input System 包你需要在 Package Manager 里确认Input System已安装并在 Project Settings 里把「Active Input Handling」设为「Both」或「Input System Package」。这一步翻车的话运行后角色完全没反应但控制台不一定报错排查起来很费时间。3.4 运行与常见启动报错点 Play 按钮后如果角色能移动、动画能播放说明环境没问题。如果遇到以下情况按对应方式处理角色掉出地图检查Player对象的 Rigidbody2D 和 Collider2D 是否挂载地形有没有 Collider。动画不播放检查 Animator 组件里的 Controller 是否赋值动画状态机里有没有默认状态。敌人不动检查敌人脚本里的目标对象是否为空或者巡逻范围参数是否为 0。音效不响检查 AudioManager 的 AudioSource 是否挂载音量参数是否被设为 0。4. 核心模块拆解从动画状态机到碰撞检测的代码实现4.1 角色动画状态机与 Animator 参数横版动作游戏的手感一半靠动画状态机。从blueWalk.anim、blueAttack1.anim、blueHurt.anim这些文件能看出开发者把角色状态拆得很细。在 Unity 的 Animator 窗口里这些动画会通过参数Parameter来切换。常见参数类型有float speed控制从 Idle 到 Walk 的过渡bool isGrounded判断是否在地面trigger attack触发攻击动画trigger hurt触发受击动画bool isDead切换到死亡状态代码里通常这样驱动// Player.cs 片段驱动动画状态机 public class Player : MonoBehaviour { private Animator anim; private Rigidbody2D rb; private float moveInput; void Start() { anim GetComponentAnimator(); rb GetComponentRigidbody2D(); } void Update() { // 获取水平输入A/D 或左右方向键 moveInput Input.GetAxisRaw(Horizontal); // 把速度绝对值传给 Animator用于 Idle/Walk 切换 anim.SetFloat(speed, Mathf.Abs(moveInput)); // 按 J 触发攻击动画 if (Input.GetKeyDown(KeyCode.J)) { anim.SetTrigger(attack); } } void FixedUpdate() { // 物理移动放在 FixedUpdate 里保证帧率无关 rb.velocity new Vector2(moveInput * 5f, rb.velocity.y); } }这段代码的逻辑很直白Update里读输入、设动画参数FixedUpdate里做物理移动。参数说明moveInput是 -1 到 1 的浮点数speed参数在 Animator 里用来判断是否播放走路动画attack触发器每次按下只触发一次。常见坑是把移动写在Update里导致不同帧率下速度不一致横版游戏里会感觉「滑步」。4.2 碰撞检测与攻击判定横版动作游戏的碰撞分两类地形碰撞和攻击判定。地形碰撞用 Rigidbody2D BoxCollider2D 就能解决攻击判定通常用 OverlapCircle 或 Trigger 来实现。源码里如果有CollisionHandler.cs或HitBox.cs大概率是这种写法// HitBox.cs 片段攻击范围检测 public class HitBox : MonoBehaviour { public int damage 1; // 攻击伤害值 public float radius 0.5f; // 检测半径 public LayerMask enemyLayer; // 敌人所在层 // 由动画事件调用在攻击帧触发 public void OnAttackFrame() { // 在当前位置画一个圆检测所有敌人层碰撞体 Collider2D[] hits Physics2D.OverlapCircleAll( transform.position, radius, enemyLayer); foreach (var hit in hits) { // 尝试获取敌人脚本并扣血 Enemy enemy hit.GetComponentEnemy(); if (enemy ! null) { enemy.TakeDamage(damage); } } } }逻辑说明OnAttackFrame不放在Update里而是通过动画事件Animation Event在攻击动画的特定帧调用这样判定时机和视觉表现对齐。参数说明damage是每次攻击扣血量radius决定攻击范围enemyLayer用来过滤只检测敌人。常见翻车点是把OverlapCircleAll放在Update里每帧调用导致一次攻击扣多次血敌人瞬间死亡。4.3 敌人 AI 与状态切换敌人 AI 通常分巡逻、追击、攻击、死亡四个状态。从beeAttack.anim、BoarDead.anim这些文件看不同敌人有独立动画但状态机逻辑可以复用。常见做法是用枚举加 switch 来管理// Enemy.cs 片段简单状态机 public enum EnemyState { Patrol, Chase, Attack, Dead } public class Enemy : MonoBehaviour { public EnemyState currentState EnemyState.Patrol; public Transform player; // 玩家位置 public float patrolRange 3f; // 巡逻半径 public float chaseRange 5f; // 追击半径 public float attackRange 1f; // 攻击距离 public int health 3; void Update() { if (currentState EnemyState.Dead) return; float distance Vector2.Distance(transform.position, player.position); // 根据距离切换状态 if (distance attackRange) currentState EnemyState.Attack; else if (distance chaseRange) currentState EnemyState.Chase; else currentState EnemyState.Patrol; // 执行当前状态行为 switch (currentState) { case EnemyState.Patrol: Patrol(); break; case EnemyState.Chase: Chase(); break; case EnemyState.Attack: Attack(); break; } } public void TakeDamage(int damage) { health - damage; if (health 0) { currentState EnemyState.Dead; // 播放死亡动画延迟销毁 GetComponentAnimator().SetTrigger(dead); Destroy(gameObject, 1f); } } }这段代码把 AI 拆成距离判断加行为执行两步。参数说明patrolRange控制巡逻范围chaseRange决定何时追击attackRange决定何时攻击。常见问题是敌人追击时直接瞬移到玩家位置解决方法是给移动加插值或速度限制不要直接赋值transform.position。4.4 场景管理与游戏流程控制GameManager.cs通常是单例负责分数、生命、关卡切换。横版卷轴游戏的关卡切换一般用SceneManager.LoadScene但要注意在切换前保存玩家状态。常见写法// GameManager.cs 片段单例与关卡切换 public class GameManager : MonoBehaviour { public static GameManager Instance; // 单例引用 public int playerLives 3; public int score 0; void Awake() { // 保证场景里只有一个 GameManager if (Instance null) { Instance this; DontDestroyOnLoad(gameObject); // 切换场景不销毁 } else { Destroy(gameObject); } } public void LoadNextLevel(string levelName) { // 切换前可以保存分数、生命等数据 SceneManager.LoadScene(levelName); } public void PlayerDied() { playerLives--; if (playerLives 0) { // 游戏结束逻辑 LoadNextLevel(GameOver); } else { // 重生逻辑 LoadNextLevel(SceneManager.GetActiveScene().name); } } }逻辑说明DontDestroyOnLoad让 GameManager 跨场景保留分数和生命不会因为切场景重置。参数说明playerLives是剩余生命score是当前分数。常见坑是忘记在Awake里做单例判重导致切回主菜单再进游戏时出现两个 GameManager分数翻倍。5. 避坑与排查跑这份源码时最容易翻车的 5 个地方5.1 动画文件导入后丢失引用现象打开场景后角色不动Animator 窗口里动画状态是空的Console 报「Missing Animation Clip」。原因.anim文件在拷贝过程中丢失了.meta文件或者 Unity 版本差异导致 GUID 不匹配。解决在 Project 窗口右键Reimport All如果还不行手动把.anim文件拖到 Animator 窗口对应状态上重新关联。以后拷贝 Unity 项目时一定要连.meta文件一起拷。5.2 角色移动但动画不切换现象按 A/D 角色能左右移动但一直播放 Idle 动画走路动画不触发。原因Animator 里的speed参数没有和代码里的anim.SetFloat(speed, ...)对应或者过渡条件设置成了Greater但阈值太高。解决打开 Animator 窗口点 Parameters 标签确认speed参数存在且类型是 Float。然后检查 Idle 到 Walk 的过渡条件把阈值调到 0.1 左右。代码里打印一下Mathf.Abs(moveInput)的值确认不是 0。5.3 攻击判定一次扣多血现象按一次攻击键敌人血条直接清空或者播放一次攻击动画但敌人受到多次伤害。原因攻击判定写在了Update里每帧都调用OverlapCircleAll而攻击动画持续多帧。解决把攻击判定绑定到动画事件上在攻击动画的特定帧调用一次。或者加一个bool isAttacking标志位攻击期间不重复触发。代码里可以用anim.SetTrigger配合Animation Event来精确控制。5.4 敌人死亡后仍然能攻击玩家现象敌人血量归零、死亡动画播放了但玩家靠近时仍然掉血。原因死亡状态只切换了动画没有禁用碰撞体或停止 AI 逻辑。解决在TakeDamage里把敌人的 Collider2D 设为enabled false或者把敌人 Layer 改成「Dead」层让玩家的攻击判定不再检测到它。同时把currentState设为Dead在Update开头直接return。5.5 切换场景后背景音乐重叠现象从第一关进第二关两首背景音乐同时播放或者音效突然消失。原因AudioManager 没有做跨场景单例每个场景都实例化了一个 AudioSource。解决和 GameManager 一样在Awake里做单例判重用DontDestroyOnLoad保留唯一的 AudioManager。切换场景时先Stop当前音乐再播放新场景的 BGM。如果音效丢失检查 AudioSource 的spatialBlend参数2D 音效应设为 0。6. 二次开发与改造把这份源码变成你自己的毕业设计拿到源码后最忌讳的是直接改数值、换贴图就交差。答辩时评委一问「你做了什么」答不上来就很被动。我的习惯是先从三个方向做增量改造每个方向都能在论文里独立成章。第一个方向是扩展敌人 AI。源码里已经有beeAttack.anim和BoarDead.anim说明至少有两种敌人。你可以加一种远程敌人用Physics2D.Raycast做视线检测玩家进入视野后发射投射物。投射物用 Prefab 加 Rigidbody2D 实现碰到玩家或地形后销毁。这个改动涉及 AI 状态机扩展、新动画状态、碰撞层配置工作量足够写一节。第二个方向是加技能系统。横版动作游戏没有技能会显得单薄。你可以在Player.cs里加一个技能冷却字典用Time.time做计时。比如按 K 键释放范围攻击调用OverlapCircleAll检测周围敌人播放一个独立的技能动画。技能冷却用 UI 显示需要和 Canvas 交互。这个改动能体现你对游戏循环和 UI 事件的理解。第三个方向是存档与关卡进度。用PlayerPrefs或 JSON 序列化保存当前关卡、分数、生命值。在GameManager里加SaveGame和LoadGame方法主菜单加「继续游戏」按钮。这个改动不复杂但能体现工程完整性答辩时也容易演示。改造时注意一个原则每次只改一个模块改完立刻运行验证。我见过太多人一次性改五六个文件结果报错后不知道是哪个改动引起的。从那以后我每次动核心脚本前都强制走一遍「备份 → 改一个文件 → 运行 → 提交」的流程。希望这份拆解能帮你把这份源码真正跑起来、改下去。本文还有配套的精品资源点击获取

相关新闻

零基础参与开源Python项目:从Fork到首个PR的完整实战指南

零基础参与开源Python项目:从Fork到首个PR的完整实战指南

1. 先搞清楚开源贡献这件事,远不止写代码很多刚接触开源Python项目的人,以为“做贡献”就等于“提PR改源码”。我最初也是这样想的,甚至一度觉得,自己没写出过有设计感的代码,就不配去动别人的仓库。直到后来真正参与进…

2026/10/18 10:35:45 阅读更多 →
基于阈值分割的全色影像水体自动提取与MATLAB实现

基于阈值分割的全色影像水体自动提取与MATLAB实现

简介:面向遥感与图像处理初学者,该专题提取资料聚焦全色影像中的水体识别,演示了以阈值分割为核心从单波段影像到二值水体图的完整流程:先通过大津法等方法自动选取阈值区分水体与非水体,再结合后处理优化提取边缘。压…

2026/10/18 10:35:45 阅读更多 →
Pacman搜索算法解析:从DFS到A*的状态空间与启发式设计

Pacman搜索算法解析:从DFS到A*的状态空间与启发式设计

简介:这是一份基于伯克利大学AI Pacman项目的搜索算法解决方案,面向正在学习人工智能、搜索策略与Python编程的开发者。资源围绕吃豆人游戏中的智能决策,完整覆盖广度优先搜索、深度优先搜索、A星搜索、Dijkstra算法,并延伸至最小…

2026/10/18 10:35:45 阅读更多 →

最新新闻

5GHz DFS机制深度解析:从CAC到NOP的完整避让流程

5GHz DFS机制深度解析:从CAC到NOP的完整避让流程

如果你调过 AP 的 5GHz 信道,大概率遇到过这种诡异场面:配置明明没问题,但把信道设成 52 或 100 之后,AP 就是死活不起来,日志里反复刷 “DFS: waiting for radar detection”,有时候等了一分钟总算起来了&…

2026/10/18 11:18:02 阅读更多 →
Nexus 3.24.0-02 内网仓库搭建与 Maven/NPM 代理配置实战

Nexus 3.24.0-02 内网仓库搭建与 Maven/NPM 代理配置实战

简介:Nexus Repository Manager 3.24.0-02 的 Unix/Linux 官方安装包,面向 Java 与前端开发团队中负责制品仓库搭建、依赖治理的运维及中高级开发者。它解决 Maven、NPM 等组件分散存储、重复下载与私有包托管难题,可作为内网统一仓库代理与分…

2026/10/18 11:18:02 阅读更多 →
PyTorch迭代训练进阶:从训练循环到稳定收敛的完整指南

PyTorch迭代训练进阶:从训练循环到稳定收敛的完整指南

最近在整理之前做过的某个图像分类项目时,发现一个挺有意思的现象:同样一批代码、同样的数据增强策略、同样的优化器配置,只是把训练主循环里的几个细节调整了一下,最终模型的收敛速度和泛化性能差别竟然能到三到五个点。这也是我…

2026/10/18 11:18:02 阅读更多 →
AI赛事直播实战:从目标检测到自动剪辑,打造精彩瞬间捕捉系统

AI赛事直播实战:从目标检测到自动剪辑,打造精彩瞬间捕捉系统

“AI 尚运动”,看到这个标题,我先讲个真实发生在转播间的事:去年一场地方台直播的篮球赛,最后30秒的绝杀,导播手一抖切错了机位,球进框的画面直接没了。赛后我们扒了三个机位的原始录像,才把那个…

2026/10/18 11:18:02 阅读更多 →
数组从入门到精通:定义、遍历、查找、排序与边界避坑指南

数组从入门到精通:定义、遍历、查找、排序与边界避坑指南

说实话,数组是编程里最不起眼的东西,但我在带新人、看代码审查时发现,很多人写了几个月甚至一年的代码,数组依然停留在"会用"的水平,一碰到边界就翻车,排序和查找只会调库函数,连手写…

2026/10/18 11:18:02 阅读更多 →
XMLViewer:高效处理大文件XML的树形查看与搜索工具

XMLViewer:高效处理大文件XML的树形查看与搜索工具

简介:XMLViewer 是一款面向开发人员与运维人员的专业 XML 查看工具,主要解决日常排查 XML 文件语法是否正确、结构是否清晰的问题。安装完成后,只需右键点击 XML 文件并选择“View”,即可快速打开查看,省去手动配置编辑…

2026/10/18 11:17:01 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →