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

> 纯单机网页游戏 · Phaser 3 + TypeScript + Vite · 无后端、无存档、无 localStorage，浏览器打开即玩。

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

## 启动方式

需要 Node.js 18+。

```bash
npm install        # 安装依赖
npm run dev        # 开发模式（http://localhost:5173）
npm run build      # 产出纯静态 dist/
npm run preview    # 本地预览构建产物（http://localhost:4173）
```

`npm run build` 产出纯静态 `dist/`，可直接用任意静态服务器托管；`npm run preview` 本地游玩。

## 按键操作

| 按键 | 功能 |
|---|---|
| `W` `A` `S` `D` / 方向键 | 移动（四向动画 + 待机帧） |
| `E` / `空格` / `回车` | 交互 / 推进对话 / 选择 |
| `1` `2` `3` | 对话选项（温柔 / 迟疑 / 否定） |
| `` ` ``（反引号） | 开关 Debug 面板 |

## Debug 面板（服务验收）

运行中按反引号键 `` ` `` 开关。默认关闭，关闭时无任何 UI 痕迹，不影响正常游玩。

功能：
- 直接设置幸福值（10 / 40 / 70 / 90 / 100，分别对应 S0/S1/S2/S3/S4）
- 切换觉知值（0 / 50 / 100）
- 切换当前日（1–7 循环）
- 置齐全部线索（C1–C9）
- 传送到任意场景（小屋/广场/面包房/杂货店/诊所/湖畔/花田/古井/雾墙）
- 强制触发四个结局之一（E1 糖衣 / E2 回收 / E3 苏醒 / E4 静默）

## 游玩说明

- 开局输入名字（留空默认「小满」）。
- 七日流程：晨起 → 公告板接任务 → 完成任务/自由活动 → 黄昏钟声 → 回屋睡觉 → 梦境过场 → 次日。
- 完整流程约 25–35 分钟，含 4 个结局。
- 幸福值以左上角向日葵表盘表示（12 片花瓣），全程不显示数字。满格后花心浮现黑籽。

## 技术架构（PRD §12）

- **Phaser 3 + TypeScript + Vite**。逻辑分辨率 320×180，整数倍放大居中，`pixelArt: true`，禁用纹理平滑。
- 场景：`BootScene`（加载）→ `TitleScene`（标题/输入名字）→ 各地图 Scene + 常驻 `UIScene`（对话框、向日葵表盘、提示）→ `EndingScene`；另 `DebugScene`。
- `CorruptionDirector`（`src/systems/CorruptionDirector.ts`）：普通 TS 单例 + 事件发射器，持有幸福/觉知/日期/任务标记/线索集合/侵蚀阶段，是全部状态与视听参数的**唯一真源**。
- 饱和度与晕影用 Phaser 相机 postFX（`SaturationPostFX`），负片闪帧用单帧白色覆盖切换。
- BGM 与音效按 §6.6 用 Web Audio 程序合成（方波主旋律 + 三角波低音 8 小节循环），playbackRate 与 BiquadFilter 低通由 `CorruptionDirector` 驱动。**无外部音频文件**。
- 无 localStorage、无外部网络请求、无外部音频/字体文件。

## 素材与地图制作流程（全部本项目内自制，无外部资产）

### 像素素材（Aseprite）

所有像素素材由 Aseprite 命令行 + Lua 脚本程序化绘制，脚本位于 `tools/`：

| 脚本 | 产物 | 说明 |
|---|---|---|
| `tools/gen_tileset.lua` | `assets/tilesets/tileset.png`（128×128，64 个 16×16 瓦片） | 草地/石板路/湖水/花丛/莓果丛/树/房屋墙顶门/室内地板/家具（床/柜台/烤炉/货架/桌椅）/井/雾/白色层墙地等 |
| `tools/gen_player.lua` | `assets/sprites/player.png`（64×96） | 主角 16×24/帧，4 朝向 × 4 帧行走（walk-down/up/left/right），第 1 帧兼待机 |
| `tools/gen_portraits.lua` | `assets/sprites/portraits.png`（624×24） | 对话头像：主角微笑 + E3「真实的脸」；7 个具名 NPC 各 3 档表情（smile/flat/off）；双子鸟；5 个群演 |
| `tools/gen_npc.lua` | `assets/sprites/npc.png`（400×24） | NPC 场景立绘 16×24 ×3 档；双子鸟 2 帧张嘴动画；5 个群演 |

重新生成素材（需本机 Aseprite，路径 `/Applications/Aseprite.app/Contents/MacOS/aseprite`）：

```bash
"/Applications/Aseprite.app/Contents/MacOS/aseprite" -b --script tools/gen_tileset.lua
"/Applications/Aseprite.app/Contents/MacOS/aseprite" -b --script tools/gen_player.lua
"/Applications/Aseprite.app/Contents/MacOS/aseprite" -b --script tools/gen_portraits.lua
"/Applications/Aseprite.app/Contents/MacOS/aseprite" -b --script tools/gen_npc.lua
```

### 地图（Tiled Map Editor）

10 个场景地图为标准 Tiled JSON 格式（`assets/maps/*.json`），由 `tools/gen_maps.cjs` 程序化生成；瓦片集描述符由 `tools/gen_tileset_json.cjs` 生成（`assets/tilesets/tileset.json`，含 `collides` 属性）。

统一结构：`ground` / `obstacles`（`collides=true`）/ `objects`（`spawn`、NPC 点位、`door`、交互点）。

| 场景 | 尺寸（瓦片） | 要点 |
|---|---|---|
| 小满小屋（室内） | 12×8 | 床、床头日历（C1） |
| 村广场 | 30×20 | 公告板、花坛、双子鸟树、庆典场地；枢纽 |
| 面包房（室内） | 15×10 | 柜台、烤炉、配方纸（C2） |
| 杂货店（室内） | 15×10 | 货架（C5） |
| 诊所（室内） | 12×8 | 芙医生、桌上表格（C8） |
| 湖畔 | 24×16 | 长椅（龟爷爷）、野餐布、湖面倒影 |
| 花田 | 20×14 | 莓果丛（T6）、浇花点 |
| 古井空地 | 14×10 | 古井（C7） |
| 雾墙边界 | 20×8 | 村庄尽头的雾，E3 入口 |
| 白色层 | 20×14 | 走廊 + 病房，去饱和白灰色板 |

重新生成地图（需本机 Tiled，路径 `/Applications/Tiled.app/Contents/MacOS/tiled`）：

```bash
node tools/gen_tileset_json.cjs
node tools/gen_maps.cjs
# 可选：用 Tiled 验证导出
"/Applications/Tiled.app/Contents/MacOS/tiled" --export-map assets/maps/plaza.json /tmp/plaza_verify.json
```

## 目录结构

```
.
├── index.html
├── package.json
├── tsconfig.json
├── vite.config.ts
├── assets/
│   ├── maps/            # 10 个 Tiled JSON 地图
│   ├── tilesets/        # tileset.png + tileset.json
│   └── sprites/         # player.png / npc.png / portraits.png
├── tools/               # Aseprite Lua + Node 生成脚本
└── src/
    ├── main.ts          # Phaser 配置入口
    ├── data/            # gamedata.ts（全部写死的台词/数值/表格）、mapsMeta.ts
    ├── systems/         # CorruptionDirector / AudioEngine / TextCorruptor / StoryDirector
    ├── entities/        # Player
    └── scenes/          # BootScene / TitleScene / UIScene / MapScene / 10 地图 / EndingScene / DebugScene
```
