xiandie/scene/little_game/八音盒.gd

168 lines
5.7 KiB
GDScript3
Raw Normal View History

2025-01-06 08:06:20 +00:00
extends Control
# answer for the puzzle, by columns
@export var current_answer := [0, 0, 0, 0, 0, 0, 0, 0, 0]
@export_enum("closed", "opened", "playing", "finished") var mode := "closed"
@export var answer := [1, 0, 0, 0, 0, 0, 0, 0, 0]
# @export var answer := [1, 4, 3, 1, 3, 6, 4, 3, 2]
@onready var points_polygon = $ButtonPositionPoints as Polygon2D
2025-01-06 08:06:20 +00:00
@onready var box = $Box as TextureRect
@onready var side_handle = $SideHandle as AnimatedSprite2D
@onready var inside_handle = $Handle as TextureButton
@onready var audio_player = $MusicPlayer2D as AudioStreamPlayer2D
var button_texture = preload("res://asset/art/little_game/八音盒/小猫.png")
var button_highlight_texture = preload("res://asset/art/little_game/八音盒/小猫高亮.png")
var box_closed_texture = preload("res://asset/art/little_game/八音盒/无按钮.png")
var box_opened_texture = preload("res://asset/art/little_game/八音盒/打开盒子.png")
var box_finished_texture = preload("res://asset/art/little_game/八音盒/有按钮.png")
var sfx_interact = preload("res://asset/audio/sfx/game/八音盒/八音盒互动.mp3") as AudioStream
var sfx_drag = preload("res://asset/audio/sfx/game/八音盒/拖动放置.mp3") as AudioStream
var sfx_open = preload("res://asset/audio/sfx/game/八音盒/八音盒打开.mp3") as AudioStream
var sfx_close = preload("res://asset/audio/sfx/game/八音盒/关盖子.mp3") as AudioStream
var sfx_exit = preload("res://asset/audio/sfx/game/八音盒/退出界面.mp3") as AudioStream
var audio_manual = preload("res://asset/audio/sfx/game/八音盒/操纵八音盒.mp3") as AudioStream
var audio_auto = preload("res://asset/audio/sfx/game/八音盒/自走八音盒.mp3") as AudioStream
var dragging = false
var current_selected_btn := 0:
set(value):
if has_node("button_root"):
# set previous button to normal
var root = get_node("button_root")
root.get_node(str(current_selected_btn)).texture = button_texture
# set current button to highlight
root.get_node(str(value)).texture = button_highlight_texture
current_selected_btn = value
func _ready() -> void:
_chechout_mode()
inside_handle.pressed.connect(_on_handle_pressed)
2025-01-06 08:06:20 +00:00
# SceneManager.focus_node(self)
# CameraFocusMarker.lock_horizontal = false
# CameraFocusMarker.limit_top = 0
# CameraFocusMarker.limit_bottom = 316
func _chechout_mode(play_sfx := false) -> void:
2025-01-06 08:06:20 +00:00
dragging = false
$Handle.visible = mode == "opened"
$SideHandle.visible = mode == "playing" or mode == "finished"
_reset_buttons()
match mode:
"closed":
audio_player.stream = sfx_interact
audio_player.play()
box.texture = box_closed_texture
_reset_buttons()
audio_player.stream = sfx_drag
"opened":
if play_sfx:
audio_player.stream = sfx_open
audio_player.play()
box.texture = box_opened_texture
"playing":
audio_player.stream = sfx_drag
box.texture = box_opened_texture
"finished":
if play_sfx:
audio_player.stream = sfx_close
audio_player.play()
box.texture = box_finished_texture
func _reset_buttons():
if mode != "closed":
if has_node("button_root"):
get_node("button_root").visible = false
return
# create buttons if not exists
if not has_node("button_root"):
var root = Node2D.new()
root.name = "button_root"
add_child(root)
for i in range(9):
var button = Sprite2D.new()
button.name = str(i)
root.add_child(button)
# reset buttons' position and texture
for i in range(9):
var button = get_node("button_root" + "/" + str(i))
if i == current_selected_btn:
button.texture = button_highlight_texture
else:
button.texture = button_texture
# load current_answer
button.position = _get_position(i, current_answer[i])
# 自动计算的位置会有偏差,使用 polygon 的点进行标记
# row rom bottom to top, 7 rows in total
# col from left to right, 9 cols in total
func _get_position(col: int, row: int) -> Vector2:
# var col_gap = col_gap_down + (col_gap_up - col_gap_down) * row / 6
# return Vector2(origin_position.x + col_gap * col, origin_position.y - row_gap * row)
var index = col + row * 9
if points_polygon.polygon and index < points_polygon.polygon.size():
2025-01-06 08:06:20 +00:00
return points_polygon.position + points_polygon.polygon[index]
else:
2025-01-06 08:06:20 +00:00
return points_polygon.position
# 1 up 2 down
func _move_button(delta: int) -> void:
if mode != "closed":
return
var current_row = current_answer[current_selected_btn]
var target_row = clampi(current_answer[current_selected_btn] + delta, 0, 6)
current_answer[current_selected_btn] = target_row
# tween if not in correct position
if current_row != target_row:
var target_position = _get_position(current_selected_btn, target_row)
var node = get_node("button_root/" + str(current_selected_btn))
create_tween().tween_property(node, "position", target_position, .5)
# play sfx
audio_player.stream = sfx_drag
audio_player.play()
# check if all buttons are in correct position
if current_answer == answer:
mode = "opened"
_chechout_mode(true)
func _unhandled_input(event: InputEvent) -> void:
if mode == "closed":
# move button
if event.is_action_pressed("up"):
_move_button(1)
elif event.is_action_pressed("down"):
_move_button(-1)
elif event.is_action_pressed("left"):
current_selected_btn = clampi(current_selected_btn - 1, 0, 8)
elif event.is_action_pressed("right"):
current_selected_btn = clampi(current_selected_btn + 1, 0, 8)
2025-01-06 08:06:20 +00:00
if mode == "playing":
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT:
if event.pressed:
dragging = true
else:
dragging = false
if event is InputEventMouseMotion:
if dragging:
#TODO
inside_handle.position += event.relative
func _on_handle_pressed() -> void:
if mode == "opened":
mode = "playing"
_chechout_mode(true)