xiandie/scene/little_game/书架.gd

205 lines
5.2 KiB
GDScript3
Raw Normal View History

2025-01-08 07:59:27 +00:00
@tool
2025-01-07 10:54:50 +00:00
extends Control
const NON_SELECTED = [-1, -1]
2025-01-08 07:59:27 +00:00
@export var shuffle_times := 20
2025-01-07 10:54:50 +00:00
@onready var sfx_select = $SfxSelect as Sfx
@onready var sfx_interchange = $SfxInterchange as Sfx
2025-01-08 07:59:27 +00:00
var current_answer := []
2025-01-07 10:54:50 +00:00
var book_width_by_row := []
var suffling := false
# [row, col]
var selected_book := NON_SELECTED:
set(value):
if selected_book == value:
return
if suffling:
selected_book = value
return
if selected_book != NON_SELECTED:
_toggle_book(false, selected_book[0], selected_book[1])
if value != NON_SELECTED:
_toggle_book(true, value[0], value[1])
selected_book = value
func _ready() -> void:
2025-01-08 07:59:27 +00:00
# init answer first
_init_answer_and_connect_signals()
2025-01-07 10:54:50 +00:00
_measure_width_by_row()
# shuffle at the end
2025-01-08 07:59:27 +00:00
if Engine.is_editor_hint():
for row in range(3):
_relocate_books(row)
else:
_shuffle_books()
func _init_answer_and_connect_signals() -> void:
for row in range(3):
var r_size = get_node("./Shelf/Layer" + str(row)).get_child_count()
# current_answer append a r_size arr
var arr = []
for id in range(r_size):
arr.append(id)
var book = _get_book_by_id(row, id)
book.get_node("BookButton").pressed.connect(_on_book_pressed.bind(row, id))
current_answer.append(arr)
2025-01-07 10:54:50 +00:00
func _measure_width_by_row() -> void:
for row in range(3):
var length = current_answer[row].size()
var width_arr = []
for col in range(length):
var book_btn = _get_book_by_id(row, col).get_node("BookButton") as TextureButton
# book_btn.position.y = -book_btn.texture_normal.get_height()
# book_btn.size = book_btn.texture_normal.get_size()
# add 1 to avoid the gap between books
width_arr.append(book_btn.texture_normal.get_width() + 1)
book_width_by_row.append(width_arr)
func _shuffle_books() -> void:
selected_book = NON_SELECTED
suffling = true
2025-01-08 07:59:27 +00:00
rand_from_seed(Time.get_ticks_usec())
2025-01-07 10:54:50 +00:00
for row in range(3):
# shuffle each row 20 times
var r_size = current_answer[row].size()
2025-01-08 07:59:27 +00:00
for _i in range(shuffle_times):
2025-01-07 10:54:50 +00:00
var col_1 = randi() % r_size
var col_2 = randi() % r_size
selected_book = [row, col_1]
_interchange_book(row, col_2, false)
_relocate_books(row)
# turn off initilazing after shuffle
suffling = false
func _on_book_pressed(row: int, id: int) -> void:
var col = current_answer[row].find(id)
if selected_book == NON_SELECTED:
selected_book = [row, col]
else:
if selected_book == [row, col]:
selected_book = NON_SELECTED
elif selected_book[0] == row:
_interchange_book(row, col)
else:
selected_book = [row, col]
func _get_book_by_id(row: int, id: int) -> Node2D:
return get_node("./Shelf/Layer" + str(row) + "/Book" + str(id))
# func _get_book_by_pos(row: int, col: int) -> Node2D:
# var layer = get_node("./Shelf/Layer" + str(row))
# return layer.get_child(col)
2025-01-08 07:59:27 +00:00
var mute_toggle = false
2025-01-07 10:54:50 +00:00
func _toggle_book(selected: bool, row: int, col: int) -> void:
var id = current_answer[row][col]
var book = _get_book_by_id(row, id)
var book_tween = create_tween()
2025-01-08 07:59:27 +00:00
if not mute_toggle:
sfx_select.play()
2025-01-07 10:54:50 +00:00
if selected:
book_tween.parallel().tween_property(book, "position:y", -10.0, 0.2)
else:
book_tween.parallel().tween_property(book, "position:y", 0.0, 0.2)
func _interchange_book(row: int, col: int, relocate := true) -> void:
if selected_book == NON_SELECTED or selected_book[0] != row:
return
var col2 = selected_book[1]
sfx_interchange.play()
# interchange current_answer
var temp = current_answer[row][col]
current_answer[row][col] = current_answer[row][col2]
current_answer[row][col2] = temp
# reset selected_book
2025-01-08 07:59:27 +00:00
mute_toggle = true
2025-01-07 10:54:50 +00:00
selected_book = NON_SELECTED
2025-01-08 07:59:27 +00:00
mute_toggle = false
2025-01-07 10:54:50 +00:00
# relocate after reset selected_book
if relocate:
_relocate_books(row)
# check answer
_check_answer()
func _relocate_books(row: int) -> void:
selected_book = NON_SELECTED
var r_size = current_answer[row].size()
var x = 0
for col in range(r_size):
var id = current_answer[row][col]
var book = _get_book_by_id(row, id)
book.position.x = x
book.position.y = 0.0
x += book_width_by_row[row][id]
func _check_answer() -> void:
2025-01-08 07:59:27 +00:00
# 第一行需要顺序排列
var row1 = current_answer[0]
for col in range(row1.size()):
if row1[col] != col:
return
# 第二行正序或者倒序都可以
var row2 = current_answer[1]
var size2 = row2.size()
if row2[0] == 0:
# 正序
for col in range(1, size2):
if row2[col] != col:
2025-01-07 10:54:50 +00:00
return
2025-01-08 07:59:27 +00:00
else:
# 倒序
for col in range(size2):
if row2[col] != size2 - 1 - col:
return
# 最后一行按色块排列0-6 蓝色7个在一起7-11 红色5个在一起12-17 黄色6个在一起
var row3 = current_answer[2]
# 0: blue, 1: red, 2: yellow
var visited = [7, 5, 6]
var visiting_init = true
var visiting = -1
for col in range(row3.size()):
var color = _get_color(row3[col])
if visiting_init:
visiting = color
visiting_init = false
if color != visiting:
return
visited[color] -= 1
if visited[color] == 0:
visiting_init = true
2025-01-07 10:54:50 +00:00
# success
_success()
2025-01-08 07:59:27 +00:00
# 0: blue, 1: red, 2: yellow
func _get_color(index: int) -> int:
# 0-6 蓝色7个在一起7-11 红色5个在一起12-17 黄色6个在一起
if index < 7:
return 0
elif index < 12:
return 1
else:
return 2
2025-01-07 10:54:50 +00:00
func _success() -> void:
print("Success!")
#TODO
pass