diff --git a/assets/circus_arena_bg.png b/assets/circus_arena_bg.png new file mode 100644 index 0000000..3b68bfa Binary files /dev/null and b/assets/circus_arena_bg.png differ diff --git a/assets/circus_arena_bg.png.import b/assets/circus_arena_bg.png.import new file mode 100644 index 0000000..cd85a6e --- /dev/null +++ b/assets/circus_arena_bg.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ct41qa8mcrasu" +path="res://.godot/imported/circus_arena_bg.png-de834c813aaf56ef1806abe1b7429fbc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/circus_arena_bg.png" +dest_files=["res://.godot/imported/circus_arena_bg.png-de834c813aaf56ef1806abe1b7429fbc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf b/assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf new file mode 100644 index 0000000..dfe976c Binary files /dev/null and b/assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf differ diff --git a/assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf.import b/assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf.import new file mode 100644 index 0000000..7e3fc37 --- /dev/null +++ b/assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://cf4a5svxlksmm" +path="res://.godot/imported/NotoSerifDisplay-CondensedExtraBold.ttf-7c8f93a07381b12b5a0d4a45235c365c.fontdata" + +[deps] + +source_file="res://assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf" +dest_files=["res://.godot/imported/NotoSerifDisplay-CondensedExtraBold.ttf-7c8f93a07381b12b5a0d4a45235c365c.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=3 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/scripts/board.gd b/scripts/board.gd index 2b3b24a..2174d05 100644 --- a/scripts/board.gd +++ b/scripts/board.gd @@ -17,20 +17,39 @@ const LANE_FILL := Color("#c9ac7c") const LANE_EDGE := Color(0.22, 0.15, 0.08, 0.9) var wood_tex: Texture2D +var circus_tex: Texture2D func _ready() -> void: z_index = -10 wood_tex = load("res://assets/wood_board.png") + circus_tex = load("res://assets/circus_arena_bg.png") queue_redraw() func _draw() -> void: - # sfondo in legno + # Arena circense quieta ai margini; la plancia copre il centro più ricco. + if circus_tex: + draw_texture_rect(circus_tex, Rect2(Vector2.ZERO, VIEW), false) + # Ombra e corpo smussato del tabellone. + var shadow := StyleBoxFlat.new() + shadow.bg_color = Color(0.12, 0.055, 0.02, 0.5) + shadow.corner_radius_top_left = 28 + shadow.corner_radius_top_right = 28 + shadow.corner_radius_bottom_left = 28 + shadow.corner_radius_bottom_right = 28 + draw_style_box(shadow, Rect2(32, 151, 1216, 560)) if wood_tex: - draw_texture_rect(wood_tex, Rect2(Vector2.ZERO, VIEW), false) - # cornice - draw_rect(Rect2(Vector2.ZERO, VIEW), Color(0.15, 0.1, 0.05, 0.4), false, 4.0) + draw_texture_rect(wood_tex, Rect2(36, 142, 1208, 558), false) + var frame := StyleBoxFlat.new() + frame.bg_color = Color(0, 0, 0, 0) + frame.border_color = Color("#81542f") + frame.set_border_width_all(8) + frame.corner_radius_top_left = 27 + frame.corner_radius_top_right = 27 + frame.corner_radius_bottom_left = 27 + frame.corner_radius_bottom_right = 27 + draw_style_box(frame, Rect2(32, 138, 1216, 566)) for i in range(5): _draw_lane(LANE_TOP + i * LANE_GAP) _draw_number(i + 1, LANE_TOP + i * LANE_GAP) @@ -58,13 +77,16 @@ func _draw_lane(y: float) -> void: var closed := pts.duplicate() closed.append(pts[0]) draw_polyline(closed, LANE_EDGE, 3.0, true) - # alloggiamenti circolari incassati alle estremità + # Alloggiamenti a calotta: anelli concentrici e luce/ombra danno profondità. for cx in [LANE_LEFT, LANE_RIGHT]: var c := Vector2(cx, y) - draw_circle(c, SOCKET_R, LANE_FILL) - draw_arc(c, SOCKET_R, 0.0, TAU, 40, LANE_EDGE, 3.0) - draw_circle(c + Vector2(0, 5), SOCKET_R - 7.0, Color(0.2, 0.12, 0.05, 0.22)) - draw_circle(c + Vector2(0, -5), SOCKET_R - 7.0, Color(1, 0.95, 0.85, 0.16)) + draw_circle(c + Vector2(0, 4), SOCKET_R + 3.0, Color(0.12, 0.06, 0.02, 0.38)) + draw_circle(c, SOCKET_R, Color("#8b6841")) + draw_circle(c + Vector2(0, 3), SOCKET_R - 6.0, Color("#6d4b2d")) + draw_circle(c + Vector2(-2, -4), SOCKET_R - 9.0, Color("#c5a476")) + draw_circle(c + Vector2(3, 5), SOCKET_R - 13.0, Color(0.2, 0.1, 0.04, 0.16)) + draw_arc(c, SOCKET_R, 0.0, TAU, 48, Color("#4a301d"), 3.0) + draw_arc(c - Vector2(1, 2), SOCKET_R - 8.0, PI, TAU, 24, Color(1, 0.92, 0.72, 0.28), 2.0) # ombra del canale in alto (profondità) draw_rect(Rect2(LANE_LEFT + 10, y - _lane_half_width((LANE_LEFT + CENTER_X) / 2.0) + 3.0, HALF_SPAN * 2 - 20, 3.0), Color(0.2, 0.12, 0.05, 0.18)) diff --git a/scripts/hud_cartouche.gd b/scripts/hud_cartouche.gd new file mode 100644 index 0000000..e175cb9 --- /dev/null +++ b/scripts/hud_cartouche.gd @@ -0,0 +1,55 @@ +extends Node2D + +## Cartiglio circense in legno, puramente decorativo: la UI interattiva +## rimane costruita da main.gd sopra questo nodo. + +const INK := Color("#5b2f19") +const WOOD_LIGHT := Color("#efd6aa") +const WOOD_MID := Color("#d8ad72") +const WOOD_DARK := Color("#8a552d") + + +func _draw() -> void: + # Ombra morbida e sagoma con angoli tagliati a 45 gradi. + var shadow := PackedVector2Array([ + Vector2(56, 27), Vector2(75, 10), Vector2(1205, 10), Vector2(1224, 27), + Vector2(1224, 128), Vector2(1205, 145), Vector2(75, 145), Vector2(56, 128) + ]) + for i in range(shadow.size()): + shadow[i] += Vector2(0, 7) + draw_colored_polygon(shadow, Color(0.12, 0.055, 0.02, 0.42)) + var body := PackedVector2Array([ + Vector2(56, 27), Vector2(75, 10), Vector2(1205, 10), Vector2(1224, 27), + Vector2(1224, 128), Vector2(1205, 145), Vector2(75, 145), Vector2(56, 128) + ]) + draw_colored_polygon(body, WOOD_LIGHT) + var rim := body.duplicate() + rim.append(body[0]) + draw_polyline(rim, WOOD_DARK, 5.0, true) + # Incisioni e venatura tenue. + draw_line(Vector2(79, 25), Vector2(1201, 25), Color(1, 0.93, 0.78, 0.7), 2.0) + draw_line(Vector2(78, 130), Vector2(1202, 130), Color(0.38, 0.18, 0.07, 0.25), 2.0) + for y in [42.0, 104.0, 119.0]: + draw_arc(Vector2(640, y), 420.0, 0.08, PI - 0.08, 40, Color(0.45, 0.24, 0.1, 0.09), 1.0) + # Tasca incassata della biglia bersaglio. + _draw_socket(Vector2(430, 78), 43.0) + # Borchie dorate del cartiglio e della targhetta Opzioni. + for p in [Vector2(78, 34), Vector2(1202, 34), Vector2(78, 120), Vector2(1202, 120), + Vector2(567, 76), Vector2(713, 76)]: + _draw_stud(p) + + +func _draw_stud(p: Vector2) -> void: + draw_circle(p + Vector2(1, 3), 8.0, Color(0.25, 0.12, 0.03, 0.32)) + draw_circle(p, 7.0, Color("#b77a24")) + draw_circle(p - Vector2(1.5, 2), 4.2, Color("#edc668")) + draw_circle(p - Vector2(2.5, 3), 1.5, Color(1, 0.94, 0.7, 0.9)) + draw_arc(p, 7.0, 0.0, TAU, 20, Color("#714318"), 1.5) + + +func _draw_socket(p: Vector2, r: float) -> void: + draw_circle(p + Vector2(0, 3), r + 4.0, Color(0.28, 0.14, 0.06, 0.55)) + draw_circle(p, r, WOOD_DARK) + draw_circle(p + Vector2(0, 3), r - 7.0, Color("#5b351f")) + draw_circle(p + Vector2(-2, -3), r - 10.0, Color(0.93, 0.76, 0.51, 0.28)) + draw_arc(p, r, 0.0, TAU, 36, INK, 2.5) diff --git a/scripts/hud_cartouche.gd.uid b/scripts/hud_cartouche.gd.uid new file mode 100644 index 0000000..eda79f0 --- /dev/null +++ b/scripts/hud_cartouche.gd.uid @@ -0,0 +1 @@ +uid://bp7dvrdihdl13 diff --git a/scripts/main.gd b/scripts/main.gd index cc9378c..cc053e8 100644 --- a/scripts/main.gd +++ b/scripts/main.gd @@ -137,66 +137,75 @@ func _build_balls() -> void: func _build_ui() -> void: var layer := CanvasLayer.new() add_child(layer) - - # La texture sorgente è alta 720 px: il contenitore con clipping impedisce - # alla sua dimensione minima di coprire la plancia sotto la barra HUD. - var bar_clip := Control.new() - bar_clip.size = Vector2(VIEW.x, 140) - bar_clip.clip_contents = true - bar_clip.mouse_filter = Control.MOUSE_FILTER_IGNORE - layer.add_child(bar_clip) - - var bar := TextureRect.new() - bar.position = Vector2.ZERO - bar.expand_mode = TextureRect.EXPAND_IGNORE_SIZE - bar.stretch_mode = TextureRect.STRETCH_SCALE - bar.texture = load("res://assets/wood_board.png") - bar.size = Vector2(VIEW.x, 140) - bar.mouse_filter = Control.MOUSE_FILTER_IGNORE - bar_clip.add_child(bar) - - var edge := ColorRect.new() - edge.color = Color(0, 0, 0, 0.15) - edge.position = Vector2(0, 140) - edge.size = Vector2(VIEW.x, 3) - layer.add_child(edge) + var display_font: Font = load("res://assets/fonts/NotoSerifDisplay-CondensedExtraBold.ttf") + var ink := Color("#5b2f19") + var cartouche: Node2D = load("res://scripts/hud_cartouche.gd").new() + layer.add_child(cartouche) var tlabel := Label.new() tlabel.text = "BERSAGLIO" - tlabel.position = Vector2(46, 26) - tlabel.add_theme_font_size_override("font_size", 22) - tlabel.add_theme_color_override("font_color", Color(0.1, 0.1, 0.1, 0.85)) + tlabel.position = Vector2(94, 44) + tlabel.size = Vector2(270, 54) + tlabel.vertical_alignment = VERTICAL_ALIGNMENT_CENTER + tlabel.add_theme_font_override("font", display_font) + tlabel.add_theme_font_size_override("font_size", 34) + tlabel.add_theme_color_override("font_color", ink) layer.add_child(tlabel) target_dot = load("res://scripts/target_dot.gd").new() - target_dot.position = Vector2(128, 96) + target_dot.position = Vector2(430, 78) layer.add_child(target_dot) help_label = Label.new() help_label.text = "Tocca la pallina corrispondente al bersaglio per lanciarla!" - help_label.position = Vector2(VIEW.x / 2 - 300, 100) - help_label.size = Vector2(600, 30) + help_label.position = Vector2(VIEW.x / 2 - 350, 154) + help_label.size = Vector2(700, 30) help_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - help_label.add_theme_font_size_override("font_size", 18) - help_label.add_theme_color_override("font_color", Color(0.08, 0.07, 0.05, 0.78)) + help_label.add_theme_font_override("font", display_font) + help_label.add_theme_font_size_override("font_size", 17) + help_label.add_theme_color_override("font_color", ink) layer.add_child(help_label) score_label = Label.new() - score_label.position = Vector2(VIEW.x - 320, 22) - score_label.add_theme_font_size_override("font_size", 34) - score_label.add_theme_color_override("font_color", Color(0.1, 0.1, 0.1, 0.9)) + score_label.position = Vector2(925, 34) + score_label.size = Vector2(245, 48) + score_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + score_label.add_theme_font_override("font", display_font) + score_label.add_theme_font_size_override("font_size", 36) + score_label.add_theme_color_override("font_color", ink) layer.add_child(score_label) combo_label = Label.new() - combo_label.position = Vector2(VIEW.x - 320, 68) - combo_label.add_theme_font_size_override("font_size", 20) - combo_label.add_theme_color_override("font_color", Color(0.08, 0.07, 0.05, 0.75)) + combo_label.position = Vector2(925, 80) + combo_label.size = Vector2(245, 34) + combo_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + combo_label.add_theme_font_override("font", display_font) + combo_label.add_theme_font_size_override("font_size", 21) + combo_label.add_theme_color_override("font_color", ink) layer.add_child(combo_label) # pulsante Opzioni var opts_btn := Button.new() - opts_btn.text = "⚙ Opzioni (Esc)" - opts_btn.position = Vector2(VIEW.x / 2 - 100, 26) + opts_btn.text = "Opzioni" + opts_btn.position = Vector2(580, 49) + opts_btn.size = Vector2(120, 57) + opts_btn.add_theme_font_override("font", display_font) + opts_btn.add_theme_font_size_override("font_size", 25) + opts_btn.add_theme_color_override("font_color", ink) + opts_btn.add_theme_color_override("font_hover_color", Color("#7b421f")) + var opt_style := StyleBoxFlat.new() + opt_style.bg_color = Color("#ddb983") + opt_style.border_color = Color("#9b6738") + opt_style.set_border_width_all(3) + opt_style.corner_radius_top_left = 9 + opt_style.corner_radius_top_right = 9 + opt_style.corner_radius_bottom_left = 9 + opt_style.corner_radius_bottom_right = 9 + opts_btn.add_theme_stylebox_override("normal", opt_style) + var opt_hover := opt_style.duplicate() + opt_hover.bg_color = Color("#ebcb96") + opts_btn.add_theme_stylebox_override("hover", opt_hover) + opts_btn.add_theme_stylebox_override("pressed", opt_style) opts_btn.pressed.connect(_open_options) layer.add_child(opts_btn)