Skip to content

Commit 0d3b1df

Browse files
committed
feat: add sorting animation to merge sort
To do so, ArrayView had to be refactored to inherit Viewport so as to hide rectangles outside of the display bounds. Closes #2
1 parent a7c064a commit 0d3b1df

File tree

4 files changed

+28
-6
lines changed

4 files changed

+28
-6
lines changed

levels/merge_sort.gd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,22 @@ func next(action):
3131
if _left == _get_middle():
3232
if action != null and action != ACTIONS.RIGHT:
3333
return emit_signal("mistake")
34+
array.emit_signal("removed", _right)
3435
_right += 1
3536
elif _right == _get_end():
3637
if action != null and action != ACTIONS.LEFT:
3738
return emit_signal("mistake")
39+
array.emit_signal("removed", _left)
3840
_left += 1
3941
elif array.at(_left) <= array.at(_right):
4042
if action != null and action != ACTIONS.LEFT:
4143
return emit_signal("mistake")
44+
array.emit_signal("removed", _left)
4245
_left += 1
4346
else:
4447
if action != null and action != ACTIONS.RIGHT:
4548
return emit_signal("mistake")
49+
array.emit_signal("removed", _right)
4650
_right += 1
4751
# If both ends have been reached, merge and advance to next block
4852
if _left == _get_middle() and _right == _get_end():

models/array_model.gd

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
class_name ArrayModel
22
extends Reference
33

4-
signal swapped(i, j) # where i <= j
4+
# For all parameterized signals, i <= j
5+
signal removed(i)
6+
signal swapped(i, j)
7+
signal sorted(i, j)
58

69
var _array = []
710
var size = 0 setget , get_size
@@ -38,6 +41,7 @@ func sort(i, j):
3841
sorted.sort()
3942
var back = _array.slice(j, size - 1) if j != size else []
4043
_array = front + sorted + back
44+
emit_signal("sorted", i, j)
4145

4246
func get_size():
4347
return _array.size()

project.godot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ _global_script_classes=[ {
1414
"language": "GDScript",
1515
"path": "res://models/array_model.gd"
1616
}, {
17-
"base": "HBoxContainer",
17+
"base": "ViewportContainer",
1818
"class": "ArrayView",
1919
"language": "GDScript",
2020
"path": "res://views/array_view.gd"

views/array_view.gd

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,30 @@ Visualization of an array as rectangles of varying heights.
33
"""
44

55
class_name ArrayView
6-
extends HBoxContainer
6+
extends ViewportContainer
77

8-
const SWAP_DURATION = 0.1
8+
const ANIM_DURATION = 0.1
99

1010
var _tween = Tween.new()
1111
var _level: ComparisonSort
1212
var _rects = []
1313
var _positions = []
1414
var _unit_width: int
1515
var _unit_height: int
16+
var _viewport = Viewport.new()
1617
onready var _separation = 128 / _level.array.size
1718

1819
func _init(level):
1920
_level = level
21+
stretch = true
22+
_viewport.usage = Viewport.USAGE_2D
2023
add_child(_level) # NOTE: This is necessary for it to read input
2124
add_child(_tween) # NOTE: This is necessary for it to animate
25+
add_child(_viewport)
2226

2327
func _ready():
2428
yield(get_tree(), "idle_frame")
29+
_viewport.size = rect_size
2530
_unit_width = rect_size.x / _level.array.size
2631
_unit_height = rect_size.y / _level.array.size
2732
# Keep track of accumulated pixel error from integer division
@@ -45,16 +50,17 @@ func _ready():
4550
_positions.append(x)
4651
x += _unit_width
4752
_rects.append(rect)
48-
add_child(rect)
53+
_viewport.add_child(rect)
4954
_level.array.connect("swapped", self, "_on_ArrayModel_swapped")
55+
_level.array.connect("sorted", self, "_on_ArrayModel_sorted")
5056

5157
func _process(delta):
5258
for i in range(_rects.size()):
5359
_rects[i].color = _level.get_effect(i)
5460
_rects[i].scale.y = -float(_level.array.at(i)) / _level.array.size
5561

5662
func _on_ArrayModel_swapped(i, j):
57-
var time = SWAP_DURATION * (1 + float(j - i) / _level.array.size)
63+
var time = ANIM_DURATION * (1 + float(j - i) / _level.array.size)
5864
_tween.interpolate_property(
5965
_rects[i], "position:x", null, _positions[j], time)
6066
_tween.interpolate_property(
@@ -63,3 +69,11 @@ func _on_ArrayModel_swapped(i, j):
6369
_rects[i] = _rects[j]
6470
_rects[j] = temp
6571
_tween.start()
72+
73+
func _on_ArrayModel_sorted(i, j):
74+
for x in range(i, j):
75+
_rects[x].position.y = 0
76+
for x in range(i, j):
77+
_tween.interpolate_property(
78+
_rects[x], "position:y", null, rect_size.y, ANIM_DURATION)
79+
_tween.start()

0 commit comments

Comments
 (0)