168 lines
4.3 KiB
GDScript
168 lines
4.3 KiB
GDScript
extends CanvasLayer
|
|
|
|
@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 success = false
|
|
|
|
var selected := 0:
|
|
set(value):
|
|
selected = value
|
|
_display_selected()
|
|
|
|
|
|
func _ready() -> void:
|
|
layer = GlobalConfig.LAYER_LITTLE_GAME
|
|
_setup()
|
|
_shuffle()
|
|
_display_selected()
|
|
content_rect.modulate.a = 0.0
|
|
content_rect.visible = true
|
|
%Label.text = tr("c01_信件全文")
|
|
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 success:
|
|
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
|
|
success = _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.parallel().tween_property(content_rect, "modulate:a", 1.0, 1.0)
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if success:
|
|
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()
|
|
get_viewport().set_input_as_handled()
|