Skip to content

Commit a74cb50

Browse files
committed
fix: prevent animation race condition
Save initial positions of array bars so that if the user presses a button so fast that one animation begins before the previous was finished, the positions wouldn't be messed up.
1 parent 96414dc commit a74cb50

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

views/array_view.gd

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ class_name ArrayView
66
extends HBoxContainer
77

88
const SWAP_DURATION = 0.1
9-
const TRANS_TYPE = Tween.TRANS_LINEAR
10-
const EASE_TYPE = Tween.EASE_IN_OUT
119

1210
var _tween = Tween.new()
1311
var _level: ComparisonSort
1412
var _rects = []
13+
# Save initial positions to prevent animation race condition
14+
var _positions = []
15+
var _unit_height: int
1516

1617
func _init(level):
1718
"""Add colored rectangles."""
1819
_level = level
19-
_level.connect("mistake", self, "_on_Level_mistake")
2020
_level.array.connect("swapped", self, "_on_ArrayModel_swapped")
2121
add_child(_level) # NOTE: This is necessary for it to read input
2222
for i in range(level.array.size):
@@ -26,24 +26,31 @@ func _init(level):
2626
_rects.append(rect)
2727
add_child(rect)
2828
add_child(_tween) # NOTE: This is necessary for it to animate
29+
_positions.resize(_level.array.size)
30+
31+
func _ready():
32+
_level.connect("mistake", get_parent(), "flash")
33+
34+
func _draw():
35+
# HACK: Workaround for resized signal not firing when window resized
36+
_unit_height = rect_size.y / _level.array.size
37+
for i in range(_rects.size()):
38+
_rects[i].rect_scale.y = -1
39+
_positions[i] = _rects[i].rect_position
2940

3041
func _process(delta):
3142
"""Update heights of rectangles based on array values."""
32-
for i in range(_level.array.size):
33-
_rects[i].rect_scale.y = -1 # HACK: Override scale to bypass weird behavior
43+
for i in range(_rects.size()):
3444
_rects[i].color = _level.get_effect(i)
35-
_rects[i].rect_size.y = rect_size.y * _level.array.at(i) / _level.array.size
36-
37-
func _on_Level_mistake():
38-
"""Flash the border red on mistakes."""
39-
get_parent().flash()
45+
_rects[i].rect_size.y = _level.array.at(i) * _unit_height
4046

4147
func _on_ArrayModel_swapped(i, j):
4248
"""Produce a swapping animation."""
43-
_tween.interpolate_property(_rects[i], "rect_position",
44-
null, _rects[j].rect_position, SWAP_DURATION, TRANS_TYPE, EASE_TYPE)
45-
_tween.interpolate_property(_rects[j], "rect_position",
46-
null, _rects[i].rect_position, SWAP_DURATION, TRANS_TYPE, EASE_TYPE)
49+
var time = SWAP_DURATION * (1 + float(j - i) / _level.array.size)
50+
_tween.interpolate_property(
51+
_rects[i], "rect_position", null, _positions[j], time)
52+
_tween.interpolate_property(
53+
_rects[j], "rect_position", null, _positions[i], time)
4754
var temp = _rects[i]
4855
_rects[i] = _rects[j]
4956
_rects[j] = temp

0 commit comments

Comments
 (0)