Fix ball rolling animation (queue_redraw on roll_angle) and realistic marble design (codex)
This commit is contained in:
+46
-8
@@ -14,7 +14,10 @@ var radius := 40.0
|
|||||||
var home_pos := Vector2.ZERO
|
var home_pos := Vector2.ZERO
|
||||||
var left_pos := Vector2.ZERO
|
var left_pos := Vector2.ZERO
|
||||||
var in_motion := false
|
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
|
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))
|
draw_circle(Vector2(radius * 0.18, radius * 0.22), radius * 0.92, Color(0, 0, 0, 0.16))
|
||||||
# luce superiore-sinistra
|
# luce superiore-sinistra
|
||||||
draw_circle(Vector2(-radius * 0.18, -radius * 0.22), radius * 0.92, Color(1, 1, 1, 0.2))
|
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)
|
# 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)
|
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))
|
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:
|
func setup(cn: String, c: Color, home: Vector2, left: Vector2, r: float) -> void:
|
||||||
@@ -60,6 +97,7 @@ func reset() -> void:
|
|||||||
_tween.kill()
|
_tween.kill()
|
||||||
in_motion = false
|
in_motion = false
|
||||||
position = home_pos
|
position = home_pos
|
||||||
|
roll_angle = 0.0
|
||||||
|
|
||||||
|
|
||||||
## Lancia la pallina verso sinistra e la fa tornare a casa. `mt` è il tempo
|
## 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
|
in_motion = true
|
||||||
if _tween and _tween.is_valid():
|
if _tween and _tween.is_valid():
|
||||||
_tween.kill()
|
_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)
|
# rotazione proporzionale alla distanza percorsa (rotolamento)
|
||||||
var dist := home_pos.x - left_pos.x
|
var dist: float = home_pos.x - left_pos.x
|
||||||
var total_angle := dist / radius
|
var total_angle: float = dist / radius
|
||||||
_tween = create_tween()
|
_tween = create_tween()
|
||||||
_tween.tween_property(self, "position", left_pos, half) \
|
_tween.tween_property(self, "position", left_pos, half) \
|
||||||
.set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN_OUT)
|
.set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
|||||||
Reference in New Issue
Block a user