Hide the debug fly and level skip behind a 房★主★有★神★器★ easter-egg panel
cheat_panel replaces the level_skip autoload: a single small button in the top-right opens a panel holding the fly toggle and the level jump buttons, so nothing that looks like leftover debug UI is on screen. The fly is no longer gated behind OS.is_debug_build, so the easter egg works in exported builds too, and the 1/2/3 shortcuts only fire while the panel is open so they cannot be hit by accident. Space stays unbound and no gameplay content was touched.
This commit is contained in:
@@ -18,12 +18,12 @@
|
||||
| 按键 | 作用 |
|
||||
|---|---|
|
||||
| `A` / `D` | 左右移动 |
|
||||
| `空格` | 跳跃(单段,空中不能二段跳) |
|
||||
| `空格` | (当前已停用,输入映射里的 `jump` 键位为空) |
|
||||
| `S` 按住 | 显示投掷抛物线预览 |
|
||||
| `S` 松开 | 投出钥匙 |
|
||||
| `W` | 传送到扔出去的钥匙位置,并把它捡回来 |
|
||||
| `Z` | 消耗一个回血道具:回一颗心 + 5 秒无敌盾 |
|
||||
| `F` | 切换飞行(**仅编辑器 / 调试版可用**,见下方说明) |
|
||||
| `F` | 切换飞行(**隐藏技能**,藏在右上角「房★主★有★神★器★」面板里,见下方说明) |
|
||||
| `R` / `Enter` | 死亡后重新开始 |
|
||||
|
||||
---
|
||||
@@ -49,6 +49,9 @@
|
||||
- **重力**:`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()`,因此**只有踩在地面上才能起跳**,天然不会二段跳
|
||||
- ⚠️ 目前输入映射里的 `jump` **没有绑定任何按键**(空格被空置了),所以这段代码暂时不会触发。
|
||||
想恢复:`项目 → 项目设置 → 输入映射 → jump → 添加按键 → 空格`,或者把 `project.godot` 里
|
||||
`jump` 的 `"events"` 改回 `[Object(InputEventKey, ... "physical_keycode":32 ...)]`。
|
||||
- **朝向**:根据 `velocity.x` 的正负翻转 `Sprite2D.flip_h`
|
||||
|
||||
### ② 瓦片地图
|
||||
@@ -92,10 +95,12 @@
|
||||
- 按 `W`:瞬移到钥匙所在位置并收回它
|
||||
- 因为预测和实际飞行调用的是**同一个 `simulate_trajectory()` 函数**,"弧线显示能落到的地方"就等于"钥匙真正落到的地方"(实测偏差 0.000 px)
|
||||
|
||||
**技能 B —— 飞行**(`player_controller.gd`)
|
||||
**技能 B —— 飞行(隐藏技能)**(`player_controller.gd`)
|
||||
|
||||
- 按 `F` 切换飞行状态,`W` / `S` 控制升降,`A` / `D` 平移
|
||||
- 为了不影响正式玩法的难度平衡,**只在编辑器 / 调试版生效**(`OS.is_debug_build()`),导出正式版按键无效
|
||||
- 按 `F` 切换飞行状态,方向键 ↑ / ↓ 控制升降(`S` 也可以下降),`A` / `D` 平移
|
||||
- 屏幕上不会有任何提示,它是藏在右上角 **「房★主★有★神★器★」** 按钮里的彩蛋:
|
||||
点开面板就能看到飞行开关和跳关按钮(键盘 `1` / `2` / `3` 跳关,`Esc` 关闭面板)
|
||||
- 这个面板由自动加载单例 `scripts/cheat_panel.gd` 提供,**三个关卡都有,正式版里也能用**
|
||||
- 如果想在导出版里也开放,把 `fly_available()` 里的 `OS.is_debug_build()` 去掉即可:
|
||||
```gdscript
|
||||
func fly_available() -> bool:
|
||||
|
||||
+2
-3
@@ -17,7 +17,7 @@ config/icon="res://icon.svg"
|
||||
|
||||
[autoload]
|
||||
|
||||
LevelSkip="*res://scenes/level_skip.tscn"
|
||||
CheatPanel="*res://scenes/cheat_panel.tscn"
|
||||
|
||||
[display]
|
||||
|
||||
@@ -45,8 +45,7 @@ move_right={
|
||||
}
|
||||
jump={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
"events": []
|
||||
}
|
||||
warp_to_key={
|
||||
"deadzone": 0.2,
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
[gd_scene load_steps=4 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/cheat_panel.gd" id="1_cheat"]
|
||||
|
||||
[sub_resource type="SystemFont" id="SystemFont_cjk"]
|
||||
font_names = PackedStringArray("Microsoft YaHei UI", "Microsoft YaHei", "SimHei", "Noto Sans CJK SC", "sans-serif")
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_panel"]
|
||||
content_margin_left = 10.0
|
||||
content_margin_top = 10.0
|
||||
content_margin_right = 10.0
|
||||
content_margin_bottom = 10.0
|
||||
bg_color = Color(0.07, 0.08, 0.13, 0.92)
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color(1, 0.82, 0.35, 0.85)
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
|
||||
[node name="CheatPanel" type="CanvasLayer"]
|
||||
process_mode = 3
|
||||
layer = 40
|
||||
script = ExtResource("1_cheat")
|
||||
|
||||
[node name="OpenButton" type="Button" parent="."]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -178.0
|
||||
offset_top = 6.0
|
||||
offset_right = -6.0
|
||||
offset_bottom = 28.0
|
||||
theme_override_colors/font_color = Color(1, 0.88, 0.5, 1)
|
||||
theme_override_fonts/font = SubResource("SystemFont_cjk")
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "房★主★有★神★器★"
|
||||
|
||||
[node name="Panel" type="PanelContainer" parent="."]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -178.0
|
||||
offset_top = 32.0
|
||||
offset_right = -6.0
|
||||
offset_bottom = 168.0
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_panel")
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="Panel"]
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="Title" type="Label" parent="Panel/VBox"]
|
||||
theme_override_colors/font_color = Color(1, 0.85, 0.4, 1)
|
||||
theme_override_fonts/font = SubResource("SystemFont_cjk")
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "神 器"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FlyButton" type="Button" parent="Panel/VBox"]
|
||||
theme_override_fonts/font = SubResource("SystemFont_cjk")
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "飞行:关(F)"
|
||||
|
||||
[node name="Row" type="HBoxContainer" parent="Panel/VBox"]
|
||||
theme_override_constants/separation = 5
|
||||
|
||||
[node name="JumpHint" type="Label" parent="Panel/VBox/Row"]
|
||||
theme_override_fonts/font = SubResource("SystemFont_cjk")
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "跳关"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CloseButton" type="Button" parent="Panel/VBox"]
|
||||
theme_override_fonts/font = SubResource("SystemFont_cjk")
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "关闭(Esc)"
|
||||
+1
-1
@@ -226,7 +226,7 @@ position = Vector2(288, 37)
|
||||
|
||||
[node name="CoinGoldRound_01" parent="Level/PrefabInstances/Collectibles" unique_id=926105584 instance=ExtResource("17_16ffm")]
|
||||
z_index = 5
|
||||
position = Vector2(447, 130)
|
||||
position = Vector2(432, 127)
|
||||
|
||||
[node name="CoinGoldRound_02" parent="Level/PrefabInstances/Collectibles" unique_id=1674416025 instance=ExtResource("17_16ffm")]
|
||||
z_index = 5
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
[gd_scene load_steps=3 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/level_skip.gd" id="1_skip"]
|
||||
|
||||
[sub_resource type="SystemFont" id="SystemFont_cjk"]
|
||||
font_names = PackedStringArray("Microsoft YaHei UI", "Microsoft YaHei", "SimHei", "Noto Sans CJK SC", "sans-serif")
|
||||
|
||||
[node name="LevelSkip" type="CanvasLayer"]
|
||||
process_mode = 3
|
||||
layer = 30
|
||||
script = ExtResource("1_skip")
|
||||
|
||||
[node name="Buttons" type="HBoxContainer" parent="."]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -130.0
|
||||
offset_top = 6.0
|
||||
offset_right = -6.0
|
||||
offset_bottom = 32.0
|
||||
theme_override_constants/separation = 4
|
||||
|
||||
[node name="Hint" type="Label" parent="Buttons"]
|
||||
theme_override_colors/font_color = Color(1, 1, 1, 0.85)
|
||||
theme_override_colors/font_outline_color = Color(0, 0, 0, 0.8)
|
||||
theme_override_constants/outline_size = 3
|
||||
theme_override_fonts/font = SubResource("SystemFont_cjk")
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "跳关"
|
||||
vertical_alignment = 1
|
||||
@@ -0,0 +1,111 @@
|
||||
extends CanvasLayer
|
||||
|
||||
## 「房★主★有★神★器★」:把两个调试功能(飞行 / 跳关)藏在一个彩蛋按钮里。
|
||||
##
|
||||
## 平时屏幕上只有右上角一个小小的「房★主★有★神★器★」按钮,
|
||||
## 点一下才弹出面板,里面是飞行开关和跳关按钮。
|
||||
## 面板打开时键盘 1/2/3 也能跳关,Esc 或再点一次按钮关闭。
|
||||
## 正式版里也能用(这是刻意留的彩蛋,不是调试残留)。
|
||||
|
||||
@export var levels: Array[String] = [
|
||||
"res://scenes/main.tscn",
|
||||
"res://scenes/level2.tscn",
|
||||
"res://scenes/level3.tscn",
|
||||
]
|
||||
## 是否显示那个彩蛋按钮(关掉的话就只能靠别的方式打开面板了)
|
||||
@export var show_button: bool = true
|
||||
|
||||
var _panel: Control = null
|
||||
var _open_button: Button = null
|
||||
var _fly_button: Button = null
|
||||
var _player: Node = null
|
||||
var _open: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
visible = true
|
||||
_panel = get_node_or_null("Panel")
|
||||
_open_button = get_node_or_null("OpenButton")
|
||||
_fly_button = get_node_or_null("Panel/VBox/FlyButton")
|
||||
|
||||
if _open_button != null:
|
||||
_open_button.visible = show_button
|
||||
_open_button.pressed.connect(toggle_panel)
|
||||
|
||||
var close := get_node_or_null("Panel/VBox/CloseButton")
|
||||
if close != null:
|
||||
close.pressed.connect(toggle_panel)
|
||||
|
||||
if _fly_button != null:
|
||||
_fly_button.pressed.connect(toggle_fly)
|
||||
|
||||
var row := get_node_or_null("Panel/VBox/Row")
|
||||
if row != null:
|
||||
var index := 1
|
||||
for path in levels:
|
||||
var btn := Button.new()
|
||||
btn.text = str(index)
|
||||
btn.custom_minimum_size = Vector2(26.0, 24.0)
|
||||
btn.focus_mode = Control.FOCUS_NONE
|
||||
btn.add_theme_font_size_override("font_size", 12)
|
||||
btn.pressed.connect(jump_to.bind(path))
|
||||
row.add_child(btn)
|
||||
index += 1
|
||||
|
||||
if _panel != null:
|
||||
_panel.visible = false
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _fly_button == null:
|
||||
return
|
||||
if _player == null or not is_instance_valid(_player):
|
||||
_player = get_tree().get_first_node_in_group("player")
|
||||
if _player == null:
|
||||
_fly_button.text = "飞行(F)"
|
||||
return
|
||||
_fly_button.text = "飞行:开(F)" if bool(_player.flying) else "飞行:关(F)"
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if not _open:
|
||||
return
|
||||
var key := event as InputEventKey
|
||||
if key == null or not key.pressed or key.echo:
|
||||
return
|
||||
if key.physical_keycode == KEY_ESCAPE:
|
||||
toggle_panel()
|
||||
return
|
||||
var n := 0
|
||||
match key.physical_keycode:
|
||||
KEY_1:
|
||||
n = 1
|
||||
KEY_2:
|
||||
n = 2
|
||||
KEY_3:
|
||||
n = 3
|
||||
KEY_4:
|
||||
n = 4
|
||||
KEY_5:
|
||||
n = 5
|
||||
if n >= 1 and n <= levels.size():
|
||||
jump_to(levels[n - 1])
|
||||
|
||||
|
||||
func toggle_panel() -> void:
|
||||
_open = not _open
|
||||
if _panel != null:
|
||||
_panel.visible = _open
|
||||
|
||||
|
||||
func toggle_fly() -> void:
|
||||
if _player == null or not is_instance_valid(_player):
|
||||
_player = get_tree().get_first_node_in_group("player")
|
||||
if _player == null or not _player.has_method("set_flying"):
|
||||
return
|
||||
_player.set_flying(not bool(_player.flying))
|
||||
|
||||
|
||||
func jump_to(path: String) -> void:
|
||||
get_tree().paused = false
|
||||
get_tree().change_scene_to_file(path)
|
||||
@@ -1,59 +0,0 @@
|
||||
extends CanvasLayer
|
||||
|
||||
## 测试用跳关:右上角一排数字按钮,点一下直接跳到对应关卡;
|
||||
## 键盘上按 1 / 2 / 3 也一样。
|
||||
## 只在编辑器 / 调试版里显示,导出的正式版会自动隐藏(和飞行一个规矩)。
|
||||
|
||||
@export var levels: Array[String] = [
|
||||
"res://scenes/main.tscn",
|
||||
"res://scenes/level2.tscn",
|
||||
"res://scenes/level3.tscn",
|
||||
]
|
||||
## 强制在正式版里也显示(一般别开)
|
||||
@export var always_show: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
visible = always_show or OS.is_debug_build()
|
||||
if not visible:
|
||||
set_process_unhandled_input(false)
|
||||
return
|
||||
|
||||
var box := get_node_or_null("Buttons")
|
||||
if box == null:
|
||||
return
|
||||
var index := 1
|
||||
for path in levels:
|
||||
var btn := Button.new()
|
||||
btn.text = str(index)
|
||||
btn.custom_minimum_size = Vector2(24.0, 24.0)
|
||||
btn.focus_mode = Control.FOCUS_NONE
|
||||
btn.add_theme_font_size_override("font_size", 12)
|
||||
btn.pressed.connect(jump_to.bind(path))
|
||||
box.add_child(btn)
|
||||
index += 1
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
var key := event as InputEventKey
|
||||
if key == null or not key.pressed or key.echo:
|
||||
return
|
||||
var n := 0
|
||||
match key.physical_keycode:
|
||||
KEY_1, KEY_KP_1:
|
||||
n = 1
|
||||
KEY_2, KEY_KP_2:
|
||||
n = 2
|
||||
KEY_3, KEY_KP_3:
|
||||
n = 3
|
||||
KEY_4, KEY_KP_4:
|
||||
n = 4
|
||||
KEY_5, KEY_KP_5:
|
||||
n = 5
|
||||
if n >= 1 and n <= levels.size():
|
||||
jump_to(levels[n - 1])
|
||||
|
||||
|
||||
func jump_to(path: String) -> void:
|
||||
get_tree().paused = false
|
||||
get_tree().change_scene_to_file(path)
|
||||
@@ -357,7 +357,8 @@ func _build_throw_visuals() -> void:
|
||||
# ---------------------------------------------------------------- 测试用飞行
|
||||
|
||||
func fly_available() -> bool:
|
||||
return debug_fly and OS.is_debug_build()
|
||||
# 这是藏在「房★主★有★神★器★」面板里的隐藏技能,正式版里也能用
|
||||
return debug_fly
|
||||
|
||||
|
||||
func set_flying(on: bool) -> void:
|
||||
@@ -368,10 +369,13 @@ func set_flying(on: bool) -> void:
|
||||
|
||||
|
||||
func handle_fly_movement() -> void:
|
||||
# get_axis(负方向, 正方向),屏幕坐标里 y 向下为正,所以空格(跳跃)要放在负方向
|
||||
# 跳跃键已经停用了,所以调试飞行改用方向键上下(S 也保留作下降)来控制升降
|
||||
var vertical := Input.get_axis("ui_up", "ui_down")
|
||||
if is_zero_approx(vertical) and Input.is_action_pressed("squat"):
|
||||
vertical = 1.0
|
||||
var direction := Vector2(
|
||||
Input.get_axis("move_left", "move_right"),
|
||||
Input.get_axis("jump", "squat")
|
||||
vertical
|
||||
)
|
||||
if direction == Vector2.ZERO:
|
||||
velocity = Vector2.ZERO
|
||||
|
||||
Reference in New Issue
Block a user