# iSometric **Repository Path**: lp9906/i-sometric ## Basic Information - **Project Name**: iSometric - **Description**: iSometric 是一款三维方块拼图游戏:系统随机生成一个 4×4×4 的连通方块组合,玩家参考三视图,在蜂巢(等距)线条视图中通过逐条点击网格线段,把目标形状的可见线框完整点亮即可通关。主要面向手机触屏,同时支持桌面端拖拽与快捷键式交互。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-24 - **Last Updated**: 2026-08-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # iSometric [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) ![Vite](https://img.shields.io/badge/Vite-5-646CFF) ![TypeScript](https://img.shields.io/badge/TypeScript-5-3178C6) ![Canvas](https://img.shields.io/badge/Canvas-2D-2dd4bf) **iSometric** 是一款三维方块拼图游戏:系统随机生成一个 4×4×4 的连通方块组合,玩家参考**三视图**,在**蜂巢(等距)线条视图**中通过逐条点击网格线段,把目标形状的可见线框完整点亮即可通关。主要面向**手机触屏**,同时支持桌面端拖拽与快捷键式交互。 > 纯原生渲染:无任何运行时依赖,全部画面由 Canvas 2D 手写实现(等距投影、隐藏线裁剪、线稿三视图)。 > 🧩 **推荐语**:三视图是线索,蜂巢是画板——逐条点亮线条,还原隐藏的三维形状。最考验空间想象力的方块拼图,碎片时间随时来一局! --- ## 📌 项目信息 | 项目 | 说明 | | --- | --- | | 名称 | iSometric | | 类型 | 三维拼图游戏(单页 Web 应用) | | 玩法 | 三视图为参考答案,蜂巢视图中用线条还原目标形状 | | 网格 | 4×4×4 三维网格(连通随机生成) | | 难度 | 简单 8~12 · 中等 13~18 · 困难 19~28 个方块 | | 技术栈 | Vite 5 + TypeScript 5 + 原生 Canvas 2D | | 视角 | 等距投影:水平 45° + 俯仰 atan(1/√2) ≈ 35.26° | | 平台 | 手机(主要)、平板、桌面浏览器、TapTap 小游戏 | | 版本 | 1.0.15 · MIT 许可证 | ## ⭐ 核心功能 ### 1. 首页与难度选择 - 大标题 + 三档难度按钮(简单 / 中等 / 困难),选择后随机生成对应规模的目标形状进入游戏 - 首页底部显示**当前版本号**(随 package.json 自动同步) ### 2. 三视图(参考答案) - **左视图 / 正视图 / 俯视图** 分层纯线条展示目标形状: - 同一平面的相邻 box 合并为闭合轮廓(内部无分割线) - 靠近视图的平面遮挡后面平面(被完全遮住的格子不绘制) - 被遮挡层的外轮廓边缘以**虚线**对比展示(与覆盖层边缘相差一格) - 俯视图**底部中间空心圆**标记正面方向(+z 在俯视图中指向屏幕下方,线条色) ### 3. 蜂巢线条视图(搭建区) - 初始**空白**,背景为一个大等边六边形(网格立方体投影外轮廓)+ 内部 box 边长单位的等边三角形网格 - 六边形**右下边中点外侧空心圆**标记**正面方向**(+z 世界方向在等距投影中指向右下,圆点正对边中段、紧贴图形外沿) - **单击网格单位线段**置灰高亮、再次单击取消;悬停显示预选提示 - **滑动涂画(防误触)**:按住滑动按**趋势**判定—— - **任意方向**首次滑过线段 = 画上(从哪端画都可以,不因线段固定端点方向误判) - 每线记住被画时的滑动方向,**反向滑过**(画完原路返回,抬手后再滑也有效)= 擦除 - 同向再滑保持(不闪烁);**近垂直横穿**忽略(不误触) - 滑动轨迹按步长插值采样,快速甩动不漏线;重绘按帧合并 - **辅助线作画模式**(蜂巢视图**左上角**📏 按钮切换,旁边 🧹 清空):点亮 27 条长参考线(x/y/z 每轴 9 条;长度 9 格 + 每端延伸 0.2)辅助对齐;**按"底"级参考呈现**——1px 细线、[4,4] 短虚线、低饱和淡绿(不抢内容线视觉层级,避免图形-背景错觉);**逐轴对齐基准**——竖着的 y 向线族中点压过视图中心的横线,左斜的 x 向线族中点排列方向 **+60°**,右斜的 z 向线族中点排列方向 **-60°**,三向间距一致;单击点亮/熄灭,**不参与完成判定**;渲染优先级最低、与背景线错开 1px;**退出模式后已点亮的辅助线保留显示**,🧹 清空按钮一键移除 - 游玩过程中 **3D 视图自动隐藏**,蜂巢视图占满整行 ### 4. 完成判定与结果展示 - **顶部计时器**:进入游玩即开始计时(⏱ mm:ss),完成时停止 - 高亮线条与目标形状**可见线框**(精确隐藏线裁剪后可见比例 ≥ 25% 的线段)一致时游戏完成: - 弹出「🎉 游戏完成!」提示(**视口固定居中**,手机上滚动后也必定可见;2.5s 自动关闭),副标题**显示用时** - 顶部常驻「✅ 已完成(难度 · 用时)」标记 - **3D 视图随即展示**最终结果:每个 box 颜色唯一(黄金角色相),可拖动旋转 / 自动旋转查看 - 完成判定对"同视线重合线段"做了去重与拾取去歧义,保证**照着目标线条点完即可通关** ### 5. 调试工具(🔧) - 强制显示 3D 视图(游玩中查看目标) - 叠加显示目标蜂巢线条(**红色 = 目标 · 灰色 = 已高亮**),直观对比"差在哪" - 显示难度 / 方块数 / 目标线段数 / 已高亮数 ### 6. 交互控制 - 单击线段:高亮 / 取消 - 拖动 3D 视图:旋转视角;滑块调节水平 / 俯仰;自动旋转;重置视角 - 响应式布局:三视图**永远一行**展示;场景随宽度自动堆叠(手机单列、桌面多列) ### 7. 日夜主题 - 首页右上角提供**主题切换按钮**(☀️ 日间 / 🌙 夜间),选择持久化到本地 - 样式分离为**基础样式 + 主题样式**(CSS 变量驱动),画布线条/遮罩颜色随主题联动重绘 - **日间主题**为默认:小清新卡通柔色系(奶油底色、纯白面板、柔和珊瑚橙点缀);夜间为深色风格(首次进入默认日间) ## 🖼️ 游戏预览 | 游戏图标 | 游戏截图 1 | | --- | --- | | ![游戏图标](images/icon.png) | ![游戏截图1](images/游戏截图1.png) | | 游戏截图 2 | 游戏截图 3 | 游戏截图 4 | | --- | --- | --- | | ![游戏截图2](images/游戏截图2.png) | ![游戏截图3](images/游戏截图3.png) | ![游戏截图4](images/游戏截图4.png) | > 宣传图 `images/宣传图.png`;实机录屏 `images/游戏录屏.mp4`。 ## 🚀 快速开始 ```bash npm install npm run dev # 开发服务器 http://localhost:5173 npm run typecheck # TypeScript 类型检查 npm run build # 生产构建(vite) npm run package # 打包生成 packages/{name}_v{version}.zip npm run preview # 预览构建产物 ``` ## 📂 目录结构 ``` iSometric/ ├── index.html # 页面结构:首页(难度)+ 游戏页(三视图/场景/浮层) ├── game.json # TapTap 小游戏配置(竖屏、appId、productName) ├── project.config.json # TapTap 小游戏工程配置(es6) ├── LICENSE # MIT 许可证 ├── README.md ├── package.json # 依赖与脚本(Vite / TypeScript) ├── tsconfig.json # TS 严格模式配置 ├── vite.config.ts # Vite 配置(端口、watch、相对路径 base、固定产物名) ├── src/ │ ├── main.ts # 入口:装配各管理器 + 渲染循环 + 主题切换 │ ├── style.css # 基础样式:布局与结构(颜色取自主题变量) │ ├── themes.css # 主题样式:夜间(默认) / 日间(小清新卡通柔色系)CSS 变量 │ ├── vite-env.d.ts # Vite 客户端类型声明(CSS 模块等) │ ├── core/ # 实体与数据(纯计算,无渲染) │ │ ├── grid.ts # 4×4×4 网格:连通随机生成、唯一色相(hueFor)、setBox/matches │ │ └── colors.ts # 主题化配色:gridColor/lineColor/panelBg(读 CSS 变量) │ ├── entity/ # 几何实体类(每类一个文件,统一从 index.ts 导入) │ │ ├── index.ts # 实体索引:Point3/Rect/Segment2/Segment3/Plane/Quad + keyOfGrid │ │ ├── Point3.ts # 三维点(comp/mid/offset/toTuple) │ │ ├── Rect.ts # 平面矩形块(遮挡测试与面合并共用) │ │ ├── Segment2.ts # 平面内单位网格边(区域轮廓) │ │ ├── Segment3.ts # 三维单位线段(自动计算 key/轴向/端点/中点/视深)+ keyOfGrid │ │ ├── Plane.ts # 轴向平面(SIZE×SIZE 平面网格 + rects/outline 缓存) │ │ └── Quad.ts # 表面四边形(3D 视图渲染用) │ ├── algo/ # 算法与计算模型(独立目录,纯计算,无渲染) │ │ ├── decompose.ts # 复杂算法:扫描线矩形分解(遮挡测试与面合并共用) │ │ ├── outline.ts # 算法:平面网格轮廓提取(单元级边) │ │ ├── planes.ts # 复杂算法:可见平面提取(内部面/背面剔除 + 归并) │ │ ├── clipping.ts # 复杂算法:精确隐藏线裁剪(视线射线求交 + 区间补集) │ │ ├── faces.ts # 复杂算法:3D 表面四边形提取(内部面剔除 + 同色合并) │ │ ├── segments.ts # 线段索引(300 条 Segment3)+ 屏幕拾取(去歧义) │ │ ├── guides.ts # 辅助线索引(27 条:x/y/z 每轴 9 条,9 格+延伸)+ pickGuide │ │ ├── swipe.ts # 滑动路径吸附检测:插值采样 + 方向无关首滑 + 方向记忆返回擦除 │ │ ├── isoFaces.ts # 3D 视图计算模型:面片投影/背面剔除/画家排序/屏幕换算 │ │ ├── viewLayers.ts # 三视图计算模型:分层掩码/足迹遮挡/可见层/虚线边缘 │ │ └── wireframe.ts # 目标线段集(组合算法):planes + clipping → 可通关 key 集合 │ ├── utils/ │ │ ├── dom.ts # byId() 类型安全 DOM 获取 │ │ ├── theme.ts # 主题切换:日夜切换 + localStorage 持久化 │ │ ├── math3d.ts # 数学计算工具:等距投影常量、向量运算、视空间/屏幕映射、区间裁剪、距离 │ │ └── canvas2d.ts # Canvas 绘制工具:DPR 清屏/批量线段/网格/掩码/轮廓/虚线/多边形 │ ├── render/ # 纯渲染(只画,不计算;计算见 algo/) │ │ ├── views.ts # 三视图渲染:读 viewLayers 模型 → 背景/遮盖/实线/虚线 │ │ ├── iso.ts # 3D 蜂巢视角渲染:读 isoFaces 模型 → 地面网格/彩色面片 │ │ └── isoLines.ts # 蜂巢线条视图渲染:读 segments 索引 → 六边形背景/高亮 │ └── game/ │ ├── GameManager.ts # 游戏状态机:难度、高亮交互与完成判定、调试开关 │ ├── SceneControls.ts # 3D 视角控制:滑块/自动旋转/拖动/重置 │ └── Renderer.ts # 渲染调度:DPR 适配、ResizeObserver、视图分发 ├── scripts/ │ └── package.mjs # 打包脚本:dist → packages/{name}_v{version}.zip(纯 Node 实现 ZIP) ├── vitest.config.ts # Vitest 配置:仅扫描 test/**/*.test.ts └── test/ # 自动化测试(Vitest,直接测真实源码)+ 无头验证脚本 ├── helpers/ # 测试辅助:mockCanvas2D(2D 上下文 mock)、测试 DOM 构建 ├── unit/ # 单元测试:实体/数学/网格/绘制工具 ├── algo/ # 算法测试:分解/轮廓/平面/裁剪/面/线段/目标集 ├── model/ # 模型测试:三视图模型、3D 面片模型 ├── render/ # 渲染测试:三视图/3D/蜂巢(mock ctx 断言绘制调用) ├── flow/ # 流程测试:GameManager 状态机(happy-dom) ├── control/ # 控制测试:SceneControls / Renderer ├── smoke/ # 冒烟测试:模块可加载、关键常量、导出完整性 ├── integration/ # 整体测试:完整游戏循环(点击必达完成) ├── render-test.mjs # 渲染测试:输出各形状的 PNG(独立脚本) ├── diag.mjs # 诊断:逐平面/线段输出可见性比例与遮挡来源 ├── debug.mjs # 调试:打印遮挡区间明细 ├── verify-lines.mjs # 验证:线段索引 300 条、目标集与索引匹配、完成判定 └── verify-complete.mjs # 验证:30 个随机形状"按红线中点点击"必达完成 ``` ## 🧠 核心算法 **分层原则**:`core/` 放数据,`entity/` 放几何实体类(每类一个文件,统一从 `entity/index.ts` 导入),`algo/` 独立存放全部算法与计算模型(纯计算,不碰 Canvas),`render/` 只做绘制(读计算模型 + Canvas 绘制工具 `utils/canvas2d.ts`)。复杂算法独立成文件并带推导备注: - `entity/` — 几何实体类(每类一个文件):**Point3**(点)、**Segment2 / Segment3**(线,Segment3 构造时自动计算 key / 轴向 / 世界端点 / 中点 / 视深)、**Plane / Rect**(面)、**Quad**(三维表面四边形);`keyOfGrid` 线段 key 规范 - `algo/decompose.ts` — **扫描线矩形分解**:水平合并 + 向上扩展,把平面网格拆为最小同值矩形块(遮挡命中测试从 O(格数) 降为 O(矩形数)) - `algo/outline.ts` — **轮廓提取**:一侧有面、一侧无面才画,无内部线 - `algo/planes.ts` — **可见平面提取**:内部面剔除 + 背面剔除(法线·视线 ≤ 0 不画)+ 按「方向+坐标」归并 - `algo/clipping.ts` — **精确隐藏线裁剪**:视线射线与面平面求交(t > CLIP_EPS),命中矩形区间收集 → 排序合并 → 补集得可见区间 - `algo/segments.ts` — 线段索引(300 条 Segment3)与屏幕拾取(16px 容差 + 同屏去歧义) - `algo/guides.ts` — **辅助线**:27 条长参考线(每轴 9 条、9 格 + 每端延伸 0.2,1px 虚线低饱和绿)索引与拾取,供辅助线作画模式点亮(不参与完成判定,退出模式保留,可一键清空) - `algo/swipe.ts` — **滑动路径吸附检测**:轨迹按步长插值采样;任意方向首次滑过 = 画,方向记忆(dirs)记录每线被画时的滑动方向,反向滑过 = 擦除(原路返回即橡皮擦),同向再滑保持、近垂直横穿忽略;同段同 key 去重 - `algo/faces.ts` — 3D 表面四边形提取(内部面剔除 + 同色矩形合并为 Quad) - `algo/isoFaces.ts` / `algo/viewLayers.ts` — 3D 面片模型(投影/背面剔除/画家排序)与三视图模型(分层/足迹/虚线),渲染层直接消费 - `utils/math3d.ts` — 等距投影常量、`toViewSpace`/`isoTransform`/`honeycombScreen` 屏幕映射、`rangeLinear` 区间裁剪、`distToSegment` - `utils/canvas2d.ts` — Canvas 绘制工具:`prepareCanvas`(DPR 清屏)、`beginStroke`/`addSegments`(批量线段路径)、`strokeCellGrid`/`fillCellMask`/`strokeCellOutlines`(网格与掩码)、`strokeDashed`(虚线)、`paintPolygon`(多边形) ### 1. 等距投影 - 水平 45° + 俯仰 `atan(1/√2) ≈ 35.26°`(常量 `CY/SY/CP/SP`),视空间坐标 = `toViewSpace(x,y,z)`;指向相机的方向 `VIEW_DIR = [-CP·SY, SP, CP·CY]` - 单个 box 投影为**六个等边三角形组成的等边六边形**(45°+45° 无法得到等边六边形) - 任意视角(3D 结果视图的拖动 / 滑块):`isoTransform`(绕 Y 轴 yaw + 绕 X 轴 pitch)+ `viewToScreen` ### 2. 平面提取(buildPlanes) - 遍历每个 box 的 6 个面:邻居 box 存在 → **内部面剔除**(闭合图形);法线背离相机(`sign·VIEW_DIR[axis] ≤ 0.0001`)→ **背面剔除** - 剩余面按「方向 + 固定平面坐标」归并为 **Plane**(SIZE×SIZE 平面网格),供遮挡测试与轮廓提取共用 ### 3. 矩形分解(decompose) - 扫描线算法:逐行合并连续同值格,与上一行同宽同值则向上扩展,把平面网格分解为**最小矩形块集合**;遮挡命中测试逐矩形进行,大幅减少计算量 ### 4. 精确隐藏线裁剪(visibleParts) - 对线段 `p(s) = a + s(b−a)` 与每个面做射线命中:沿视线方向命中面平面(`t > CLIP_EPS = 0.02`)且命中点落在面矩形内 ⇒ 该 s 区间被遮挡 - 收集全部被遮挡区间 → 排序合并 → 取补集得到**可见区间**;顺序无关、结果精确 ### 5. 目标线段集(computeTargetSegments) - 每个可见平面的轮廓单元边(**outlineSegments**:一侧有面、一侧无面才画,无内部线)转为 Segment3 候选 - 过滤规则:可见比例 ≥ 25%(`VISIBLE_THRESHOLD`);同一边被多平面重复收集按 key 去重;同视线射线(同轴 + 中点偏移 ∥ 视线方向)上的线段只保留**离相机最近**的一条 - 目标 key 与拾取索引完全一致,保证「照着目标线条点完即可通关」 ### 6. 线段索引与拾取(pickSegment) - 预生成 300 条单位线段(x/y/z 三轴方向各 4×5×5,Segment3 索引 key → Segment3 的 Map) - 屏幕点击:计算点到 300 条线段投影的距离,16px 容差内取最近;同屏重合线段**优先返回目标集合中的线段**,其次返回离相机最近(视深 z 最大)的可见一条 ## 🔬 技术要点 - **等距投影**:水平 45° + 俯仰 `atan(1/√2) ≈ 35.26°`,单个 box 投影为**六个等边三角形组成的等边六边形**(45°+45° 无法得到等边六边形) - **精确隐藏线裁剪**:每条线段与所有面做射线命中测试,仅「命中点在面多边形内且面更靠近相机」的部分被遮挡——顺序无关、结果精确 - **目标线段集**:目标可见线框所占单位网格线段,规则为——可见比例 ≥ 25% 计入;同视线射线(同轴 + 偏移 ∥ 视线方向)上的线段只保留最近一条;同一边被多平面重复收集时按 key 去重 - **线段拾取去歧义**:同屏重合线段优先返回目标集合中的线段,其次离相机最近的(可见)一条 - **唯一配色**:3D 视图按 box 序号黄金角色相(`hue = 序号×137.508 + 15`),任意两个 box 色相不同 - **三视图层次**:近层足迹遮挡 + 同层合并轮廓 + 虚线隐藏边缘对比展示 ## 🧪 测试 ### Vitest 自动化测试(推荐) ```bash npm test # 全量运行(163 用例 / 21 文件) npm run test:watch # 监听模式 npm run typecheck # 类型检查(含测试文件) ``` 按目录分层,直接测试**真实源码模块**(非逻辑副本): | 目录 | 覆盖 | |---|---| | `test/unit/` | 单元测试:实体类(entity)、数学工具(math3d)、网格(grid)、Canvas 绘制工具(canvas2d) | | `test/algo/` | 算法测试:矩形分解、轮廓提取、平面提取、隐藏线裁剪、表面四边形、线段索引/拾取、滑动吸附、目标线段集 | | `test/model/` | 模型测试:三视图计算模型(分层/足迹/虚线)、3D 面片模型(投影/背面剔除/排序) | | `test/render/` | 渲染测试:三视图 / 3D / 蜂巢线条(mock 2D 上下文,断言绘制调用序列) | | `test/flow/` | 流程测试:GameManager 状态机(首页→游玩→完成→返回,happy-dom 真实 DOM) | | `test/control/` | 控制测试:SceneControls(滑块/自动旋转/拖动/重置)、Renderer(DPR 适配/渲染调度) | | `test/smoke/` | 冒烟测试:全部模块可加载、关键常量、导出完整性 | | `test/integration/` | 整体测试:完整游戏循环(生成→目标集→按红线点击→必达完成,30 随机形状) | ### 独立验证脚本(无依赖,node 直跑) ```bash node test/render-test.mjs # 渲染 PNG 输出 node test/diag.mjs # 平面/线段可见性诊断 node test/verify-lines.mjs # 线段索引与目标集验证 node test/verify-complete.mjs # 模拟"按红线中点点击"必达完成 ``` ## 🤖 AI 协作 本项目在开发过程中由 AI 辅助编码完成: - **模型**:DeepSeek v4 Flash(`deepseek-v4-flash`) - **开发框架**:DeepSeek Harness(`deepseek-harness`) ### AI 处理流程 每个迭代周期的标准流程(按序执行,缺一不可): 1. **处理**:按需求修改代码(修复/优化/新功能),`npm run typecheck` 通过 2. **更新 MD**:同步更新 `README.md`(功能/架构/事件表变更 + 变更记录条目) 3. **升版 Package Version**:更新 `package.json` 的 `version`(如 1.0.51) 4. **pkg zip**:执行 `npm run package` 生成 `packages/{name}_v{version}.zip`(name 取自 package.json) 5. **commit**:`git add` 全部改动并提交(提交信息注明变更内容与版本号) ## 📝 变更记录 - **v1.0.15**:辅助线视觉弱化——改为 1px 细线 + [4,4] 短虚线 + 低饱和淡绿(日间 0.55 / 夜间 0.6),归入"底"级参考元素,避免突兀强线造成图形-背景错觉、干扰对目标与高亮的判断;长度/步进/对齐/错开均不变 - **v1.0.14**:新增辅助线作画模式——蜂巢视图左上角 📏 按钮切换 + 🧹 清空按钮;27 条长参考线(x/y/z 每轴 9 条,长度 9 格 + 延伸 0.2);逐轴对齐(y 向压中心横线、x 向 +60°、z 向 -60°,三向间距一致);渲染优先级最低、与背景线错开 1px;退出模式保留显示;不参与完成判定 - **v1.0.13**:新增游戏计时器——顶部实时显示 ⏱ mm:ss(进入游玩开始、返回首页重置);通关提示与常驻标记显示**用时**;完成瞬间计时停止定格 - **v1.0.12**:修复俯视图方向标记圆点裁剪——圆点固定定位在图形底边下方 14px(锚点网格投影,不依赖画布高度),三视图画布比例 1:1 → 1:1.2 为圆点预留底部留白 - **v1.0.11**:正面方向标记优化——俯视图底部 / 蜂巢视图右下边中点外侧的空心圆标记(线条色、随主题联动);蜂巢圆点从画布角落移至六边形右下边中点外侧(正对边中段),俯视图圆点下移 14px - **v1.0.10**:滑动涂画修复——吸附检测重构为**方向无关首滑 + 方向记忆**:任意方向首次滑过 = 画(修复"向左下固定擦除"),每线记忆被画时的滑动方向、反向滑过 = 擦除(修复"路径返回不擦除",抬手后再滑也有效);滑动吸附封装为独立算法 `algo/swipe.ts` 并配套单元测试 - **v1.0.9**:完善测试体系——引入 Vitest + happy-dom(devDependencies),新增 163 个用例覆盖单元/算法/模型/渲染/流程/控制/冒烟/整体八类测试(`npm test` 一键运行,直接测试真实源码);修复 `algo/faces.ts` 平面归并 key 编码遗留 bug(同平面格被拆散导致合并失效);`canvas2d.ts` 空 mask 跳过空路径绘制 - **v1.0.8**:代码结构再分层——几何实体类拆分到独立目录 `entity/`(每类一个文件 + 索引桶,keyOfGrid 归入线段实体,outlineSegments 移至 `algo/outline.ts`);上一版 v1.0.7 已把算法与计算模型集中到 `algo/`、渲染与计算彻底分离(`render/` 纯绘制 + `utils/canvas2d.ts` 绘制工具) - **v1.0.7**:代码结构优化——点线面几何元素封装为实体类(新增 `core/geometry.ts`:Point3/Segment2/Segment3/Plane/Rect/Quad,keyOfGrid/decompose/outlineSegments 收拢,wireframe 与 faces 的矩形分解合并为一处);数学计算函数集中到 `utils/math3d.ts`(dot/rangeLinear/axisToWorld/isoTransform/viewToScreen/honeycombScreen,消除各渲染文件内联重复);README 新增「核心算法」章节 - **v1.0.6**:首页底部新增当前版本显示(直接读取 package.json 自动同步);默认主题改为日间(首次进入即日间,夜间需手动切换并持久化) - **v1.0.5**:新增日夜主题——样式拆分基础/主题两层(CSS 变量驱动)、日间小清新卡通柔色系、首页主题切换按钮(localStorage 持久化)、画布颜色随主题联动;三视图改为永远一行展示 - **v1.0.4**:代码结构重构——src 按 core/utils/render/game 分类、isoLines 拆分(线框几何独立为 wireframe.ts)、main 封装为 GameManager/SceneControls/Renderer 三个管理类、高频代码抽入公共工具(dom/math3d)、新增 vite-env.d.ts 修复 CSS 导入类型报错 - **v1.0.3**:修复手机端完成提示不可见——完成横幅改为视口固定居中(滚动后仍可见)、显示时长 1.5s→2.5s、新增常驻「✅ 已完成」标记 - **v1.0.2**:TapTap 小游戏打包配置(`game.json` / `project.config.json`)+ 相对路径 base 与固定产物名(`main.js`) - **v1.0.1**:打包脚本 `scripts/package.mjs` 顶层目录名与 zip 文件名改为读取 `package.json` 的 `name`(不再硬编码) - **v1.0.0**:初版上线(线条级拼图玩法、三视图参考、3D 结果展示、移动端适配) ## 📄 许可证 [MIT](LICENSE) © 2025 liupu