teststrecke-game/scripts/roadborder.gd
2024-12-04 16:30:43 +01:00

131 lines
4 KiB
GDScript

extends Line2D
const END_FITTING_DISTANCE=1 #fitting distance from end of pipe
const CORNER_FITTING_DISTANCE=4 #fitting of last pipe before a corner piece
const CORNER_NEXT_FITTING_DISTANCE=8 #fitting after corner
const PIPE_MAX_LENGTH=2*55 #1m=55,172px
const WEIGHT_DISTANCE_FROM_PIPE=9
const WEIGHT_RANDOM_OFFSET=0
const WEIGHT_DISTANCE_MIN=0.5*55
const WEIGHT_DISTANCE_MAX=4*55
const MIN_WEIGHT_DISTANCE_FROM_CORNER=20
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
#var staticbody=get_child(0) #get road collision object (StaticBody2D)
var rightborder=true
var staticbody:StaticBody2D=$road_r
if staticbody==null:
staticbody=$road_l
rightborder=false #is left border
addCaps($fitting)
addWeights($weight,rightborder)
var line_poly=Geometry2D.offset_polyline(points,width/2)
for poly in line_poly:
var col = CollisionPolygon2D.new()
col.polygon=poly
staticbody.add_child(col)
func addCaps(fitting:Sprite2D) -> void:
if fitting==null:
return
var lastp:Vector2
var skipfirst=true
for p:Vector2 in points:
if skipfirst:
lastp=p
skipfirst=false
continue #skip first
var line_angle=(p-lastp).angle()
#print("Point="+str(p)+" lastp="+str(lastp))
#Add end fitting
var fitting_distance_from_end=CORNER_FITTING_DISTANCE
if points.find(p)==points.size()-1:
fitting_distance_from_end=END_FITTING_DISTANCE
var line_end_fitting_point=p + (lastp-p).normalized()*fitting_distance_from_end
var newfitting:Sprite2D=fitting.duplicate()
newfitting.transform=Transform2D(line_angle,line_end_fitting_point)
add_child(newfitting)
#Add corner fitting (beginning of pipe)
if points.find(lastp)!=0: #if this pipe segment is not the first
var line_corner_fitting_point=lastp + (p-lastp).normalized()*CORNER_NEXT_FITTING_DISTANCE
var newcornerfitting:Sprite2D=fitting.duplicate()
newcornerfitting.transform=Transform2D(line_angle,line_corner_fitting_point)
add_child(newcornerfitting)
#add intermediate fittings
while (p-lastp).length()>PIPE_MAX_LENGTH:
var line_end_intfitting_point=lastp + (p-lastp).normalized()*PIPE_MAX_LENGTH
lastp=line_end_intfitting_point #update
var newintfitting:Sprite2D=fitting.duplicate()
newintfitting.transform=Transform2D(line_angle,line_end_intfitting_point)
add_child(newintfitting)
lastp=p
fitting.queue_free() #remote original fitting
func addWeights(weight:Sprite2D,rightborder:bool) -> void:
if weight==null:
return
print("Add weights, rightboarder="+str(rightborder))
var lengthWithoutSupport=0
var lastp:Vector2
var skipfirst=true
for p:Vector2 in points:
if skipfirst:
lastp=p
skipfirst=false
continue #skip first
var line_angle=(p-lastp).angle()
lengthWithoutSupport+=(p-lastp).length()
while lengthWithoutSupport>WEIGHT_DISTANCE_MAX:
var line_weight_point=lastp + (p-lastp).normalized()*min(randf_range(WEIGHT_DISTANCE_MIN,WEIGHT_DISTANCE_MAX),(p-lastp).length()-MIN_WEIGHT_DISTANCE_FROM_CORNER)
var newweight:Sprite2D=weight.duplicate()
if newweight.region_enabled:
var countTextures=newweight.texture.get_size().x/newweight.region_rect.size.x
print("countTextures="+str(countTextures))
newweight.region_rect.position.x=newweight.region_rect.size.x*randi_range(0,countTextures-1)
print(" using pos="+str(newweight.region_rect.position))
newweight.transform=Transform2D(0,line_weight_point+(Vector2.ONE*WEIGHT_DISTANCE_FROM_PIPE).rotated(line_angle+(90 if rightborder else -90))+Vector2(randf_range(-WEIGHT_RANDOM_OFFSET,WEIGHT_RANDOM_OFFSET),randf_range(-WEIGHT_RANDOM_OFFSET,WEIGHT_RANDOM_OFFSET)))
if rad_to_deg(line_angle)<-90 or rad_to_deg(line_angle)>90:
newweight.z_index=-1 #put behind
else:
newweight.z_index=1 #put in front
if not rightborder:
newweight.z_index*=-1 #flip for other side
add_child(newweight)
lastp=line_weight_point #update
lengthWithoutSupport=(p-lastp).length()
lastp=p
weight.queue_free()