extends CanvasLayer signal exiting signal success @onready var container = %PartsContainer @onready var whole = %Whole @onready var content_rect = %Content # original: 152 var part_size = 110 var positions = [] # from part 0 to 3, rotated by 0, 90, 180, 270 degrees var rotations = [0, 0, 0, 0] var images = [] var game_finished = false var selected := 0: set(value): selected = value _display_selected() func _ready() -> void: layer = GlobalConfig.CANVAS_LAYER_LITTLE_GAME _setup() _shuffle() _display_selected() content_rect.modulate.a = 0.0 content_rect.visible = true SceneManager.pop_center_notification(tr("input_拼凑信件")) func _setup() -> void: # 保存 whole 中的 4 个 part 的位置,然后从 whole 中移除,添加到 container 中 positions.clear() images.clear() for i in range(4): var part = whole.get_child(0) as TextureButton part.pressed.connect(_select_part.bind(part)) images.append(part.texture_normal.get_image()) positions.append(part.position) # 从 whole 中移除,添加到 container 中 whole.remove_child(part) container.add_child(part) part.texture_click_mask = BitMap.new() part.texture_click_mask.create_from_image_alpha(images[i]) _container_replace_children() func _select_part(part) -> void: selected = part.get_index() _display_selected() func _exchange_parts(a: int, b: int) -> void: var part_a = container.get_child(a) var part_b = container.get_child(b) container.move_child(part_a, b) container.move_child(part_b, a) # reassign answer container.move_child(part_a, b) _container_replace_children() func _container_replace_children() -> void: container.get_child(0).position = Vector2(0, 0) container.get_child(1).position = Vector2(part_size, 0) container.get_child(2).position = Vector2(0, part_size) container.get_child(3).position = Vector2(part_size, part_size) func _rotate_part(direction := 1) -> void: var part = container.get_child(selected) as TextureButton var id = int(str(part.name)) rotations[id] = wrapi(rotations[id] + direction, 0, 4) images[id].rotate_90(direction) part.texture_normal = ImageTexture.create_from_image(images[id]) part.texture_click_mask.create_from_image_alpha(images[id]) func _shuffle() -> void: # shuffle answer for i in range(30): var a = randi() % 4 var b = randi() % 4 _exchange_parts(a, b) # shuffle rotations for i in range(4): selected = i for j in range(randi() % 4): _rotate_part() selected = 0 func _display_selected() -> void: if game_finished: return for i in range(4): if i == selected: container.get_child(i).modulate = Color(1, 1, 1) else: container.get_child(i).modulate = Color(0.7, 0.7, 0.7) func _check_answer() -> void: var _success = true for i in range(4): var part = container.get_child(i) var id = int(str(part.name)) if rotations[id] != 0 or id != i: _success = false break game_finished = _success if _success: # 从 container 中移除,添加到 whole 中 var tween = create_tween() tween.tween_property(whole, "scale", Vector2.ONE, 1.0) var diff = whole.position - container.position whole.position = container.position for i in range(4): var part = container.get_child(0) container.remove_child(part) whole.add_child(part) # 逐个恢复到原始 modulate part.modulate = Color(1, 1, 1) # 逐个移动到正确位置 tween.parallel().tween_property(part, "position", diff + positions[i], 1.0) tween.tween_callback(_post_success) func _post_success(): # 不显示文本,让玩家在重要物品栏去看(提示) # var tween = create_tween() # tween.tween_property(content_rect, "modulate:a", 1.0, 1.0) var texture = preload("res://asset/art/prop/c01/院长的信.png") var inspector = SceneManager.get_inspector() inspector.pop_standard_inspection(texture, null, tr("prop_院长的信_说明")) SceneManager.enable_important_item("prop_院长的信") whole.visible = false # 1s 后退出 await get_tree().create_timer(1.0).timeout if get_parent() != null: success.emit() get_parent().remove_child(self) func _unhandled_input(event: InputEvent) -> void: # block all input get_viewport().set_input_as_handled() if event.is_action_pressed("cancel") or event.is_action_pressed("escape"): if game_finished: success.emit() else: exiting.emit() get_parent().remove_child(self) return if game_finished: return var handled = false if event.is_action_pressed("up"): if selected > 1: _exchange_parts(selected, selected - 2) selected -= 2 handled = true elif event.is_action_pressed("down"): if selected < 2: _exchange_parts(selected, selected + 2) selected += 2 handled = true elif event.is_action_pressed("left"): if selected % 2 == 1: _exchange_parts(selected, selected - 1) selected -= 1 handled = true elif event.is_action_pressed("right"): if selected % 2 == 0: _exchange_parts(selected, selected + 1) selected += 1 handled = true elif event.is_action_pressed("interact"): _rotate_part() handled = true if handled: $SfxMove.play() _display_selected() _check_answer()