From 94f05adf344afbdb26b2e5a8881d2a0816cb122e Mon Sep 17 00:00:00 2001 From: enne2 Date: Tue, 18 Aug 2026 17:46:34 +0200 Subject: [PATCH] Fix ball rolling animation (queue_redraw on roll_angle) and realistic marble design (codex) --- scripts/ball.gd | 54 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/scripts/ball.gd b/scripts/ball.gd index f5fd0a2..fb3f84d 100644 --- a/scripts/ball.gd +++ b/scripts/ball.gd @@ -14,7 +14,10 @@ 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 roll_angle := 0.0: + set(v): + roll_angle = v + queue_redraw() # aggiorna il disegno a ogni step di rotazione var _tween: Tween @@ -27,13 +30,47 @@ func _draw() -> void: draw_circle(Vector2(radius * 0.18, radius * 0.22), radius * 0.92, Color(0, 0, 0, 0.16)) # luce superiore-sinistra draw_circle(Vector2(-radius * 0.18, -radius * 0.22), radius * 0.92, Color(1, 1, 1, 0.2)) + # marmorizzazione a vortici che ruota col rotolamento (design realistico) + _draw_marbling() # bordo nero spesso (stile china) draw_arc(Vector2.ZERO, radius, 0.0, TAU, 48, Color(0.1, 0.1, 0.1, 0.9), 4.0) - # riflesso speculare + # riflesso speculare (fisso: la luce non ruota con la superficie) 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 _draw_marbling() -> void: + # Tre venature curve, irregolari e non simmetriche. Tutta la geometria + # superficiale ruota; illuminazione e riflesso vengono invece disegnati dopo. + var vein_color: Color = ball_color.darkened(0.42) + vein_color.a = 0.20 + var soft_color: Color = ball_color.darkened(0.28) + soft_color.a = 0.12 + var veins: Array[PackedVector2Array] = [ + _make_vein(-0.72, -0.22, 0.68, -0.06, 0.15, 0.09), + _make_vein(-0.55, 0.34, 0.34, 0.60, -0.13, 0.07), + _make_vein(-0.18, -0.64, 0.58, -0.40, -0.10, 0.06), + ] + for i: int in range(veins.size()): + var rotated_points := PackedVector2Array() + for point: Vector2 in veins[i]: + rotated_points.append(point.rotated(roll_angle)) + var width: float = radius * (0.075 if i == 0 else 0.045) + draw_polyline(rotated_points, soft_color, width * 1.9, true) + draw_polyline(rotated_points, vein_color, width, true) + + +func _make_vein(x0: float, y0: float, x1: float, y1: float, + bend: float, ripple: float) -> PackedVector2Array: + var points := PackedVector2Array() + var direction := Vector2(x1 - x0, y1 - y0) + var normal := direction.normalized().orthogonal() + for step: int in range(17): + var t: float = float(step) / 16.0 + var base := Vector2(lerpf(x0, x1, t), lerpf(y0, y1, t)) + var curve: float = sin(t * PI) * bend + var wave: float = sin(t * TAU * 1.35 + x0 * 4.0) * ripple + points.append((base + normal * (curve + wave)) * radius) + return points func setup(cn: String, c: Color, home: Vector2, left: Vector2, r: float) -> void: @@ -60,6 +97,7 @@ func reset() -> void: _tween.kill() in_motion = false position = home_pos + roll_angle = 0.0 ## Lancia la pallina verso sinistra e la fa tornare a casa. `mt` รจ il tempo @@ -68,10 +106,10 @@ func launch(mt: float) -> void: in_motion = true if _tween and _tween.is_valid(): _tween.kill() - var half := maxf(mt * 0.5, 0.01) + var half: float = 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 + var dist: float = home_pos.x - left_pos.x + var total_angle: float = dist / radius _tween = create_tween() _tween.tween_property(self, "position", left_pos, half) \ .set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN_OUT)