From ff575d6798f488f4248132af013ff92f06ef61d7 Mon Sep 17 00:00:00 2001 From: cc Date: Tue, 23 Jun 2026 20:37:38 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=94=B9=E7=94=A8=20xlsx=20=E4=BD=9C?= =?UTF-8?q?=E4=B8=BA=E4=BB=BB=E5=8A=A1=E6=B8=85=E5=8D=95=EF=BC=8C=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=20csv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除 引擎学习开发计划.csv - 更新为最新的 引擎学习开发计划.xlsx - README 与计划文档中的引用同步改为 xlsx Co-Authored-By: Claude Opus 4.8 --- README.md | 2 +- 引擎学习开发计划.csv | 37 ---------------------------------- 引擎学习开发计划.md | 2 +- 引擎学习开发计划.xlsx | Bin 15159 -> 10289 bytes 4 files changed, 2 insertions(+), 39 deletions(-) delete mode 100644 引擎学习开发计划.csv diff --git a/README.md b/README.md index cd3c021..51735d7 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ 之后会用它做一款小游戏。完整路线见: - 📖 [引擎学习开发计划.md](引擎学习开发计划.md) —— 详细的分阶段学习与开发计划 -- 📊 [引擎学习开发计划.csv](引擎学习开发计划.csv) —— 任务清单(可当进度看板) +- 📊 [引擎学习开发计划.xlsx](引擎学习开发计划.xlsx) —— 任务清单(可当进度看板) ## 项目结构 diff --git a/引擎学习开发计划.csv b/引擎学习开发计划.csv deleted file mode 100644 index 8bdbe25..0000000 --- a/引擎学习开发计划.csv +++ /dev/null @@ -1,37 +0,0 @@ -阶段,序号,任务/知识点,类型,是否有教程,推荐教程(中文优先),链接,产出/备注 -阶段0 地基,0.1,Rust语言入门(所有权/借用/trait/泛型/错误处理),语言,✅有中文教程,Rust程序设计语言中文版 / Rust语言圣经,https://kaisery.github.io/trpl-zh-cn/ ; https://course.rs/,能独立写带结构体枚举trait的小程序 -阶段0 地基,0.2,数据结构与基本算法,理论,✅/🔧,Rust语言圣经"手把手实现链表"+通用数据结构课,https://course.rs/,理解ECS用连续数组为何更快 -阶段0 地基,0.3,游戏数学:线性代数(向量/矩阵/变换/正交投影),理论,✅有中文教程,GAMES101前几讲(线代复习+变换),https://www.bilibili.com/video/BV1X7411F744/,能手算旋转+平移的矩阵 -阶段0 地基,0.4,计算机图形学基础(光栅化/帧缓冲/着色器/管线),理论,✅有中文教程,GAMES101(重点光栅化与变换),https://www.bilibili.com/video/BV1X7411F744/,能说清图片如何显示到屏幕 -阶段0 地基,0.5,引擎宏观认知+游戏设计模式,理论,🔧有教程需改写,游戏编程模式中文版 + The Cherno第1集,https://gpp.tkchu.me/ ; https://www.bilibili.com/video/BV14v411h7Hu/,画出引擎模块草图 -阶段0 地基,0.6,Git版本控制,工具,✅有中文教程,廖雪峰Git教程,https://liaoxuefeng.com/books/git/introduction/index.html,项目托管到GitHub -阶段1 工具链,1.1,安装Rust工具链(rustup/cargo),工具,✅有中文教程,TRPL中文版入门指南,https://kaisery.github.io/trpl-zh-cn/ch01-00-getting-started.html,cargo run跑通HelloWorld -阶段1 工具链,1.2,配置VS Code + rust-analyzer + 调试器,工具,✅有中文教程,B站搜"VS Code Rust 环境配置",https://rust-analyzer.github.io/,代码有智能提示和实时报错 -阶段1 工具链,1.3,理解crate生态(crates.io/docs.rs/关键库定位),工具,✅有中文教程,crates.io / docs.rs,https://crates.io ; https://docs.rs,能自查一个库怎么用 -阶段2 渲染入门,2.A,用macroquad做小游戏建立手感(贪吃蛇/打砖块),代码,🔧有教程需改写,"Macroquad官方书(英文,代码极短)",https://mq.agical.se/ ; https://github.com/not-fl3/macroquad,做出一个能玩的贪吃蛇 -阶段2 渲染入门,2.B,winit开窗口 + wgpu初始化 + 第一个三角形,代码,✅有中文教程,学习wgpu中文版,https://jinleili.github.io/learn-wgpu-zh/,窗口里出现彩色三角形 -阶段3 2D渲染器,3.1,渲染管线/WGSL着色器/顶点索引缓冲,代码,✅有中文教程,学习wgpu中文版"管线/缓冲"章,https://jinleili.github.io/learn-wgpu-zh/,理解着色器与缓冲 -阶段3 2D渲染器,3.2,纹理加载(image库)与精灵Sprite渲染,代码,✅有中文教程,学习wgpu中文版"纹理与绑定组"章,https://jinleili.github.io/learn-wgpu-zh/,屏幕显示一张图片 -阶段3 2D渲染器,3.3,2D正交摄像机与世界/屏幕坐标转换,代码,✅有中文教程,学习wgpu中文版"Uniform与摄像机"章(简化为正交),https://jinleili.github.io/learn-wgpu-zh/,能移动缩放视角 -阶段3 2D渲染器,3.4,批处理渲染Batch Rendering(2D性能关键),代码,🔧有教程需改写,The Cherno "2D Batch Rendering"系列(C++),https://www.bilibili.com/video/BV14v411h7Hu/,流畅画上千精灵 -阶段3 2D渲染器,3.5,文本渲染(字体图集/SDF),代码,🔧有教程需改写,glyphon/wgpu_text库示例 + 位图字体原理,https://docs.rs/glyphon/,屏幕显示分数与调试信息 -阶段4 核心架构,4.1,游戏主循环(固定时间步长),代码,✅有中文教程,游戏编程模式"游戏循环"章,https://gpp.tkchu.me/game-loop.html,物理在不同帧率表现一致 -阶段4 核心架构,4.2,集成数学库glam,代码,✅有中文教程,glam文档(概念已掌握),https://docs.rs/glam/,引擎统一Vec2/Mat3类型 -阶段4 核心架构,4.3,日志系统(log/tracing分级日志),代码,✅有中文教程,log/env_logger库README + Cherno Logging集,https://docs.rs/log/,能打印分级调试信息 -阶段4 核心架构,4.4,事件系统(观察者/事件分发),代码,🔧有教程需改写,The Cherno事件系统系列 + 游戏编程模式观察者章,https://gpp.tkchu.me/observer.html,各系统能订阅处理事件 -阶段4 核心架构,4.5,ECS实体组件系统(先用hecs/bevy_ecs再考虑自造),架构,✅/⚠️,Bevy中文教程/Cheatbook + 游戏编程模式组件章,https://yiviv.com/bevy-cheatbook/ ; https://bevyengine-cn.github.io/learn/book_cn/getting-started/ecs/,能创建实体挂组件写系统 -阶段4 核心架构,4.6,资源管理器(纹理/音频/字体缓存+句柄),架构,⚠️无现成教程,参考Bevy Assets设计自行实现,https://bevy.org/,assets.load接口 -阶段5 子系统,5.1,输入系统(键鼠/手柄封装+按键映射),代码,🔧有教程需改写,winit输入文档 + gilrs手柄库,https://docs.rs/gilrs/,input.is_pressed接口 -阶段5 子系统,5.2,"音频系统(音效/BGM/音量,kira或rodio)",代码,✅/🔧,kira/rodio库示例 + B站"Rust音频",https://docs.rs/kira/,游戏能放音效和BGM -阶段5 子系统,5.3,"2D物理与碰撞(AABB/圆/响应,或集成rapier2d)",代码,🔧/⚠️,B站"AABB/SAT碰撞" + Randy Gaul物理教程 + rapier2d,https://rapier.rs/,角色能站平台被墙挡 -阶段5 子系统,5.4,精灵动画系统(序列帧/图集/动画状态机),代码,⚠️无现成教程,状态机参考游戏编程模式"状态"章自行实现,https://gpp.tkchu.me/state.html,角色播放走跳待机动画 -阶段5 子系统,5.5,粒子系统(发射器/生命周期/批量渲染),代码,🔧有教程需改写,The Cherno "Particle System"集(C++),https://www.bilibili.com/video/BV14v411h7Hu/,爆炸火焰等特效 -阶段5 子系统,5.6,场景管理与序列化(serde+ron/json),代码,✅/⚠️,B站/掘金"Rust serde" + 自行设计场景,https://serde.rs/,关卡能存文件再读回 -阶段5 子系统,5.7,游戏内UI系统(集成egui),代码,✅有中文教程,egui官方示例 + B站"Rust egui教程",https://github.com/emilk/egui,主菜单/暂停界面/HUD -阶段6 编辑器,6.1,集成egui编辑器面板(实体列表/属性Inspector),工具,✅有中文教程,egui文档 + The Cherno Editor系列建立设计观,https://github.com/emilk/egui,编辑器里选中实体改属性 -阶段6 编辑器,6.2,资源热重载(notify监听文件变化),工具,⚠️无现成教程,notify库README自行实现,https://docs.rs/notify/,改图不用重启程序 -阶段6 编辑器,6.3,关卡/地图编辑(自做或对接Tiled),工具,🔧有教程需改写,Tiled官方(有中文) + tiled rust库,https://www.mapeditor.org/ ; https://docs.rs/tiled/,用编辑器拼一张关卡 -阶段7 做游戏,7.1,选题与游戏设计(小而完整),设计,✅有中文教程,indienova独立游戏社区 + B站游戏设计入门,https://indienova.com/,一页纸设计文档 -阶段7 做游戏,7.2,用引擎实现完整游戏循环(菜单到结算到存档),代码,⚠️无现成教程,串起所有系统并反向补全引擎,,从头玩到尾的完整小游戏 -阶段7 做游戏,7.3,打磨与优化(性能/手感juice),代码,🔧有教程需改写,GDC "Juice it or lose it"(B站搬运),https://www.bilibili.com/,手感舒服不卡顿 -阶段7 做游戏,7.4,跨平台打包与发布(Win/Mac/Linux/可选WASM),工具,✅/🔧,cargo build --release + 学习wgpu中文版Web章,https://jinleili.github.io/learn-wgpu-zh/,发给朋友能玩/发布itch.io diff --git a/引擎学习开发计划.md b/引擎学习开发计划.md index 41450e5..286cc30 100644 --- a/引擎学习开发计划.md +++ b/引擎学习开发计划.md @@ -299,7 +299,7 @@ | ECS 思想 | Bevy Cheatbook 中文 | https://yiviv.com/bevy-cheatbook/ | | Git | 廖雪峰 Git 教程 | https://liaoxuefeng.com/books/git/introduction/index.html | -> 详细逐条任务见同目录下的 **引擎学习开发计划.csv**(可导入表格软件当进度看板用)。 +> 详细逐条任务见同目录下的 **引擎学习开发计划.xlsx**(可当进度看板用)。 --- diff --git a/引擎学习开发计划.xlsx b/引擎学习开发计划.xlsx index b0cb689dc1bc092ac524b6aac8155fb9b813e4ac..2c216fea9a3907ee7b582d81f71b270ed7d13b14 100644 GIT binary patch delta 4862 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

Sq|!@+y9Poyhs~_y#|siqNofX2**)uXS(f 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

Wx-P? zwOS|qKI6O%9f2kLd(OSFQ!C{xu&2Mj8s{EUfcmz?eb=@VIW(sw*R6h*T*RYCy`e73 zC3t^?rbxlYqto-0Pt}HUlxX7oUZdx!>W7V`X-<@79t6I}3F$YsChn?E8g@~svu1!a zWrB^78f1;-YaR_ZKQU0D$v#SL%42Uhx7ZX#Wbtx(`j9h~TC#;e-;vR12{amKgt{)X zs@AnG6MZ2ALvWNa^uneh>rn5pwoNHpERURP-c5-b`uOO--Fv(~Dfr&D`Q5$#J+yr} z=p+Bl3n%zgGnY+r$4QZ_0pwyk_O6pfj2IvcGrqYmp9b(3lFbmB>b?1lxg<=tsvw_TMuT5QykspZr%Y z(Gmygq+m_)64B}3ll^yN1OokIQ2sA5AWKxDrzHFTxt0GSOx`Dk(bJLrPviZ&?t1rM j?>|kQD{+*bmh6AZ3JwIq{(k@+Jc%d_G>Ccp|FQlrJwwd5