Wooden Juggle Board: full-width varying lanes, sockets, numbers 1-5, glossy rotating balls, wooden HUD (codex-verified)
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dbc1xl8n81snw"
|
||||
path="res://.godot/imported/wood_board.png-e621ed61b7f7a4be5ad003e94a5862d9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/wood_board.png"
|
||||
dest_files=["res://.godot/imported/wood_board.png-e621ed61b7f7a4be5ad003e94a5862d9.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
|
||||
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bo68xvvx7qj1y"
|
||||
path="res://.godot/imported/mockup_circus_board.jpg-2fbd62a24f1306c4f037d8eaff63a49f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://docs/mockup_circus_board.jpg"
|
||||
dest_files=["res://.godot/imported/mockup_circus_board.jpg-2fbd62a24f1306c4f037d8eaff63a49f.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
|
||||
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d1s4bxbf7lchs"
|
||||
path="res://.godot/imported/mockup_circus_board_final.jpg-62ba66bb1e3cf2595372b834855655ff.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://docs/mockup_circus_board_final.jpg"
|
||||
dest_files=["res://.godot/imported/mockup_circus_board_final.jpg-62ba66bb1e3cf2595372b834855655ff.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
|
||||
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c4v4qubssge3k"
|
||||
path="res://.godot/imported/mockup_circus_board_hud.jpg-3f82d16327a4fd0aa0a732821e5577b7.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://docs/mockup_circus_board_hud.jpg"
|
||||
dest_files=["res://.godot/imported/mockup_circus_board_hud.jpg-3f82d16327a4fd0aa0a732821e5577b7.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
|
||||
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://rrev0wpv2y4g"
|
||||
path="res://.godot/imported/mockup_circus_board_hud_integrato.jpg-9094609fe3bab20ea5d287ef5c72f95f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://docs/mockup_circus_board_hud_integrato.jpg"
|
||||
dest_files=["res://.godot/imported/mockup_circus_board_hud_integrato.jpg-9094609fe3bab20ea5d287ef5c72f95f.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
|
||||
@@ -14,6 +14,7 @@ var radius := 40.0
|
||||
var home_pos := Vector2.ZERO
|
||||
var left_pos := Vector2.ZERO
|
||||
var in_motion := false
|
||||
var roll_angle := 0.0 # rotazione della biglia durante il rotolamento
|
||||
var _tween: Tween
|
||||
|
||||
|
||||
@@ -30,6 +31,9 @@ func _draw() -> void:
|
||||
draw_arc(Vector2.ZERO, radius, 0.0, TAU, 48, Color(0.1, 0.1, 0.1, 0.9), 4.0)
|
||||
# riflesso speculare
|
||||
draw_circle(Vector2(-radius * 0.3, -radius * 0.34), radius * 0.16, Color(1, 1, 1, 0.85))
|
||||
# segno che ruota mentre la biglia rotola
|
||||
var spot := Vector2(cos(roll_angle), sin(roll_angle)) * radius * 0.55
|
||||
draw_circle(spot, radius * 0.12, Color(0, 0, 0, 0.28))
|
||||
|
||||
|
||||
func setup(cn: String, c: Color, home: Vector2, left: Vector2, r: float) -> void:
|
||||
@@ -65,11 +69,18 @@ func launch(mt: float) -> void:
|
||||
if _tween and _tween.is_valid():
|
||||
_tween.kill()
|
||||
var half := maxf(mt * 0.5, 0.01)
|
||||
# rotazione proporzionale alla distanza percorsa (rotolamento)
|
||||
var dist := home_pos.x - left_pos.x
|
||||
var total_angle := dist / radius
|
||||
_tween = create_tween()
|
||||
_tween.tween_property(self, "position", left_pos, half) \
|
||||
.set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN_OUT)
|
||||
_tween.parallel().tween_property(self, "roll_angle", total_angle, half) \
|
||||
.set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN_OUT)
|
||||
_tween.tween_property(self, "position", home_pos, half) \
|
||||
.set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN_OUT)
|
||||
_tween.parallel().tween_property(self, "roll_angle", 0.0, half) \
|
||||
.set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN_OUT)
|
||||
_tween.finished.connect(_on_motion_done)
|
||||
|
||||
|
||||
|
||||
+71
-29
@@ -1,43 +1,85 @@
|
||||
extends Node2D
|
||||
## Plancia in stile hand-drawn/sketch: sfondo chiaro, 5 corsie grigie con
|
||||
## alloggiamenti circolari alle estremità (come il board di riferimento).
|
||||
## Plancia Juggle Board in legno: binari a TUTTA larghezza con larghezza
|
||||
## variabile (svasati alle estremità, stretti al centro), alloggiamenti
|
||||
## circolari incassati e indicatori numerici 1-5, come nel mockup.
|
||||
|
||||
const VIEW := Vector2(1280, 720)
|
||||
const LANE_TOP := 210.0
|
||||
const LANE_GAP := 98.0
|
||||
const HOME_X := 1130.0
|
||||
const LEFT_X := 300.0
|
||||
const CHANNEL_H := 44.0
|
||||
const SOCKET_R := 46.0
|
||||
const LANE_LEFT := 70.0 # centro alloggiamento sinistro
|
||||
const LANE_RIGHT := 1210.0 # centro alloggiamento destro
|
||||
const SOCKET_R := 46.0 # raggio alloggiamento (ampio alle estremità)
|
||||
const H_NARROW := 24.0 # semi-altezza canale al centro (stretto)
|
||||
const CENTER_X := (LANE_LEFT + LANE_RIGHT) / 2.0
|
||||
const HALF_SPAN := (LANE_RIGHT - LANE_LEFT) / 2.0
|
||||
|
||||
const BG := Color("#f7f5f0") # tono carta
|
||||
const FILL := Color("#b0b0b0")
|
||||
const OUTLINE := Color(0.1, 0.1, 0.1, 0.85)
|
||||
const LANE_FILL := Color("#c9ac7c")
|
||||
const LANE_EDGE := Color(0.22, 0.15, 0.08, 0.9)
|
||||
|
||||
var wood_tex: Texture2D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
z_index = -10
|
||||
wood_tex = load("res://assets/wood_board.png")
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
# sfondo plancia (tono carta)
|
||||
draw_rect(Rect2(Vector2.ZERO, VIEW), BG)
|
||||
# cornice esterna
|
||||
draw_rect(Rect2(Vector2.ZERO, VIEW), Color(0, 0, 0, 0.12), false, 3.0)
|
||||
for i in 5:
|
||||
# sfondo in legno
|
||||
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)
|
||||
for i in range(5):
|
||||
_draw_lane(LANE_TOP + i * LANE_GAP)
|
||||
_draw_number(i + 1, LANE_TOP + i * LANE_GAP)
|
||||
|
||||
|
||||
func _lane_half_width(x: float) -> float:
|
||||
# larghezza corsia: ampia alle estremità (d=1), stretta al centro (d=0)
|
||||
var d := absf(x - CENTER_X) / HALF_SPAN
|
||||
d = clampf(d, 0.0, 1.0)
|
||||
return H_NARROW + (SOCKET_R - H_NARROW) * d * d
|
||||
|
||||
|
||||
func _draw_lane(y: float) -> void:
|
||||
# canale centrale
|
||||
var ch := Rect2(LEFT_X, y - CHANNEL_H / 2.0, HOME_X - LEFT_X, CHANNEL_H)
|
||||
draw_rect(ch, FILL)
|
||||
draw_rect(ch, OUTLINE, false, 3.0)
|
||||
# ombra interna in alto (scanalatura incassata)
|
||||
draw_rect(Rect2(LEFT_X + 3, y - CHANNEL_H / 2.0 + 3.0, HOME_X - LEFT_X - 6, 3.0), Color(0, 0, 0, 0.18))
|
||||
# luce interna in basso
|
||||
draw_rect(Rect2(LEFT_X + 3, y + CHANNEL_H / 2.0 - 6.0, HOME_X - LEFT_X - 6, 3.0), Color(1, 1, 1, 0.25))
|
||||
# alloggiamenti circolari alle estremità (incassati)
|
||||
for cx in [LEFT_X, HOME_X]:
|
||||
var pts := PackedVector2Array()
|
||||
var steps := 48
|
||||
for k in range(steps + 1):
|
||||
var x := lerpf(LANE_LEFT, LANE_RIGHT, float(k) / steps)
|
||||
var hw := _lane_half_width(x)
|
||||
pts.append(Vector2(x, y - hw))
|
||||
for k in range(steps, -1, -1):
|
||||
var x := lerpf(LANE_LEFT, LANE_RIGHT, float(k) / steps)
|
||||
var hw := _lane_half_width(x)
|
||||
pts.append(Vector2(x, y + hw))
|
||||
draw_polygon(pts, [LANE_FILL])
|
||||
var closed := pts.duplicate()
|
||||
closed.append(pts[0])
|
||||
draw_polyline(closed, LANE_EDGE, 3.0, true)
|
||||
# alloggiamenti circolari incassati alle estremità
|
||||
for cx in [LANE_LEFT, LANE_RIGHT]:
|
||||
var c := Vector2(cx, y)
|
||||
draw_circle(c, SOCKET_R, FILL)
|
||||
draw_arc(c, SOCKET_R, 0.0, TAU, 48, OUTLINE, 3.0)
|
||||
# cavità: ombra in basso, luce in alto
|
||||
draw_circle(c + Vector2(0, 5), SOCKET_R - 7.0, Color(0, 0, 0, 0.12))
|
||||
draw_circle(c + Vector2(0, -5), SOCKET_R - 7.0, Color(1, 1, 1, 0.18))
|
||||
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))
|
||||
# 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))
|
||||
|
||||
|
||||
func _draw_number(n: int, y: float) -> void:
|
||||
var c := Vector2(38, y)
|
||||
var col: Color
|
||||
match n:
|
||||
1: col = Color("#de6b7e")
|
||||
2: col = Color("#1852de")
|
||||
3: col = Color("#88ce96")
|
||||
4: col = Color("#e8b84b")
|
||||
_: col = Color("#9b7ede")
|
||||
draw_circle(c, 22.0, col)
|
||||
draw_circle(c + Vector2(0, 2), 22.0, Color(0, 0, 0, 0.18))
|
||||
draw_arc(c, 22.0, 0.0, TAU, 32, Color(0.1, 0.1, 0.1, 0.85), 2.0)
|
||||
draw_string(ThemeDB.fallback_font, c + Vector2(-14, -10), str(n), HORIZONTAL_ALIGNMENT_CENTER, 28, 26, Color(1, 1, 1))
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://l7l3t71lt50f
|
||||
+19
-8
@@ -14,8 +14,8 @@ const VIEW := Vector2(1280, 720)
|
||||
const LANE_TOP := 210.0
|
||||
const LANE_GAP := 98.0
|
||||
const BALL_RADIUS := 40.0
|
||||
const HOME_X := 1130.0
|
||||
const LEFT_X := 300.0
|
||||
const HOME_X := 1210.0 # alloggiamento destro (a tutta larghezza)
|
||||
const LEFT_X := 70.0 # alloggiamento sinistro (a tutta larghezza)
|
||||
const HIT_RADIUS := BALL_RADIUS * 1.4 # area di tocco/clic (maggiorata)
|
||||
|
||||
# I valori di calibrazione (velocità, moltiplicatori, decay) sono gestiti dal
|
||||
@@ -123,7 +123,7 @@ func _toggle_options() -> void:
|
||||
|
||||
func _build_balls() -> void:
|
||||
var names := COLORS.keys()
|
||||
for i in names.size():
|
||||
for i in range(names.size()):
|
||||
var cn: String = names[i]
|
||||
var home := Vector2(HOME_X, LANE_TOP + i * LANE_GAP)
|
||||
var left := Vector2(LEFT_X, LANE_TOP + i * LANE_GAP)
|
||||
@@ -138,11 +138,22 @@ func _build_ui() -> void:
|
||||
var layer := CanvasLayer.new()
|
||||
add_child(layer)
|
||||
|
||||
var bar := ColorRect.new()
|
||||
bar.color = Color(0.97, 0.97, 0.97, 0.95)
|
||||
# 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)
|
||||
layer.add_child(bar)
|
||||
bar.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
bar_clip.add_child(bar)
|
||||
|
||||
var edge := ColorRect.new()
|
||||
edge.color = Color(0, 0, 0, 0.15)
|
||||
@@ -167,7 +178,7 @@ func _build_ui() -> void:
|
||||
help_label.size = Vector2(600, 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.1, 0.1, 0.1, 0.55))
|
||||
help_label.add_theme_color_override("font_color", Color(0.08, 0.07, 0.05, 0.78))
|
||||
layer.add_child(help_label)
|
||||
|
||||
score_label = Label.new()
|
||||
@@ -179,7 +190,7 @@ func _build_ui() -> void:
|
||||
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.1, 0.1, 0.1, 0.6))
|
||||
combo_label.add_theme_color_override("font_color", Color(0.08, 0.07, 0.05, 0.75))
|
||||
layer.add_child(combo_label)
|
||||
|
||||
# pulsante Opzioni
|
||||
|
||||
Reference in New Issue
Block a user