119 lines
4.7 KiB
GDScript
119 lines
4.7 KiB
GDScript
class_name JugglingGymGame
|
|
extends Control
|
|
## Prototipo P3B: trascina un attrezzo sul giocoliere corretto.
|
|
|
|
signal return_requested
|
|
|
|
const MOCKUP := preload("res://games/juggling_gym/assets/p3b/p3b_mockup.jpg")
|
|
const BALLS := preload("res://games/juggling_gym/assets/p3b/3b_palline.png")
|
|
const ROLA_BOLA := preload("res://games/juggling_gym/assets/p3b/3b_rola_bola.png")
|
|
const CLUBS := preload("res://games/juggling_gym/assets/p3b/3b_clave.png")
|
|
const PLATES := preload("res://games/juggling_gym/assets/p3b/3b_piatti_cinesi.png")
|
|
const SPHERE := preload("res://games/juggling_gym/assets/p3b/3b_sfera.png")
|
|
const ACTIVE_TOOLS := ["palline", "piatti", "sfera"]
|
|
const TOOL_DATA := {
|
|
"palline": {"texture": BALLS, "target": "left", "center": Vector2(0.18, 0.80), "size": Vector2(0.14, 0.18), "available": true},
|
|
"rola_bola": {"texture": ROLA_BOLA, "target": "center", "center": Vector2(0.34, 0.80), "size": Vector2(0.15, 0.16), "available": false},
|
|
"clave": {"texture": CLUBS, "target": "left", "center": Vector2(0.50, 0.80), "size": Vector2(0.15, 0.18), "available": false},
|
|
"piatti": {"texture": PLATES, "target": "right", "center": Vector2(0.66, 0.80), "size": Vector2(0.16, 0.18), "available": true},
|
|
"sfera": {"texture": SPHERE, "target": "center", "center": Vector2(0.82, 0.80), "size": Vector2(0.14, 0.18), "available": true},
|
|
}
|
|
|
|
var score := 0
|
|
var score_label: Label
|
|
var message_label: Label
|
|
var tool_controls: Dictionary = {}
|
|
var drop_zones: Dictionary = {}
|
|
|
|
|
|
func _ready() -> void:
|
|
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
_build()
|
|
|
|
|
|
func _build() -> void:
|
|
var artwork := TextureRect.new()
|
|
artwork.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
artwork.texture = MOCKUP
|
|
artwork.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
|
artwork.stretch_mode = TextureRect.STRETCH_SCALE
|
|
artwork.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
add_child(artwork)
|
|
|
|
var back := MenuUI.add_hotspot(self, MenuUI.BACK_BUTTON_CENTER, MenuUI.BACK_BUTTON_SIZE)
|
|
back.tooltip_text = "Torna alla palestra"
|
|
back.pressed.connect(func(): return_requested.emit())
|
|
back.z_index = 20
|
|
|
|
_add_drop_zone("left", Vector2(0.27, 0.41), Vector2(0.20, 0.42))
|
|
_add_drop_zone("center", Vector2(0.50, 0.39), Vector2(0.20, 0.45))
|
|
_add_drop_zone("right", Vector2(0.73, 0.41), Vector2(0.20, 0.44))
|
|
_build_tools()
|
|
_build_hud()
|
|
|
|
|
|
func _add_drop_zone(id: String, center: Vector2, size: Vector2) -> void:
|
|
var zone := GymDropZone.new()
|
|
zone.configure(id)
|
|
zone.tool_dropped.connect(_on_tool_dropped)
|
|
zone.z_index = 5
|
|
add_child(zone)
|
|
MenuUI.set_normalized_rect(zone, center, size)
|
|
drop_zones[id] = zone
|
|
|
|
|
|
func _build_tools() -> void:
|
|
for tool_id in TOOL_DATA:
|
|
var config: Dictionary = TOOL_DATA[tool_id]
|
|
var tool := GymTool.new()
|
|
tool.configure(tool_id, config["texture"], config["available"])
|
|
tool.tooltip_text = "Trascina sul giocoliere corretto" if config["available"] else "Disponibile in una prossima versione"
|
|
tool.z_index = 10
|
|
add_child(tool)
|
|
MenuUI.set_normalized_rect(tool, config["center"], config["size"])
|
|
tool_controls[tool_id] = tool
|
|
|
|
|
|
func _build_hud() -> void:
|
|
var instruction := MenuUI.add_label(self, "Trascina ogni attrezzo sul giocoliere", Vector2(0.50, 0.10), Vector2(0.34, 0.08), 22)
|
|
instruction.add_theme_stylebox_override("normal", MenuUI.note_style())
|
|
instruction.z_index = 20
|
|
|
|
score_label = MenuUI.add_label(self, "0 / %d" % ACTIVE_TOOLS.size(), Vector2(0.91, 0.12), Vector2(0.12, 0.08), 24)
|
|
score_label.add_theme_stylebox_override("normal", MenuUI.note_style())
|
|
score_label.z_index = 20
|
|
|
|
message_label = MenuUI.add_label(self, "", Vector2(0.50, 0.91), Vector2(0.28, 0.07), 22)
|
|
message_label.add_theme_stylebox_override("normal", MenuUI.note_style())
|
|
message_label.modulate.a = 0.0
|
|
message_label.z_index = 20
|
|
|
|
|
|
func _on_tool_dropped(zone_id: String, data: Dictionary) -> void:
|
|
var tool_id := str(data.get("tool_id", ""))
|
|
if not TOOL_DATA.has(tool_id):
|
|
return
|
|
var config: Dictionary = TOOL_DATA[tool_id]
|
|
var correct: bool = str(config["target"]) == zone_id
|
|
var zone: GymDropZone = drop_zones[zone_id]
|
|
zone.flash(correct)
|
|
if not correct:
|
|
_show_message("Prova con un altro giocoliere", false)
|
|
return
|
|
if tool_id in tool_controls and tool_controls[tool_id].disabled:
|
|
return
|
|
|
|
tool_controls[tool_id].disabled = true
|
|
score += 1
|
|
score_label.text = "%d / %d" % [score, ACTIVE_TOOLS.size()]
|
|
_show_message("Ben fatto!" if score < ACTIVE_TOOLS.size() else "Palestra completata!", true)
|
|
|
|
|
|
func _show_message(text: String, success: bool) -> void:
|
|
message_label.text = text
|
|
message_label.add_theme_color_override("font_color", Color("#2c6e3f") if success else Color("#9b352b"))
|
|
message_label.modulate.a = 1.0
|
|
var tween := create_tween()
|
|
tween.tween_interval(1.25)
|
|
tween.tween_property(message_label, "modulate:a", 0.0, 0.28)
|