feat: add spreading mushroom to playground level
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
extends Node3D
|
||||
|
||||
@export var spread_radius := 2.0
|
||||
@export var spread_interval_min := 5.0
|
||||
@export var spread_interval_max := 15.0
|
||||
@export var max_mushrooms_in_radius := 3
|
||||
@export var check_radius := 1.5
|
||||
@export var max_total_mushrooms := 50
|
||||
|
||||
static var total_mushrooms := 0
|
||||
|
||||
@onready var spread_timer: Timer = $SpreadTimer
|
||||
@onready var ground_ray: RayCast3D = $GroundRay
|
||||
|
||||
func _ready() -> void:
|
||||
total_mushrooms += 1
|
||||
_setup_timer()
|
||||
|
||||
# Randomize initial scale for variety
|
||||
scale = Vector3.ONE * randf_range(0.8, 1.2)
|
||||
rotation.y = randf_range(0, TAU)
|
||||
|
||||
func _setup_timer() -> void:
|
||||
spread_timer.wait_time = randf_range(spread_interval_min, spread_interval_max)
|
||||
spread_timer.start()
|
||||
|
||||
func _on_spread_timer_timeout() -> void:
|
||||
if total_mushrooms >= max_total_mushrooms:
|
||||
return
|
||||
|
||||
if _count_nearby_mushrooms() >= max_mushrooms_in_radius:
|
||||
# Too crowded, try again later
|
||||
_setup_timer()
|
||||
return
|
||||
|
||||
_attempt_spread()
|
||||
_setup_timer()
|
||||
|
||||
func _attempt_spread() -> void:
|
||||
var random_angle := randf_range(0, TAU)
|
||||
var random_dist := randf_range(spread_radius * 0.5, spread_radius)
|
||||
var offset := Vector3(cos(random_angle) * random_dist, 5.0, sin(random_angle) * random_dist)
|
||||
|
||||
ground_ray.position = offset
|
||||
ground_ray.force_raycast_update()
|
||||
|
||||
if ground_ray.is_colliding():
|
||||
var collision_point := ground_ray.get_collision_point()
|
||||
var collision_normal := ground_ray.get_collision_normal()
|
||||
|
||||
# Only spread on relatively flat surfaces
|
||||
if collision_normal.dot(Vector3.UP) > 0.7:
|
||||
_spawn_mushroom(collision_point)
|
||||
|
||||
func _spawn_mushroom(pos: Vector3) -> void:
|
||||
var mushroom_scene = load(scene_file_path)
|
||||
var new_mushroom = mushroom_scene.instantiate()
|
||||
get_parent().add_child(new_mushroom)
|
||||
new_mushroom.global_position = pos
|
||||
|
||||
# Visual feedback/animation
|
||||
new_mushroom.scale = Vector3.ZERO
|
||||
var tween = create_tween()
|
||||
tween.tween_property(new_mushroom, "scale", Vector3.ONE * randf_range(0.8, 1.2), 1.0).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
|
||||
|
||||
func _count_nearby_mushrooms() -> int:
|
||||
var count := 0
|
||||
for mushroom in get_tree().get_nodes_in_group("mushrooms"):
|
||||
if mushroom == self: continue
|
||||
if global_position.distance_to(mushroom.global_position) < check_radius:
|
||||
count += 1
|
||||
return count
|
||||
|
||||
func _exit_tree() -> void:
|
||||
total_mushrooms -= 1
|
||||
Reference in New Issue
Block a user