# 崩坏童话：蜜糖村（网页版）

> v2.0 · 纯单机网页像素游戏 · 无存档 / 无后端 / 无 localStorage · 浏览器打开即玩 · 完整流程约 25–35 分钟，含 4 个结局。

一个看起来百分之百治愈的像素童话村庄，实际是一场情绪疗程的沉浸幻境。玩家越"幸福"，世界越饱和、越甜、越不对劲；通往真相的路，恰恰是那些系统禁止的悲伤。

技术栈：**Phaser 3 + TypeScript + Vite**。逻辑分辨率 320×180，整数倍放大居中，`pixelArt`。全部像素素材与地图为本项目自制（见下文制作流程），无任何外部资产、外部音频或字体文件。

---

## 一、启动方式

```bash
npm install        # 安装依赖（phaser / vite / typescript）
npm run build      # 类型检查 + 产出纯静态 dist/
npm run preview    # 本地起服，浏览器打开提示的地址（默认 http://localhost:4173）游玩
# 开发热重载：
npm run dev
```

打开页面 → 输入名字（留空默认「小满」）→ 点「开始疗程」或回车 → 进入 Day 1 小屋。
音频在首次点击 / 按键后开始（浏览器自动播放策略）。

---

## 二、按键

| 操作 | 键 |
|---|---|
| 移动 | `WASD` 或 方向键（96 像素/秒，四向动画 + 待机帧） |
| 交互 / 推进对话 | `E`（靠近可交互对象 ≤24 像素出现「按 E」提示）；对话也可鼠标点击推进 |
| 对话选项 | `W`/`S` 或 上/下 选择，`E` 确定（温柔 / 迟疑 / 否定三类，影响幸福与觉知） |
| 睡觉过日 | 走到床边按 `E` |
| Debug 面板 | 反引号键 `` ` `` 开关 |

核心玩法：每日「晨起 → 公告板接任务 → 完成任务 → 黄昏钟声 → 回屋睡觉 → 梦境过场 → 次日」。共 7 天、15 个任务、9 处线索，Day 7 庆典按状态走向四结局之一。

HUD 只有左上角一朵**向日葵表盘**：12 片花瓣按幸福值点亮，满格后花心浮现过熟的黑籽——**全程不显示任何数字**。幸福越高，世界饱和度越高、BGM 越变调变闷、台词越出错、NPC 表情从微笑滑向崩坏。

---

## 三、Debug 面板（`` ` `` 开关，服务验收）

默认关闭、无任何 UI 痕迹，不影响正常游玩。开启后（页面右上角）可：

- **直接设置幸福值**：10 / 40 / 70 / 90 / 100 —— 对应侵蚀阶段 S0–S4，可肉眼/肉耳验证饱和度、晕影、NPC 表情档、文本腐蚀密度、BGM 变调与低通。
- **直接设置觉知值**：0 / 40 / 70 / 100。
- **设置当前日**：1–7（同步激活当日任务、线索时段门槛）。
- **传送到任意场景**：home / plaza / bakery / grocery / clinic / lake / field / well / fog（白色层由结局/梦境使用）。
- **置齐全部线索**：一次点亮 9 处线索。
- **强制触发四个结局**：E1 糖衣 / E2 回收 / E3 苏醒 / E4 静默。

E3 病历会显示你输入的名字、编号 `PT-07` 与**真实游玩时长**（读运行计时），最后一帧主角头像的微笑消失、换成一张疲惫而真实的脸。

---

## 四、素材与地图制作流程（全部原创，无外部资产）

一键重建全部素材与地图：

```bash
npm run assets      # = bash tools/build_assets.sh
```

该脚本按顺序执行三步（需本机已装 Aseprite 与 Tiled）：

### 1. 像素美术 —— Aseprite（`tools/gen_all.lua`）
用 Aseprite 命令行批处理 + Lua API **逐像素绘制**并导出 PNG（`public/assets/sprites/`）：

```bash
aseprite -b --script-param outdir=public/assets/sprites --script tools/gen_all.lua
```

