150 lines
6.5 KiB
GDScript
150 lines
6.5 KiB
GDScript
extends Control
|
|
signal finished
|
|
const DURATION := 4.0
|
|
const SHIP := preload("res://assets/planets/freighter.png")
|
|
var start_position := Vector2.ZERO
|
|
var destination_name := "ODLEGŁY SEKTOR"
|
|
var elapsed := 0.0
|
|
var _ship: Sprite2D
|
|
var _flash: ColorRect
|
|
var _title: Label
|
|
var _status: Label
|
|
var _stars: Array[Vector3] = []
|
|
var _done := false
|
|
|
|
func _ready() -> void:
|
|
process_mode = Node.PROCESS_MODE_ALWAYS
|
|
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
mouse_filter = Control.MOUSE_FILTER_STOP
|
|
var rng := RandomNumberGenerator.new()
|
|
rng.seed = 872901
|
|
for star in 170: _stars.append(Vector3(rng.randf(),rng.randf(),rng.randf_range(0.3,1.0)))
|
|
_ship = Sprite2D.new()
|
|
_ship.texture = SHIP
|
|
_ship.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS
|
|
add_child(_ship)
|
|
_flash = ColorRect.new()
|
|
_flash.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
_flash.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
add_child(_flash)
|
|
_title = _label(destination_name.to_upper(),18,Color("c4f3ff"))
|
|
_status = _label("INICJALIZACJA NAPĘDU SKOKOWEGO",11,Color("6eaeba"))
|
|
_play_audio()
|
|
_update_frame()
|
|
|
|
func _label(value: String, font_size: int, color: Color) -> Label:
|
|
var label := Label.new()
|
|
label.text = value
|
|
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
label.add_theme_font_size_override("font_size",font_size)
|
|
label.add_theme_color_override("font_color",color)
|
|
label.add_theme_color_override("font_outline_color",Color("020810"))
|
|
label.add_theme_constant_override("outline_size",5)
|
|
add_child(label)
|
|
return label
|
|
|
|
func _input(_event: InputEvent) -> void:
|
|
get_viewport().set_input_as_handled()
|
|
|
|
func _process(delta: float) -> void:
|
|
elapsed = minf(DURATION,elapsed+delta)
|
|
_update_frame()
|
|
if elapsed >= DURATION and not _done:
|
|
_done = true
|
|
finished.emit()
|
|
|
|
func _update_frame() -> void:
|
|
var charge := smoothstep(0.0,0.9,elapsed)
|
|
var acceleration := smoothstep(0.8,2.6,elapsed)
|
|
var jump := smoothstep(2.6,3.15,elapsed)
|
|
var center := Vector2(size.x*0.5,size.y*0.64)
|
|
var departure := start_position if start_position != Vector2.ZERO else center
|
|
var ship_position := departure.lerp(center,charge)
|
|
ship_position.y -= size.y*(0.16*acceleration+0.24*jump)
|
|
var height := lerpf(285.0,minf(440.0,size.y*0.61),charge)
|
|
height *= 1.0-jump*0.93
|
|
_ship.position = ship_position
|
|
_ship.scale = Vector2(height/SHIP.get_height()*(1.0-jump*0.6),height/SHIP.get_height())
|
|
_ship.modulate = Color(1.0+acceleration*0.3,1.0+acceleration*0.5,1.0+acceleration*0.7,1.0-jump)
|
|
_ship.visible = elapsed < 3.18
|
|
var flash := exp(-pow((elapsed-3.15)/0.10,2.0))*0.9
|
|
var blackout := smoothstep(3.55,DURATION,elapsed)
|
|
_flash.color = Color(0.55,0.87,1.0,flash) if flash > blackout else Color(0.015,0.025,0.045,blackout)
|
|
_title.position = Vector2(0,28)
|
|
_title.size = Vector2(size.x,30)
|
|
_status.position = Vector2(0,61)
|
|
_status.size = Vector2(size.x,22)
|
|
_status.text = "SKOK WARP" if elapsed > 2.6 else ("PRZYSPIESZANIE · TRASA ZABEZPIECZONA" if elapsed > 0.9 else "INICJALIZACJA NAPĘDU SKOKOWEGO")
|
|
_title.modulate.a = 1.0-blackout
|
|
_status.modulate.a = 1.0-blackout
|
|
queue_redraw()
|
|
|
|
func _draw() -> void:
|
|
var charge := smoothstep(0.0,0.9,elapsed)
|
|
var acceleration := smoothstep(0.8,2.6,elapsed)
|
|
var jump := smoothstep(2.6,3.15,elapsed)
|
|
draw_rect(Rect2(Vector2.ZERO,size),Color(0.005,0.014,0.03,charge*0.96))
|
|
for star in _stars:
|
|
var y := fmod(star.y*size.y+elapsed*(18.0+acceleration*180.0+jump*1200.0)*star.z,size.y+160.0)-80.0
|
|
var point := Vector2(star.x*size.x,y)
|
|
var length := 1.0+acceleration*star.z*34.0+jump*star.z*150.0
|
|
draw_line(point,point+Vector2(0,length),Color(0.4,0.75,1.0,charge*star.z*0.55),1.0,true)
|
|
if _ship != null and _ship.visible and jump < 0.98:
|
|
var height: float = SHIP.get_height()*_ship.scale.y
|
|
var tail: Vector2 = _ship.position+Vector2(0,height*0.45)
|
|
var power := (0.2+charge*0.5+acceleration*0.7)*(1.0-jump)
|
|
for side in [-1.0,1.0]:
|
|
var nozzle := tail+Vector2(side*height*0.075,0)
|
|
for halo in range(6,0,-1): draw_circle(nozzle,halo*7.0*power,Color(0.1,0.7,1.0,0.018*power))
|
|
var flame := (35.0+acceleration*170.0)*power*(0.94+sin(elapsed*71.0)*0.06)
|
|
for layer in 3:
|
|
var width := (13.0-layer*3.2)*power
|
|
var tip := nozzle+Vector2(sin(elapsed*43.0+side)*minf(4.0,width*0.2),flame*(1.0-layer*0.2))
|
|
var colors := [Color(0.08,0.4,1.0,0.25),Color(0.2,0.85,1.0,0.65),Color(0.85,1.0,1.0,0.95)]
|
|
draw_colored_polygon(PackedVector2Array([nozzle+Vector2(-width,-8),nozzle+Vector2(width,-8),nozzle+Vector2(width*0.65,flame*0.3),tip,nozzle+Vector2(-width*0.65,flame*0.3)]),colors[layer])
|
|
var portal := smoothstep(1.75,2.75,elapsed)*(1.0-smoothstep(3.18,3.6,elapsed))
|
|
var gate := Vector2(size.x*0.5,size.y*0.24)
|
|
if portal > 0.001:
|
|
draw_set_transform(gate,0,Vector2(1,0.24))
|
|
for halo in range(8,0,-1): draw_circle(Vector2.ZERO,(100.0+halo*6)*portal,Color(0.15,0.65,1.0,0.014))
|
|
draw_circle(Vector2.ZERO,104*portal,Color(0.01,0.035,0.065,0.95))
|
|
for ring in 3:
|
|
draw_arc(Vector2.ZERO,(102+ring*5)*portal,elapsed*(2+ring),elapsed*(2+ring)+TAU*0.91,96,Color(0.4+ring*0.2,0.8+ring*0.07,1.0,0.8),2.0,true)
|
|
draw_set_transform(Vector2.ZERO)
|
|
if elapsed > 3.05:
|
|
var flare := exp(-pow((elapsed-3.16)/0.12,2.0))
|
|
for layer in range(6,0,-1):
|
|
draw_line(gate-Vector2(size.x*0.45,0),gate+Vector2(size.x*0.45,0),Color(0.3,0.8,1.0,flare*0.07),float(layer*4),true)
|
|
var ring_time := maxf(0.0,elapsed-3.15)
|
|
draw_arc(gate,20.0+ring_time*650.0,0,TAU,96,Color(0.4,0.85,1.0,maxf(0.0,0.65-ring_time)),2.0,true)
|
|
draw_line(gate,gate+Vector2(0,-size.y),Color(0.8,0.98,1.0,flare),4.0+flare*24.0,true)
|
|
|
|
func _play_audio() -> void:
|
|
var rate := 22050
|
|
var data := PackedByteArray()
|
|
data.resize(int(DURATION*rate)*2)
|
|
var rng := RandomNumberGenerator.new()
|
|
rng.seed = 73902
|
|
var phase := 0.0
|
|
var noise := 0.0
|
|
for sample in int(DURATION*rate):
|
|
var t := float(sample)/rate
|
|
var rise := smoothstep(0.0,3.1,t)
|
|
phase += TAU*(38.0+rise*140.0)/rate
|
|
noise = lerpf(noise,rng.randf_range(-1,1),0.12+rise*0.2)
|
|
var envelope := smoothstep(0,0.3,t)*(1.0-smoothstep(3.15,3.8,t))
|
|
var rush := exp(-pow((t-3.14)/0.16,2.0))
|
|
var value := (sin(phase)*0.13+sin(phase*1.51)*0.05+noise*(0.1+rise*0.25))*envelope+noise*rush*0.55
|
|
data.encode_s16(sample*2,int(clampf(value,-0.9,0.9)*32767))
|
|
var stream := AudioStreamWAV.new()
|
|
stream.format = AudioStreamWAV.FORMAT_16_BITS
|
|
stream.mix_rate = rate
|
|
stream.data = data
|
|
var audio := AudioStreamPlayer.new()
|
|
audio.stream = stream
|
|
audio.volume_db = -9.0
|
|
if AudioServer.get_bus_index("Effects") >= 0: audio.bus = &"Effects"
|
|
add_child(audio)
|
|
audio.play()
|