Documented and adjusted vine initialization
This commit is contained in:
parent
808ffb337e
commit
8ca085192d
3 changed files with 38 additions and 22 deletions
|
|
@ -31,3 +31,7 @@ func _enter_grid() -> void:
|
||||||
func _init(_location = Vector2.ZERO, _offset = Vector2.ZERO):
|
func _init(_location = Vector2.ZERO, _offset = Vector2.ZERO):
|
||||||
location = _location
|
location = _location
|
||||||
offset = _offset
|
offset = _offset
|
||||||
|
|
||||||
|
static func random_at(_location):
|
||||||
|
var rand_offset = Vector2(randf_range(60, 240), randf_range(90, 270))
|
||||||
|
return GridNode.new(_location, rand_offset)
|
||||||
|
|
|
||||||
|
|
@ -23,5 +23,5 @@ func spread():
|
||||||
# Grow a vine
|
# Grow a vine
|
||||||
func grow_to_next_bud(dir):
|
func grow_to_next_bud(dir):
|
||||||
var target_location = Global.vec_mod(location + dir, Grid.num_collumns, true)
|
var target_location = Global.vec_mod(location + dir, Grid.num_collumns, true)
|
||||||
var target = vine.random_vine_node_at(target_location)
|
var target = GridNode.random_at(target_location)
|
||||||
await vine.grow_vine_sequence(self, target, true, false)
|
await vine.grow_vine_sequence(self, target, true, false)
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ var status_params : Dictionary = {}
|
||||||
# When max depth is reached, everything is active from then on.
|
# When max depth is reached, everything is active from then on.
|
||||||
var active_depth = -1
|
var active_depth = -1
|
||||||
var fully_active = false
|
var fully_active = false
|
||||||
var max_depth = 10
|
var max_depth = 50
|
||||||
|
|
||||||
# Array containings lists of sprites, using their depths as index
|
# Array containings lists of sprites, using their depths as index
|
||||||
var vine_data = []
|
var vine_data = []
|
||||||
|
|
@ -86,21 +86,29 @@ func grow_vine_sequence(start : GridNode, target: GridNode, grow_bud = false, qu
|
||||||
if not quick_spawn:
|
if not quick_spawn:
|
||||||
await get_tree().create_timer(0.2).timeout
|
await get_tree().create_timer(0.2).timeout
|
||||||
|
|
||||||
|
# If growing while active, place buds
|
||||||
if active_depth >= depth + num_segments or fully_active:
|
if active_depth >= depth + num_segments or fully_active:
|
||||||
if grow_bud and target.location.y > 0 and target.location.y <= Grid.max_bud_height:
|
if grow_bud and target.location.y > 0 and target.location.y <= Grid.max_bud_height:
|
||||||
spawn_bud(target.location, target.offset, depth + num_segments)
|
spawn_bud(target.location, target.offset, depth + num_segments)
|
||||||
else:
|
else:
|
||||||
|
# Otherwise, remember the spot to spawn a bud later.
|
||||||
|
# Further, note that the previous location is no longer a leaf unless it is the petal.
|
||||||
if target.location.y > 0 and target.location.y <= Grid.max_bud_height:
|
if target.location.y > 0 and target.location.y <= Grid.max_bud_height:
|
||||||
for i in range(vine_end_data.size()):
|
for i in range(vine_end_data.size()):
|
||||||
if vine_end_data[i].location == start.location:
|
if vine_end_data[i].location == start.location and not vine_end_data[i] is Petal:
|
||||||
vine_end_data.remove_at(i)
|
vine_end_data.remove_at(i)
|
||||||
break
|
break
|
||||||
target.depth = depth + num_segments
|
target.depth = depth + num_segments
|
||||||
vine_end_data.append(target)
|
vine_end_data.append(target)
|
||||||
|
|
||||||
|
# Register the new vine segment in the grid
|
||||||
Grid.add_vine_to(self, target.location)
|
Grid.add_vine_to(self, target.location)
|
||||||
vine_locations.append(Global.vec_mod(target.location, Grid.num_collumns, true))
|
vine_locations.append(Global.vec_mod(target.location, Grid.num_collumns, true))
|
||||||
|
|
||||||
|
# Generates a random function on (segment_count - 1)
|
||||||
|
# many grid points with bounded second derivative
|
||||||
func generate_random_offsets(segment_count, max_second_derivative):
|
func generate_random_offsets(segment_count, max_second_derivative):
|
||||||
|
# First, randomize the derivative of the desired function
|
||||||
var differences = []
|
var differences = []
|
||||||
var last_diff = 0
|
var last_diff = 0
|
||||||
for i in range(segment_count):
|
for i in range(segment_count):
|
||||||
|
|
@ -108,11 +116,15 @@ func generate_random_offsets(segment_count, max_second_derivative):
|
||||||
differences.append(new_diff)
|
differences.append(new_diff)
|
||||||
last_diff = new_diff
|
last_diff = new_diff
|
||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
|
|
||||||
|
# Shift that derivative by a constant to add up to 0
|
||||||
for i in range(segment_count):
|
for i in range(segment_count):
|
||||||
sum += differences[i]
|
sum += differences[i]
|
||||||
var correction = - sum / segment_count
|
var correction = - sum / segment_count
|
||||||
for i in range(segment_count):
|
for i in range(segment_count):
|
||||||
differences[i] += correction
|
differences[i] += correction
|
||||||
|
|
||||||
|
# Return the partial sums over the derivative constructed above
|
||||||
var ret = []
|
var ret = []
|
||||||
var next_val = 0
|
var next_val = 0
|
||||||
for i in range(segment_count):
|
for i in range(segment_count):
|
||||||
|
|
@ -120,6 +132,7 @@ func generate_random_offsets(segment_count, max_second_derivative):
|
||||||
next_val += differences[i]
|
next_val += differences[i]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
# Instantiates a bud
|
||||||
func spawn_bud(location, offset, depth):
|
func spawn_bud(location, offset, depth):
|
||||||
var bud = bud_resource.instantiate()
|
var bud = bud_resource.instantiate()
|
||||||
bud.location = location
|
bud.location = location
|
||||||
|
|
@ -128,9 +141,13 @@ func spawn_bud(location, offset, depth):
|
||||||
bud.depth = depth
|
bud.depth = depth
|
||||||
get_tree().get_root().get_node("main").add_child(bud)
|
get_tree().get_root().get_node("main").add_child(bud)
|
||||||
|
|
||||||
|
# Upon activation start the process of slowly increasing the active depth
|
||||||
func activate():
|
func activate():
|
||||||
update_active_depth()
|
if active_depth < 0:
|
||||||
|
update_active_depth()
|
||||||
|
|
||||||
|
# Progressively activate the vine by retexturing its sprites and spawning buds if neccessary
|
||||||
|
# Once max_depth is reached, fully activate the vine
|
||||||
func update_active_depth():
|
func update_active_depth():
|
||||||
if active_depth < max_depth:
|
if active_depth < max_depth:
|
||||||
await get_tree().create_timer(0.15).timeout
|
await get_tree().create_timer(0.15).timeout
|
||||||
|
|
@ -138,12 +155,13 @@ func update_active_depth():
|
||||||
if vine_data.size() > active_depth:
|
if vine_data.size() > active_depth:
|
||||||
for sprite in vine_data[active_depth]:
|
for sprite in vine_data[active_depth]:
|
||||||
sprite.texture = ResourceLoader.load(img_path_active)
|
sprite.texture = ResourceLoader.load(img_path_active)
|
||||||
for data in vine_end_data:
|
for node in vine_end_data:
|
||||||
if data.depth == active_depth:
|
if node.depth == active_depth and not node is Petal:
|
||||||
spawn_bud(data.location, data.offset, data.depth)
|
spawn_bud(node.location, node.offset, node.depth)
|
||||||
update_active_depth()
|
update_active_depth()
|
||||||
else: fully_active = true
|
else: fully_active = true
|
||||||
|
|
||||||
|
# Upon entering the scene, select the applied status, then spawn the inactive vine
|
||||||
func _enter_tree() -> void:
|
func _enter_tree() -> void:
|
||||||
var data : Dictionary = status_data.pick_random()
|
var data : Dictionary = status_data.pick_random()
|
||||||
status_name = data.name
|
status_name = data.name
|
||||||
|
|
@ -151,27 +169,21 @@ func _enter_tree() -> void:
|
||||||
img_path_active = data.img_path
|
img_path_active = data.img_path
|
||||||
init_random()
|
init_random()
|
||||||
|
|
||||||
func random_vine_node_at(location):
|
# Initializes a random vine
|
||||||
var offset = random_offset()
|
|
||||||
return GridNode.new(location, offset)
|
|
||||||
|
|
||||||
func init_random():
|
func init_random():
|
||||||
|
# First, include the petal
|
||||||
Grid.add_vine_to(self, petal.location)
|
Grid.add_vine_to(self, petal.location)
|
||||||
vine_locations.append(petal.location)
|
vine_locations.append(petal.location)
|
||||||
vine_end_data.append(petal)
|
vine_end_data.append(petal)
|
||||||
for i in range(randi_range(2,2)):
|
# Attempt to grow a new vine for a total 6 - 12 times
|
||||||
|
var grow_attempts = randi_range(6,12)
|
||||||
|
while grow_attempts > 0:
|
||||||
|
# Attempt to grow from a random end to 1 - 4 random directions
|
||||||
var end = vine_end_data.pick_random()
|
var end = vine_end_data.pick_random()
|
||||||
var branches_count = 0
|
for branch in range(min(ceil(randf() * 4), grow_attempts)):
|
||||||
for branch in range(ceil(randf() * 4)):
|
grow_attempts -= 1
|
||||||
var dir = [Vector2.UP, Vector2.DOWN, Vector2.RIGHT, Vector2.LEFT].pick_random()
|
var dir = [Vector2.UP, Vector2.DOWN, Vector2.RIGHT, Vector2.LEFT].pick_random()
|
||||||
var target_location = Global.vec_mod(end.location + dir, Grid.num_collumns, true)
|
var target_location = Global.vec_mod(end.location + dir, Grid.num_collumns, true)
|
||||||
if target_location.y <= Grid.max_bud_height + 1 and Grid.get_vines_at(target_location).is_empty():
|
if target_location.y <= Grid.max_bud_height + 1 and Grid.get_vines_at(target_location).is_empty():
|
||||||
if not (target_location.y <= 0 or target_location.y > Grid.max_bud_height):
|
var target = GridNode.random_at(target_location)
|
||||||
branches_count += 1
|
|
||||||
var target = random_vine_node_at(target_location)
|
|
||||||
grow_vine_sequence(end, target, true, true)
|
grow_vine_sequence(end, target, true, true)
|
||||||
if i==0 and branches_count == 1:
|
|
||||||
vine_end_data.append(petal)
|
|
||||||
|
|
||||||
func random_offset():
|
|
||||||
return Vector2(randf_range(60, 240), randf_range(90, 270))
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue