Add README documenting controls, gameplay and how the requirements are met
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# 平台闯关 · Pixel Platformer
|
||||
|
||||
一个用 **Godot 4.7** 制作的 2D 像素风平台跳跃游戏。
|
||||
|
||||
---
|
||||
|
||||
## 运行方式
|
||||
|
||||
1. 用 Godot 4.7 打开本目录(选择 `project.godot`)
|
||||
2. 按 `F5` 运行
|
||||
|
||||
主场景:`scenes/main.tscn`
|
||||
|
||||
---
|
||||
|
||||
## 操作
|
||||
|
||||
| 按键 | 作用 |
|
||||
|---|---|
|
||||
| `A` / `D` | 左右移动 |
|
||||
| `空格` | 跳跃(单段,空中不能二段跳) |
|
||||
| `S` 按住 | 显示投掷抛物线预览 |
|
||||
| `S` 松开 | 投出钥匙 |
|
||||
| `W` | 传送到扔出去的钥匙位置,并把它捡回来 |
|
||||
| `Z` | 消耗一个回血道具:回一颗心 + 5 秒无敌盾 |
|
||||
| `F` | 切换飞行(**仅编辑器 / 调试版可用**,见下方说明) |
|
||||
| `R` / `Enter` | 死亡后重新开始 |
|
||||
|
||||
---
|
||||
|
||||
## 玩法
|
||||
|
||||
- **生命值**:共 3 颗心。碰到尖刺扣 1 颗心并被打回出生点,生命归零后进入死亡界面。
|
||||
- **收集物**:地图上有 3 个金色小球,走过去自动拾取,变成"回血道具"。
|
||||
- **回血**:按 `Z` 消耗一个道具,回一颗心并获得 5 秒无敌盾。
|
||||
- **钥匙**:走过去自动捡起;按住 `S` 时实时显示抛物线轨迹和落点;松开投出。按 `W` 可以直接瞬移到钥匙处并收回它。
|
||||
- **弹簧**:踩上去弹起约 57px(普通跳跃约 20px)。
|
||||
- **隐藏通道**:关卡里有几处"看着是石壁、其实能直接穿过去"的暗道。
|
||||
|
||||
---
|
||||
|
||||
## 对应作业要求
|
||||
|
||||
### ① 玩家移动控制代码
|
||||
|
||||
`scripts/player_controller.gd`
|
||||
|
||||
- 节点类型 `CharacterBody2D`,每帧结束调用 `move_and_slide()`
|
||||
- **重力**:`get_gravity()`,只在 `not is_on_floor()` 时累加到 `velocity.y`
|
||||
- **水平移动**:`Input.get_axis("move_left", "move_right")` 取方向,用 `move_toward()` 做加速 / 减速插值,手感比直接赋值柔和
|
||||
- **跳跃**:`Input.is_action_just_pressed("jump")` 配合 `is_on_floor()`,因此**只有踩在地面上才能起跳**,天然不会二段跳
|
||||
- **朝向**:根据 `velocity.x` 的正负翻转 `Sprite2D.flip_h`
|
||||
|
||||
### ② 瓦片地图
|
||||
|
||||
- 用了 **3 层 `TileMapLayer`**:
|
||||
- `TerrainBase` — 主体地形
|
||||
- `TerrainDetailsA` / `TerrainDetailsB` — 前景装饰(z_index 1 / 2)
|
||||
- `TileSet` 使用 18×18 的图集(`assets/game/tilesets/`),逐个图块配置了**物理碰撞多边形**;草地单向平台用 `one_way` 实现
|
||||
- 隐藏通道的做法:在地形层上用 `erase_cell()` 把指定格子挖空,再在那个位置盖一张**完全没有碰撞的 `Sprite2D`**(贴图借用旁边墙块),于是画面上仍然是完整石壁、人却能穿过去
|
||||
|
||||
### ③ 碰撞体的区别与使用场景
|
||||
|
||||
项目里四种碰撞方式都用到了:
|
||||
|
||||
| 类型 | 用在哪 | 为什么选它 |
|
||||
|---|---|---|
|
||||
| `CharacterBody2D` | 玩家 | 需要主动移动、被地形阻挡、能踩在地面和箱子上 |
|
||||
| `StaticBody2D` | 木箱、弹簧、树干、路牌、传送箱 | 不动的实体障碍,玩家能站上去、撞得到 |
|
||||
| `Area2D` | 金币、尖刺、弹簧触发区、钥匙 | 只需要"碰到就触发",**不产生物理推挤**,所以能穿过去 |
|
||||
| `TileMapLayer` 物理层 | 大面积地面 | 重复地形太多,用瓦片自带碰撞最省事,不用摆几百个 CollisionShape2D |
|
||||
|
||||
**碰撞层约定**:
|
||||
|
||||
| 层号 | 用途 |
|
||||
|---|---|
|
||||
| 1 | 世界实体(地形、木箱、树干、路牌、弹簧、传送箱) |
|
||||
| 2 | 玩家 |
|
||||
| 4 | 危险物(尖刺) |
|
||||
| 8 | 交互触发区(弹簧、传送箱的检测区) |
|
||||
| 16 | 收集物(金币、宝石、钥匙) |
|
||||
|
||||
玩家的 `collision_mask` 只有 layer 1,所以只和"世界实体"发生物理碰撞,不会被金币、尖刺挡住。
|
||||
|
||||
### ④ 角色技能
|
||||
|
||||
**技能 A —— 投掷钥匙 + 传送**(`scripts/key.gd`)
|
||||
|
||||
- 走过去自动捡起钥匙
|
||||
- 按住 `S`:用**与玩家完全相同的碰撞掩码**做抛物线模拟,实时画出轨迹和落点标记
|
||||
- 松开 `S`:把钥匙按同样的初速度扔出去
|
||||
- 按 `W`:瞬移到钥匙所在位置并收回它
|
||||
- 因为预测和实际飞行调用的是**同一个 `simulate_trajectory()` 函数**,"弧线显示能落到的地方"就等于"钥匙真正落到的地方"(实测偏差 0.000 px)
|
||||
|
||||
**技能 B —— 飞行**(`player_controller.gd`)
|
||||
|
||||
- 按 `F` 切换飞行状态,`W` / `S` 控制升降,`A` / `D` 平移
|
||||
- 为了不影响正式玩法的难度平衡,**只在编辑器 / 调试版生效**(`OS.is_debug_build()`),导出正式版按键无效
|
||||
- 如果想在导出版里也开放,把 `fly_available()` 里的 `OS.is_debug_build()` 去掉即可:
|
||||
```gdscript
|
||||
func fly_available() -> bool:
|
||||
return debug_fly
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
├─ project.godot 引擎配置(输入映射、窗口、渲染)
|
||||
├─ scripts/
|
||||
│ ├─ player_controller.gd 玩家:移动、跳跃、生命值、投掷、飞行
|
||||
│ ├─ key.gd 钥匙:拾取 / 飞行 / 落地、轨迹模拟
|
||||
│ ├─ spring.gd 弹簧:踩上去弹起
|
||||
│ ├─ hazard.gd 危险物:碰到扣血
|
||||
│ ├─ collectible.gd 收集物:走过去拾取
|
||||
│ ├─ hidden_passages.gd 隐藏通道:挖空地砖 + 盖假墙
|
||||
│ ├─ hud.gd 左上角:心 + 道具数 + 护盾倒计时
|
||||
│ └─ death_screen.gd 死亡界面:渐黑 + 重新开始
|
||||
├─ scenes/
|
||||
│ ├─ main.tscn 主场景(关卡)
|
||||
│ ├─ player.tscn 玩家
|
||||
│ ├─ hud.tscn 状态显示
|
||||
│ ├─ death_screen.tscn 死亡界面
|
||||
│ └─ prefabs/ 预制件:金币、钥匙、弹簧、尖刺、木箱、树、路牌
|
||||
└─ assets/
|
||||
├─ game/ 实际使用的素材
|
||||
└─ kenney/ Kenney 原始素材库
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 素材来源
|
||||
|
||||
- 图形素材:**Kenney — Pixel Platformer (1.2)**
|
||||
- 授权:**CC0**(可商用、可修改,无需署名)
|
||||
- 来源:https://kenney.nl
|
||||
- 详见 `LICENSE_KENNEY.txt`
|
||||
|
||||
---
|
||||
|
||||
## 版本控制
|
||||
|
||||
本项目使用 git 进行版本管理。
|
||||
Reference in New Issue
Block a user