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()