f549c03533
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.
112 lines
2.9 KiB
GDScript
112 lines
2.9 KiB
GDScript
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)
|