产出（16×16 瓦片 / 16×24 角色，糖果色板 + 白色层独立灰白色板，无抗锯齿、无描边渐变）：
- `tileset.png` —— 72 瓦片（草地/石板/湖水/花丛/莓果/树/房屋/室内家具/井/雾/白色层墙地/装饰，≥64）。
- `player.png` —— 主角 16×24，4 朝向 × 4 帧行走（每朝向第 1 帧兼待机）。
- `portraits.png` —— 主角对话头像（永恒微笑）+ E3 专用「真实的脸」。
- `npc_*.png` ×6 —— 阿福/圆圆/大宝/咪咪/芙医生/龟爷爷，各 3 档表情（smile/flat/off），`off` 与 `smile` 仅差 1–2 像素（一只眼睛低 1 像素、嘴角多 1 像素），不画成鬼脸。
- `birds.png` —— 双子鸟 2 帧张嘴；`extras.png` —— 群演 ×5 各 2 帧循环；`sparrow.png` —— E3 窗外的真麻雀。

预览用蒙太奇脚本：`tools/montage.lua`（放大拼图，仅供肉眼校对，不参与打包）。

### 2. 地图 —— Tiled（`tools/gen_maps.mjs` → `.tmx` → Tiled 导出 `.json`）
Node 脚本生成 10 张地图的 Tiled 源文件（`tools/tmx/*.tmx`，内嵌 tileset），再用 Tiled 命令行导出为 Phaser 可读 JSON（`public/assets/maps/`）：

```bash
node tools/gen_maps.mjs
tiled --export-map tools/tmx/plaza.tmx public/assets/maps/plaza.json   # 每张地图一次
```

统一三层结构：`ground` / `obstacles`（有瓦片即碰撞）/ `objects`（`spawn`、`door`〔含 target/dest〕、`npc`、`interact`〔含 kind〕）。所有室外场景经村广场互通，门与出入口在成对地图两侧对齐。10 张：小满小屋 12×8、村广场 30×20、面包房 15×10、杂货店 15×10、诊所 12×8、湖畔 24×16、花田 20×14、古井空地 14×10、雾墙边界 20×8、白色层 20×14（走廊+病房）。

### 3. 音频 —— Web Audio 程序合成（`src/core/Audio.ts`）
无任何音频文件。8 小节 8-bit 治愈循环（方波主旋律 + 三角波低音）渲染进 `AudioBuffer` 循环播放，`playbackRate` 与 `BiquadFilter` 低通由侵蚀阶段实时驱动（S2 起变慢，S3 加 8kHz 低通，S4 到 0.84 倍 + 4kHz 低通 + 鸟鸣声部静音而双子鸟仍张嘴）。另有 4 个程序合成音效：对话哔、任务完成叮、黄昏钟声、E2 心电滴声。Day 6「保持微笑 60 秒」任务 40–60 秒所有声音渐隐至零（突然的安静）。

---

## 五、代码结构

```
src/
  main.ts                 Phaser 配置、整数缩放、音频阶段联动
  core/
    Director.ts           CorruptionDirector 单例：幸福/觉知/日/任务/线索/侵蚀阶段的唯一真源 + 侵蚀矩阵 + 文本腐蚀
    Audio.ts              程序合成 BGM/SFX
    quests.ts             公告、NPC 对话装配、15 任务与 9 线索逻辑、结局判定
  data/content.ts         全部逐字台词/数值/表格（公告、错字表、任务、线索、结局）
  scenes/
    BootScene / TitleScene / WorldScene（通用地图场景）/ UIScene（表盘·对话·Debug·梦境·雨·欢乐庆典）/ EndingScene
tools/
    gen_all.lua           Aseprite 绘制脚本
    gen_maps.mjs          Tiled .tmx 生成脚本
    build_assets.sh       一键重建（Aseprite + Tiled）
```

`CorruptionDirector` 是全部状态与视听参数的唯一真源；饱和度与晕影用 Phaser 相机 postFX（ColorMatrix / Vignette），S4 负片闪帧用 ColorMatrix negative 单帧切换。

---

## 六、明确不做（同 PRD §15）

战斗、背包/合成 UI、存档读档、成就、多人、移动端触控、配音、真实音频文件、二周目专属内容、天气系统（雨仅为 Day 6 一次脚本演出）。
