# crow_pitcher **Repository Path**: jasydong/crow_pitcher ## Basic Information - **Project Name**: crow_pitcher - **Description**: 乌鸦喝水的小游戏 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-30 - **Last Updated**: 2026-06-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 🐦 乌鸦喝水 · Crow & Pitcher > 改编自伊索寓言的 Web 小游戏。烈日下,一只口渴的乌鸦找到一瓶水,但水位太低、瓶口太窄够不着——你来帮它投石子升高水位。 一个纯前端、单文件、零依赖的 Canvas 小游戏,双击 HTML 即可在浏览器中运行。 --- ## 📦 运行方式 无需安装任何依赖,无需构建步骤。 **方式一:直接打开** 双击 `index.html`,用现代浏览器(Chrome / Edge / Firefox / Safari)打开即可。 **方式二:本地服务器(可选)** 若想获得更标准的开发体验,可用任意静态服务器: ```bash # Python python -m http.server 8000 # Node npx serve . ``` 然后访问 `http://localhost:8000`。 > 💡 音效基于 WebAudio,部分浏览器要求页面有用户交互后才会发声——点击「开始游戏」按钮即可正常播放。 --- ## 🎮 玩法说明 | 操作 | 效果 | |------|------| | 移动鼠标 / 手指 | 控制空中乌鸦,瞄准瓶口上方投石位置 | | 点击 / 触屏点击 | 乌鸦松开嘴里的石子,石子沿抛物线落入瓶中 | | 🔊 按钮 | 切换静音 | ### 胜负条件 - 🏆 **胜利**:水位升至瓶口金色目标线,乌鸦喝到水。 - 💀 **失败**: - **口渴度**耗尽(左上角进度条归零),或 - 12 颗石子全部用完仍未达标。 ### 瞄准提示 瓶口上方有一个落点指示圆点: - 🟢 **绿色** = 石子能落入窄颈,水位上升 - 🔴 **红色** = 偏离瓶口,石子会弹飞(消耗一颗,不升水位) --- ## ✨ 特性 - **纯单文件**:所有 HTML / CSS / JS 集中在 `index.html`,无外部库、无图片资源、无音效文件。 - **手绘 Canvas 场景**:渐变天空、飘动云朵、太阳光晕、草地与地面碎石,全部矢量绘制。 - **物理模拟**:石子抛物线下落、旋转、运动模糊残影;命中瓶口边缘会弹飞并扬起灰尘。 - **水的表现**:双正弦叠加的水面波浪、命中时的水花粒子、扩散涟漪、屏幕白闪与轻微震动反馈。 - **玻璃质感瓶子**:半透明填充 + 高光条纹 + 轮廓描边 + 窄颈物理判定。 - **动态乌鸦**:翅膀拍打动画、眼神朝向跟随、嘴里叼石状态。 - **WebAudio 合成音效**:投石、水花、碰撞、胜负音全部由代码实时合成,无音频文件。 - **响应式 + 触屏支持**:自适应任意视口尺寸,支持鼠标与触屏,DPR 高清渲染。 - **完整游戏流程**:开始界面 → 游玩 → 胜负结算 → 一键重玩。 --- ## 🛠 技术栈 - HTML5 Canvas 2D - 原生 JavaScript(无框架、无构建工具) - CSS3(Flexbox、渐变、backdrop-filter、动画) - Web Audio API(程序化合成音效) --- ## 📁 项目结构 ``` crow_pitcher/ ├── index.html # 游戏全部代码(HTML + CSS + JS) └── README.md # 本文档 ``` --- ## 🎚 难度调参 所有可调参数集中在 `index.html` 的 `game` 对象与 `startGame()` / `layout()` 函数中: | 参数 | 位置 | 默认值 | 说明 | |------|------|--------|------| | `stonesLeft` | `game` 对象 / `startGame()` | `12` | 初始石子数量 | | `thirstRate` | `game` 对象 | `0.018` | 口渴度每秒下降速率(越大越难) | | `thirst` | `startGame()` | `1.0` | 初始口渴度缓冲(1=满) | | `computeRaise()` | 函数 | `stoneR * 2.3` | 单颗石子升水量(越大越容易赢) | | `waterTop` 初始值 | `layout()` | `y - h*0.30` | 初始水位(越低越难) | | `targetY` | `layout()` | `rimY + h*0.10` | 目标水位线(越靠近瓶口越难) | 例如想要更难的挑战:把 `stonesLeft` 改为 `9`,或把 `thirstRate` 调到 `0.025`。 --- ## 🧩 代码结构概览 ```text ┌─ 布局与状态 layout() / game 对象 / resize() ├─ 输入处理 mousemove / mousedown / touch 事件 ├─ 实体生成 spawnStone() / spawnSplash() / spawnRipple() ├─ 主循环 loop() → update() + render() │ ├─ 物理 石子下落、入瓶判定、水位上升、胜负检测 │ └─ 渲染 天空 / 云 / 太阳 / 地面 / 瓶子 / 水 / 石子 / 乌鸦 / 粒子 ├─ HUD updateHUD()(口渴条、石子计数、命中数) ├─ 游戏流程 startGame() / endGame() / showResult() ├─ 音效 ensureAudio() / sfx()(WebAudio 合成) └─ 工具 clamp() ``` --- ## 🐛 已知设计要点 开发过程中修复的关键平衡性问题(供后续调参参考): 1. **水位上升量**:每颗石子需升约 16–26px,约 9–11 颗命中可胜;过小会导致必输局。 2. **负局判定**:需同时满足「库存为 0」且「无飞行中的石子」才会判负,避免乌鸦自动叼石造成逻辑死锁。 --- ## 📜 寓言寓意 > 遇到困难动脑筋,办法总比困难多。 乌鸦喝水的故事告诉我们:面对看似无解的困境,冷静思考、善用身边资源,往往能找到出路。 --- ## 📄 许可 本项目用于学习与娱乐,可自由使用与修改。