学习路径Learning path · 连续项目Worked project
三颗星,一扇门:把同一个游戏逐步做完整Three stars, one door: complete one game step by step
这是本站编写的浏览器小游戏。收齐三颗星后走到 E,逐步查看核心循环、暂停、存档、触屏、适配与发布。代码验证只针对这个样例,不是引擎或 AI 产品评测。This site-authored browser game asks you to collect three stars and reach E. Explore its loop, pause, saves, touch controls, resizing and publication. Code checks concern this example only, not engines or AI products.
六个阶段The six stages
下面六节是完整教学内容,构建时就写进 HTML —— 脚本关掉也照样能读。想边读边试,用工作台的阶段选择器切换控件。The six sections below are the full teaching text, written into the HTML at build time — they read fine with scripting off. Use the workbench’s stage selector to try each one.
游戏本体:7×5 棋盘,三颗星,一扇门The game itself: a 7×5 board, three stars, one door
方向键或 WASD 移动;踩到 ★ 收星,收齐三颗之后走到 E 才算完成。下面的「阶段」选择器决定哪些控件出现 —— 那些控件正是这六个阶段要讲的东西。Arrows or WASD move. Step on ★ to collect a star; reaching E only completes the round after all three. The stage selector below decides which controls appear — those controls are the six lessons.
位置 1,1 · 星星 0/3 · 步数 0。收集三颗星,再到 E 出口。Position 1,1 · Stars 0/3 · Moves 0. Collect three stars, then reach E.
还没有此项目存档。保存仅在当前浏览器与当前站点;不上传。No project save yet. Saving stays in this browser and origin; it is not uploaded.
阶段 6 · 发布前自己勾一遍Stage 6 · tick these before you ship
棋盘由构建时复制过来的 ./game.js 画,样式是同目录的 game.css;两者都不是手写进页面的。The board is drawn by ./game.js, copied at build time; its styles are the sibling game.css. Neither is hand-written into the page.
阶段 1 · 先让核心循环成立Stage 1 · Establish the core loop
这一步改什么What changes here:: 把关卡、玩家位置、已收集星星和步数分开保存。方向键或 WASD 改状态,再重画棋盘;碰墙不增加步数,出口在收齐星星后才算完成。Keep level, position, collected stars and moves separate. Arrows/WASD update state before repainting. Walls do not add moves; reaching the exit completes the game only after collecting all stars.
代码在哪一层Where the code sits
state = { x: 1, y: 1, moves: 0, collected: [] };
// Input -> legal move -> update state -> render
// Completion is derived from position and collected stars.
怎么检查它真的成立How to check it actually holds
- 从起
- Mo
不成立时先看哪里Where to look when it does not
- 若出
- Fo
阶段 2 · 暂停与重新开始Stage 2 · Pause and restart
这一步改什么What changes here:: 暂停是独立状态,不改关卡和收集进度。页面隐藏时自动暂停,回来后主动继续。重新开始只重置盘面,不删除已有浏览器存档。Pause is independent of level/progress. A hidden page pauses; returning requires explicit resume. Restart resets the board without deleting a browser save.
代码在哪一层Where the code sits
if (paused) return;
// On visibilitychange: if document.hidden, pause.
// Restart creates a fresh state; it does not call localStorage.clear().
怎么检查它真的成立How to check it actually holds
- 暂停
- Mo
不成立时先看哪里Where to look when it does not
- 若暂
- If
阶段 3 · 版本化存档与失败降级Stage 3 · Versioned saves and fallback
这一步改什么What changes here:: 只保存关卡 ID、版本、坐标、步数和已收集项。读入时校验字段、位置和关卡,不信任文件中的完成标记。存储受限仍能玩,并可下载/读入 JSON 文件;不上传存档。Save only level ID, schema version, coordinates, moves and collected items. Validate fields, position and level; derive completion rather than trusting a flag. Storage-blocked play still works with JSON download/import. Saves are not uploaded.
代码在哪一层Where the code sits
{ schema: 1, level: 'three-stars-1', x, y, moves, collected }
// Parse -> validate -> replace state. Invalid saves keep the current board.
// Browser save and file import are separate explicit actions.
怎么检查它真的成立How to check it actually holds
- 走几
- Sa
不成立时先看哪里Where to look when it does not
- lo
- lo
→ 下一阶段:让触屏与键盘走同一条逻辑→ Next stage: Share movement between touch and keyboard
阶段 4 · 让触屏与键盘走同一条逻辑Stage 4 · Share movement between touch and keyboard
这一步改什么What changes here:: 四个方向按钮调用相同的 move 函数,不另写一套触屏规则。按钮保留可点尺寸与键盘焦点;只在棋盘聚焦时接管方向键,不阻止整页滚动与缩放。Directional buttons call the same move function as keyboard input. Keep usable targets/focus. Capture arrows only while the board has focus; do not block page scrolling or zooming.
代码在哪一层Where the code sits
button.addEventListener('click', () => move(dx, dy));
// Direction buttons: touch-action: manipulation.
// Keyboard handling belongs to the focusable board, not the whole document.
怎么检查它真的成立How to check it actually holds
- 用屏
- Th
不成立时先看哪里Where to look when it does not
- 若触
- Fo
→ 下一阶段:改变显示尺寸,保留游戏状态→ Next stage: Resize the view without resetting state
阶段 5 · 改变显示尺寸,保留游戏状态Stage 5 · Resize the view without resetting state
这一步改什么What changes here:: 棋盘用七列弹性网格,尺寸由容器控制;坐标存在状态里,不以屏幕像素存档。窄棋盘选项只是显示练习,所有阶段都保留基础窄屏可读性。Use seven flexible columns within the container. Store coordinates in state, not screen pixels. The narrow-board option is a display exercise; every stage retains basic narrow-screen usability.
代码在哪一层Where the code sits
grid-template-columns: repeat(7, minmax(0, 1fr));
// Layout changes do not recreate initial game state.
// Saved coordinates remain grid coordinates.
怎么检查它真的成立How to check it actually holds
- 走几
- Af
不成立时先看哪里Where to look when it does not
- 若缩
- If
→ 下一阶段:打包、回放与发布检查→ Next stage: Package, replay and check publication
阶段 6 · 打包、回放与发布检查Stage 6 · Package, replay and check publication
这一步改什么What changes here:: 下载包包含 HTML、脚本、样式、品牌资源、素材记录和哈希清单。游戏本身没有网络请求或后端;站群与文档链接另需联网。发布自己的作品时检查代码/素材许可、资源路径、大小写、HTTPS 和目标浏览器。The download includes HTML, scripts, styles, brand assets, an asset ledger and hashes. The game itself has no network calls/backend; site/document links need connectivity. For your own publication, check code/asset rights, paths/case, HTTPS and target browsers.
代码在哪一层Where the code sits
index.html + game.js + game.css + brand.js + brand.css
asset-ledger.json + manifest.json + README.txt + NOTICE.txt
// Extract, serve on localhost, then test the actual packaged files.
怎么检查它真的成立How to check it actually holds
- 对解
- Pl
不成立时先看哪里Where to look when it does not
- 路径
- Fo
这是最后一个阶段。勾一遍上面工作台里「发布前自己勾一遍」那几条,再按下一节的清单核对包内文件。This is the last stage. Tick the release list in the workbench above, then check the package files against the next section.
素材与许可台账Asset and licensing ledger
下表逐项写明来源、用途与再分发权利。素材由 AI 起草不自动改变授权范围:本站没有因为「AI 生成」就给任何条目套 CC BY 或 MIT。例外只可能写在条目自己的许可列里,目前实测没有例外。Each row states origin, purpose and redistribution rights. AI drafting does not change the scope of rights: nothing here is labelled CC BY or MIT merely because a model produced it. An exception could only appear in the licence column of that row; the current ledger has none.
许可口径与法律页第 1 节一致:除非另有注明,内容由 Specul 自行创作并保留所有权利,本站未对文案与设计单独授予复制、改编、再分发或商业使用许可。正常链接与单句引用欢迎,整篇转载或商业使用请先联系本站。The licence wording follows section 1 of the legal page: unless noted otherwise the content is created by Specul and all rights are reserved — no separate licence is granted for copying, adapting, redistributing or commercial use. Links and single-sentence quotation are welcome; full republication or commercial use needs contact first. 法律页第 1 节section 1 of the legal page · 第 8 节(隐私与本地存储)section 8 on privacy and local storage
| 条目Item | 来源Origin | 用途Role | 许可Licence | 再分发权利Redistribution |
|---|---|---|---|---|
| game.js · 游戏逻辑与棋盘渲染game.js (game logic and board rendering) | 本站源仓 projects/three-stars/game.js;由 AI 起草,本站按文件与实际行为逐项核对后收录Source file projects/three-stars/game.js in this repository; drafted by AI and checked file-by-file against its actual behaviour before inclusion | 棋盘渲染、键盘与触屏输入、暂停、版本化存档与导入导出;无网络请求Board rendering, keyboard and touch input, pause, versioned saves and file import/export; no network calls | Specul 站点条款(法律页第 1 节)Specul site terms (legal page, section 1) | 未另行授予再分发或商业使用许可;可链接、可引用No separate redistribution or commercial licence; linking and quotation allowed |
| game.css · 工作台样式game.css (workbench styles) | 本站源仓 projects/three-stars/game.css;只引用 brand.css 的 token,不写裸色值Source file projects/three-stars/game.css in this repository; it uses only brand.css tokens and declares no raw colour values | 棋盘网格、方向按钮、阶段工具条与打印样式Board grid, direction buttons, stage toolbar and print rules | Specul 站点条款(法律页第 1 节)Specul site terms (legal page, section 1) | 未另行授予再分发许可No separate redistribution licence |
| project.json · 六阶段教学文案project.json (the six-stage teaching copy) | 本站编写的教学文案(中英两列同批修订)Teaching copy authored for this site (the Chinese and English fields are revised in the same pass) | 六个阶段的「改什么 · 代码 · 怎么检查 · 失败时先看」文本,构建期内嵌进页面The six stages' what / code / check / failure text, inlined into the page at build time | Specul 站点条款(法律页第 1 节)Specul site terms (legal page, section 1) | 未另行授予再分发许可;引用请注明来源No separate redistribution licence; credit the source when quoting |
| three-stars.html · 页面文案与台账three-stars.html (page copy and ledger) | 本站编写;台账条目逐条来自本仓源文件与共享品牌资产的真相源路径Authored for this site; each ledger row points at a source path in this repository or at a shared brand asset | 承载六阶段说明、可玩游戏本体、下载说明与素材台账Carries the stage explanations, the playable game, the download notes and the asset ledger | Specul 站点条款(法律页第 1 节)Specul site terms (legal page, section 1) | 未另行授予再分发许可No separate redistribution licence |
| brand.css · brand.js · 站群共享品牌资产brand.css · brand.js (shared site-brand assets) | 真相源 www.specul/brand.css 与 www.specul/brand.js;本仓有 vendored 副本,构建时按同一份复制Truth sources are www.specul/brand.css and www.specul/brand.js; this repository keeps a vendored copy and the build ships that same content | 全站外壳、明暗与语言切换、字号与配色 tokenSite shell, theme and language switching, the type and colour tokens | Specul 站点条款(法律页第 1 节);品牌标识另受第 9 节商标条款约束Specul site terms (legal page, section 1); the marks themselves fall under section 9 on trademarks | 随包复制只为让样例离线可开;不授予再分发或商业使用许可,也不授予商标权Copied into the package only so the sample opens offline; no redistribution, commercial or trademark licence is granted |
| site.css · 内容层排版site.css (content-layer typography) | 构建时由 _sites/_template/site.css 与 _data/game/css/vg.css 拼接Assembled at build time from _sites/_template/site.css plus _data/game/css/vg.css | 面板、表格、正文节奏等 vg 站内容层样式Panels, tables and body rhythm for the vg site | Specul 站点条款(法律页第 1 节)Specul site terms (legal page, section 1) | 未另行授予再分发许可No separate redistribution licence |
| 字体 · 无嵌入字体Fonts · none embedded | 本项目不打包任何字体文件;页面用读者系统里已有的字体,★ ● · E 都是文本字符No font file is packaged; the page uses fonts already on the reader's system, and ★ ● · E are text characters | 文字与符号显示Text and symbol rendering | 不涉及再分发No redistribution involved | 无字体再分发义务;你自己的项目要嵌字体时按字体授权单独核对(见「字体的授权陷阱」)No font redistribution duty; if your own project embeds a font, check that font's licence separately (see the font licensing term) |
| 图片 · 音频 · 3D · 无此类素材Images · audio · 3D · none of these | 本项目不含图片、音频、3D 模型或生成素材The project contains no images, audio, 3D models or generated media | —- | 不涉及Not applicable | 无第三方素材许可义务;也请勿把「没有素材」当成「素材随便用」的先例No third-party asset obligations; and do not treat 'no assets here' as a precedent for using assets freely |
| 第三方运行时代码 · 无Third-party runtime code · none | 无 npm 依赖、无 CDN、无框架;页面脚本只有 game.js 一份No npm dependencies, no CDN, no framework; game.js is the only page script | —- | 不涉及Not applicable | 无第三方许可通知义务No third-party notice obligations |
| zip.mjs · 打包辅助(不进包)zip.mjs (build-time packer, not shipped inside the archive) | 本站源仓 projects/three-stars/zip.mjs:自写 stored ZIP 与 CRC32,构建期使用Source file projects/three-stars/zip.mjs: a hand-written stored-ZIP and CRC32 writer used at build time | 生成 three-stars.zip 与哈希清单Generates three-stars.zip and the hash manifest | Specul 站点条款(法律页第 1 节)Specul site terms (legal page, section 1) | 属于构建工具,不随下载包分发;未另行授予再分发许可A build tool; not shipped inside the download and not separately licensed |
| 存档 JSON · 本地数据,示例均为虚构Save JSON · local data; every sample value is fictional | 由玩家在本机导出(three-stars-save.json);本站展示的示例内容均为虚构Exported locally by the player (three-stars-save.json); every example value shown by this site is fictional | 关卡 ID、版本号、坐标、步数、已收集星星Level id, schema version, position, move count and collected stars | 数据归导出者本机所有The data stays on the machine that exported it | 不上传、不含账号或标识信息;隐私口径见法律页第 8 节Nothing is uploaded and it carries no account or identifier; privacy terms are in section 8 of the legal page |
性质:本站按文件与行为逐条核对,核验日 2026-11-06。这不是法律意见,也不代替你去读上游条款原文。Nature: checked row by row against the files and their behaviour on 2026-11-06. This is not legal advice and does not replace reading the upstream terms.
可下载成品包The downloadable package
你现在打开的就是解压出来的这一份。成品包本体在站点上:You are looking at the unpacked copy. The archive itself lives on the site: three-stars.zip · 线上页面the online page · 逐文件哈希per-file hashes
这个包里应该有这些文件(逐文件的字节数与 SHA-256 在 manifest.json 里):These are the files this package should contain (per-file bytes and SHA-256 are in manifest.json):
index.htmlgame.jsgame.cssbrand.cssbrand.jssite.cssasset-ledger.jsonREADME.txtNOTICE.txtmanifest.json
打开方式:解压后直接双击 index.html 就能玩 —— 样式、脚本与品牌资源都在包内,不发请求。要做完整检查时再起一个本地静态服务打开一次:file:// 下的 localStorage 与站点来源的策略不同,这一项要按你实际发布的协议另测。How to open: extract and double-click index.html and it plays — styles, scripts and brand assets are inside and nothing is requested. For a full check, also serve the folder over a local static server: localStorage under file:// is not governed like a site origin, so that item has to be re-tested under the protocol you actually ship on.
独立核对:本站用独立解压工具与 zip 校验各跑过一遍(CRC、逐文件字节比对、离线打开)。结论与局限写在下一节。Independent checks: this site extracted and verified the archive with separate tooling (CRC, byte-for-byte file comparison, opening it offline). The conclusions and their limits are in the next section.
机读版台账:asset-ledger.json · 哈希清单:manifest.json · 包内说明:README.txt · 许可文字:NOTICE.txtMachine-readable ledger: asset-ledger.json · hash manifest: manifest.json · package notes: README.txt · licence text: NOTICE.txt
本站检查过什么 · 没检查什么What this site checked · and did not
核验日 2026-11-06,范围只有这一份样例与这一个包;下面每一条都在浏览器里实际跑过,不是代码意图。Verified on 2026-11-06, scoped to this sample and this package only; every line below was run in a browser, not merely read off the code.
- 从起点收齐三颗星并走到出口,位置、星星数、步数与完成判定一致;撞墙不增加步数。Collected all three stars from the start and reached the exit with matching position, star count, moves and completion; a wall move adds none.
- 无效导入被拒绝:错误版本号、墙内坐标、重复星星与超大文件都不改变当前盘面。Invalid imports rejected: a wrong schema version, a wall coordinate, duplicate stars and an oversized file each leave the board unchanged.
- 存储受限(localStorage 被拒)时仍可完整游玩,并给出下载/读入文件的替代路径。Play stays complete when browser storage is denied, with the download/import route offered instead.
- 键盘与屏幕按钮走同一条移动逻辑;暂停时两者都不生效;Tab 能进出棋盘与控件。Keyboard and on-screen buttons share one move path; neither moves while paused; Tab enters and leaves the board and the controls.
- 320px 窄屏、触屏点按、明暗两主题、中英切换都过;改窗口尺寸与换棋盘宽度不丢状态。A 320px narrow screen, taps, both themes and both languages pass; resizing the window or switching board width keeps the state.
- 关掉脚本后六个阶段仍读得完整 —— 教学文案是构建期内嵌的静态 HTML,不靠 JS 注入。With scripting off the six stages stay fully readable — the teaching text is static HTML inlined at build time, not injected by JS.
- 下载包:独立工具解压、逐文件与源字节比对、CRC 校验、离线直接打开可玩。The package: extracted with an independent tool, compared byte-for-byte against its sources, CRC-checked, and opened offline without a server.
这些结论不覆盖:其它浏览器与真机设备、其它站点协议下的存储策略、长时间游玩的手感,以及任何引擎或 AI 产品的能力评价。本站不跑分,也不给通过率或正确率。Not covered: other browsers and real devices, storage policy on other origins or protocols, how the feel holds up over a long session, and any judgement of an engine or an AI product. This site runs no benchmarks and publishes no pass rate or accuracy figure.
这个样例不说的What this sample does not claim
- 不证明任何引擎或 AI 产品的好坏,只说明这份 7×5 样例自己的代码行为It proves nothing about an engine or an AI product; it describes this 7×5 sample’s own code behaviour
- 不给通过率、正确率或「一次就写对」的数字No pass rate, accuracy or first-try figure
- 下载包不另行授予复制、改编、再分发或商业使用许可(见上面台账与法律页第 1 节)The download grants no separate licence to copy, adapt, redistribute or use commercially (see the ledger above and section 1 of the legal page)
← 返回学习路径← Back to the learning path · 作品库the showcase · 实战流程the build order · 首页Home