This commit is contained in:
Tomasz Boruc 2026-10-09 20:59:55 +02:00
parent 4219d50445
commit 9f0346dbce
15 changed files with 276 additions and 42 deletions

Binary file not shown.

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://fuxp5amihmlw"
path="res://.godot/imported/engine.mp3-abed1efbf987bf6ef3f75ae367830962.mp3str"
[deps]
source_file="res://assets/sounds/effects/engine.mp3"
dest_files=["res://.godot/imported/engine.mp3-abed1efbf987bf6ef3f75ae367830962.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@ -7,13 +7,13 @@ script = ExtResource("1_definition")
item_id = "missile_launcher" item_id = "missile_launcher"
display_name = "Wyrzutnia rakiet" display_name = "Wyrzutnia rakiet"
category = 0 category = 0
description = "Wystrzeliwuje wolną rakietę z eksplozją obszarową. Cooldown: 5 s." description = "Wystrzeliwuje naprowadzaną rakietę z eksplozją obszarową. Cooldown: 5 s."
primary_stat = "damage" primary_stat = "damage"
primary_value = 60.0 primary_value = 60.0
stat_suffix = " DMG" stat_suffix = " DMG"
weapon_kind = 3 weapon_kind = 3
fire_interval = 5.0 fire_interval = 5.0
weapon_cooldown = 5.0 weapon_cooldown = 5.0
projectile_speed = 220.0 projectile_speed = 440.0
weapon_range = 1000.0 weapon_range = 1000.0
energy_cost = 25.0 energy_cost = 25.0

View File

@ -7,6 +7,7 @@
[ext_resource type="PackedScene" path="res://scenes/ui/ship_equipment_panel.tscn" id="5_equipment"] [ext_resource type="PackedScene" path="res://scenes/ui/ship_equipment_panel.tscn" id="5_equipment"]
[ext_resource type="PackedScene" path="res://scenes/ui/ship_inventory_panel.tscn" id="6_inventory"] [ext_resource type="PackedScene" path="res://scenes/ui/ship_inventory_panel.tscn" id="6_inventory"]
[ext_resource type="PackedScene" path="res://scenes/game/weapon_test_target.tscn" id="7_target"] [ext_resource type="PackedScene" path="res://scenes/game/weapon_test_target.tscn" id="7_target"]
[ext_resource type="Script" path="res://scripts/game/scene_music_player.gd" id="8_scene_music"]
[sub_resource type="RectangleShape2D" id="TopWall"] [sub_resource type="RectangleShape2D" id="TopWall"]
size = Vector2(5200, 40) size = Vector2(5200, 40)
@ -23,6 +24,11 @@ size = Vector2(40, 3600)
[node name="Game" type="Node2D" unique_id=1630707678] [node name="Game" type="Node2D" unique_id=1630707678]
script = ExtResource("1_game") script = ExtResource("1_game")
[node name="GameMusic" type="AudioStreamPlayer" parent="." unique_id=784369202]
script = ExtResource("8_scene_music")
track_path = "res://assets/sounds/music/game_music.mp3"
playback_volume_db = -17.0
[node name="SpaceBackground" type="Node2D" parent="." unique_id=300719476] [node name="SpaceBackground" type="Node2D" parent="." unique_id=300719476]
z_index = -20 z_index = -20
script = ExtResource("2_background") script = ExtResource("2_background")

View File

@ -4,6 +4,8 @@
[ext_resource type="Script" path="res://scripts/items/ship_inventory.gd" id="2_inventory"] [ext_resource type="Script" path="res://scripts/items/ship_inventory.gd" id="2_inventory"]
[ext_resource type="Script" path="res://scripts/game/weapon_controller.gd" id="3_weapons"] [ext_resource type="Script" path="res://scripts/game/weapon_controller.gd" id="3_weapons"]
[ext_resource type="Script" path="res://scripts/game/shield_visual.gd" id="4_shield"] [ext_resource type="Script" path="res://scripts/game/shield_visual.gd" id="4_shield"]
[ext_resource type="Script" path="res://scripts/game/ship_engine_audio.gd" id="5_engine_audio"]
[ext_resource type="Script" path="res://scripts/game/engine_visual.gd" id="6_engine_visual"]
[sub_resource type="CircleShape2D" id="ShipCollision"] [sub_resource type="CircleShape2D" id="ShipCollision"]
radius = 18.0 radius = 18.0
@ -31,3 +33,9 @@ script = ExtResource("2_inventory")
[node name="WeaponController" type="Node" parent="."] [node name="WeaponController" type="Node" parent="."]
script = ExtResource("3_weapons") script = ExtResource("3_weapons")
[node name="EngineAudio" type="AudioStreamPlayer" parent="."]
script = ExtResource("5_engine_audio")
[node name="EngineVisual" type="Node2D" parent="."]
script = ExtResource("6_engine_visual")

View File

@ -2,6 +2,7 @@
[ext_resource type="Script" uid="uid://csjojorlptcs1" path="res://scripts/ui/main_menu.gd" id="1_script"] [ext_resource type="Script" uid="uid://csjojorlptcs1" path="res://scripts/ui/main_menu.gd" id="1_script"]
[ext_resource type="Texture2D" uid="uid://bfc6l14s8iwhp" path="res://assets/background/background_menu.jpg" id="2_background"] [ext_resource type="Texture2D" uid="uid://bfc6l14s8iwhp" path="res://assets/background/background_menu.jpg" id="2_background"]
[ext_resource type="Script" path="res://scripts/game/scene_music_player.gd" id="3_scene_music"]
[sub_resource type="StyleBoxFlat" id="StyleBox_primary"] [sub_resource type="StyleBoxFlat" id="StyleBox_primary"]
content_margin_left = 22.0 content_margin_left = 22.0
@ -64,6 +65,11 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_script") script = ExtResource("1_script")
[node name="MenuMusic" type="AudioStreamPlayer" parent="." unique_id=784369201]
script = ExtResource("3_scene_music")
track_path = "res://assets/sounds/music/menu_music.mp3"
playback_volume_db = -13.0
[node name="Background" type="TextureRect" parent="." unique_id=1339534440] [node name="Background" type="TextureRect" parent="." unique_id=1339534440]
layout_mode = 1 layout_mode = 1
anchors_preset = 15 anchors_preset = 15

View File

@ -0,0 +1,102 @@
extends Node2D
const TRAIL_INTERVAL := 0.035
const MAX_TRAIL_PARTICLES := 90
var _ship: CharacterBody2D
var _thrust_strength := 0.0
var _engine_phase := 0.0
var _trail_emission_timer := 0.0
var _trail_particles: Array[Dictionary] = []
func _ready() -> void:
_ship = get_parent() as CharacterBody2D
set_as_top_level(true)
z_index = -1
if is_instance_valid(_ship):
global_position = _ship.global_position
global_rotation = _ship.global_rotation
func _process(delta: float) -> void:
if not is_instance_valid(_ship):
return
global_position = _ship.global_position
global_rotation = _ship.global_rotation
_engine_phase += delta
var thrust_active := Input.is_action_pressed("ship_thrust")
if bool(_ship.get("_is_destroyed")):
thrust_active = false
var target_strength := 1.0 if thrust_active else 0.0
_thrust_strength = move_toward(_thrust_strength, target_strength, 5.5 * delta)
if thrust_active:
_trail_emission_timer += delta
while _trail_emission_timer >= TRAIL_INTERVAL:
_trail_emission_timer -= TRAIL_INTERVAL
_spawn_trail_particle()
_update_trail_particles(delta)
queue_redraw()
func _spawn_trail_particle() -> void:
if _trail_particles.size() >= MAX_TRAIL_PARTICLES:
return
var aft := Vector2.DOWN.rotated(_ship.global_rotation)
var side := Vector2(-aft.y, aft.x)
var angle := randf_range(-0.18, 0.18)
var particle_direction := aft.rotated(angle)
var life := randf_range(0.45, 0.8)
_trail_particles.append({
"position": _ship.global_position + aft * 21.0,
"velocity": _ship.velocity + particle_direction * randf_range(30.0, 58.0) + side * randf_range(-6.0, 6.0),
"age": 0.0,
"life": life,
"size": randf_range(1.5, 3.0),
})
func _update_trail_particles(delta: float) -> void:
for particle_index in range(_trail_particles.size() - 1, -1, -1):
var particle := _trail_particles[particle_index]
particle["position"] = particle["position"] + particle["velocity"] * delta
particle["age"] = float(particle["age"]) + delta
_trail_particles[particle_index] = particle
if float(particle["age"]) >= float(particle["life"]):
_trail_particles.remove_at(particle_index)
func _draw() -> void:
_draw_trail()
if _thrust_strength <= 0.01:
return
var pulse := 0.82 + 0.18 * sin(_engine_phase * 25.0)
var length := (28.0 + pulse * 14.0) * _thrust_strength
var base_y := 22.0
var outer_tip := base_y + length
var inner_tip := base_y + length * 0.76
var core_tip := base_y + length * 0.48
draw_colored_polygon(PackedVector2Array([
Vector2(-5.2, base_y), Vector2(-3.2, base_y + 6.0), Vector2(0.0, outer_tip),
Vector2(3.2, base_y + 6.0), Vector2(5.2, base_y),
]), Color(0.04, 0.58, 1.0, 0.48 * _thrust_strength))
draw_colored_polygon(PackedVector2Array([
Vector2(-2.8, base_y), Vector2(-1.8, base_y + 4.0), Vector2(0.0, inner_tip),
Vector2(1.8, base_y + 4.0), Vector2(2.8, base_y),
]), Color(0.24, 0.9, 1.0, 0.78 * _thrust_strength))
draw_colored_polygon(PackedVector2Array([
Vector2(-1.0, base_y), Vector2(0.0, core_tip), Vector2(1.0, base_y),
]), Color(0.88, 0.98, 1.0, 0.92 * _thrust_strength))
draw_circle(Vector2(0.0, base_y), 2.3, Color(0.42, 0.88, 1.0, 0.82 * _thrust_strength))
func _draw_trail() -> void:
for particle in _trail_particles:
var age := float(particle["age"])
var life := float(particle["life"])
var fade := 1.0 - clampf(age / life, 0.0, 1.0)
var current_position: Vector2 = particle["position"]
var particle_velocity: Vector2 = particle["velocity"]
var particle_size := float(particle["size"])
var current_local := to_local(current_position)
var tail_local := to_local(current_position - particle_velocity.normalized() * particle_size * 3.5)
draw_line(tail_local, current_local, Color(0.22, 0.78, 1.0, fade * 0.52), particle_size * 0.72, true)
draw_circle(current_local, particle_size * fade, Color(0.62, 0.94, 1.0, fade * 0.72))

View File

@ -20,11 +20,18 @@ func _process(_delta: float) -> void:
var ship_position := player.global_position var ship_position := player.global_position
var ship_velocity := player.velocity var ship_velocity := player.velocity
var angular_speed := float(player.get("angular_velocity")) var angular_speed := float(player.get("angular_velocity"))
var enemy_count := 0
for enemy in get_tree().get_nodes_in_group("enemies"):
if not enemy.is_queued_for_deletion():
enemy_count += 1
debug_info.text = """STEROWANIE debug_info.text = """STEROWANIE
W: ciąg S: hamulec / wsteczny W: ciąg S: hamulec / wsteczny
Q / E: strafe A / D: obrót Q / E: strafe A / D: obrót
LPM / PPM: broń 1 / broń 2 LPM / PPM: broń 1 / broń 2
POZIOM
WROGOWIE: %d
STATEK STATEK
KADŁUB: %d / %d KADŁUB: %d / %d
TARCZE: %d / %d TARCZE: %d / %d
@ -40,6 +47,7 @@ POZYCJA X: %.1f
POZYCJA Y: %.1f POZYCJA Y: %.1f
KIERUNEK: %.1f° KIERUNEK: %.1f°
OBRÓT: %.2f rad/s""" % [ OBRÓT: %.2f rad/s""" % [
enemy_count,
roundi(float(player.get("hull"))), roundi(float(player.get("max_hull"))), roundi(float(player.get("hull"))), roundi(float(player.get("max_hull"))),
roundi(float(player.get("shields"))), roundi(float(player.get("max_shields"))), roundi(float(player.get("shields"))), roundi(float(player.get("max_shields"))),
roundi(float(player.get("energy"))), roundi(float(player.get("max_energy"))), roundi(float(player.get("energy"))), roundi(float(player.get("max_energy"))),

View File

@ -0,0 +1,23 @@
extends AudioStreamPlayer
@export_file("*.mp3") var track_path := ""
@export_range(-30.0, 0.0, 0.5, "suffix:dB") var playback_volume_db := -14.0
func _ready() -> void:
if track_path.is_empty():
push_error("SceneMusicPlayer has no track_path configured.")
return
var audio_data := FileAccess.get_file_as_bytes(track_path)
if audio_data.is_empty():
push_error("Could not read music track: %s" % track_path)
return
var music_stream := AudioStreamMP3.load_from_buffer(audio_data)
if music_stream == null:
push_error("Could not decode music track: %s" % track_path)
return
music_stream.loop = true
stream = music_stream
volume_db = playback_volume_db
play()

View File

@ -0,0 +1 @@
uid://dvokq8qdccw37

View File

@ -0,0 +1,37 @@
extends AudioStreamPlayer
const ENGINE_SOUND_PATH := "res://assets/sounds/effects/engine2.mp3"
const SILENT_VOLUME_DB := -60.0
const THRUST_VOLUME_DB := -11.0
const VOLUME_FADE_DB_PER_SECOND := 68.0
var _ship: CharacterBody2D
func _ready() -> void:
_ship = get_parent() as CharacterBody2D
var audio_data := FileAccess.get_file_as_bytes(ENGINE_SOUND_PATH)
if audio_data.size() <= 44:
push_error("Could not read engine sound: %s" % ENGINE_SOUND_PATH)
return
var engine_stream := AudioStreamMP3.load_from_buffer(audio_data)
if engine_stream == null:
push_error("Could not decode engine sound: %s" % ENGINE_SOUND_PATH)
return
engine_stream.loop = true
stream = engine_stream
volume_db = SILENT_VOLUME_DB
pitch_scale = 0.86
play()
func _process(delta: float) -> void:
if stream == null or not is_instance_valid(_ship):
return
var thrust_active := Input.is_action_pressed("ship_thrust")
if bool(_ship.get("_is_destroyed")):
thrust_active = false
var target_volume := THRUST_VOLUME_DB if thrust_active else SILENT_VOLUME_DB
volume_db = move_toward(volume_db, target_volume, VOLUME_FADE_DB_PER_SECOND * delta)
var target_pitch := 1.12 if thrust_active else 0.86
pitch_scale = move_toward(pitch_scale, target_pitch, 0.42 * delta)

View File

@ -0,0 +1 @@
uid://lr8uj128xaql

View File

@ -84,18 +84,18 @@ func _physics_process(delta: float) -> void:
and _shot_timers[slot_index] <= 0.0 and _shot_timers[slot_index] <= 0.0
and _consume_energy(definition.energy_cost) and _consume_energy(definition.energy_cost)
): ):
_fire_projectile(slot_index, definition, item.get_stat_total("damage")) _fire_projectile(definition, item.get_stat_total("damage"))
_shot_timers[slot_index] = definition.weapon_cooldown _shot_timers[slot_index] = definition.weapon_cooldown
_: _:
if _shot_timers[slot_index] <= 0.0 and _consume_energy(definition.energy_cost): if _shot_timers[slot_index] <= 0.0 and _consume_energy(definition.energy_cost):
_fire_projectile(slot_index, definition, item.get_stat_total("damage")) _fire_projectile(definition, item.get_stat_total("damage"))
_shot_timers[slot_index] = definition.fire_interval _shot_timers[slot_index] = definition.fire_interval
for slot_index in 2: for slot_index in 2:
_fire_just_pressed[slot_index] = false _fire_just_pressed[slot_index] = false
func _fire_projectile(slot_index: int, definition: ItemDefinition, projectile_damage: float) -> void: func _fire_projectile(definition: ItemDefinition, projectile_damage: float) -> void:
var direction := _aim_direction() var muzzle_position := _muzzle_position()
var muzzle_position := _muzzle_position(slot_index) var direction := _aim_direction_from(muzzle_position)
var projectile := PROJECTILE_SCENE.instantiate() var projectile := PROJECTILE_SCENE.instantiate()
projectile.call( projectile.call(
"configure", "configure",
@ -113,8 +113,8 @@ func _fire_laser(slot_index: int, definition: ItemDefinition, beam_damage: float
var line := _laser_lines[slot_index] var line := _laser_lines[slot_index]
if _shot_timers[slot_index] > 0.0 or float(ship.get("energy")) < definition.energy_cost: if _shot_timers[slot_index] > 0.0 or float(ship.get("energy")) < definition.energy_cost:
return return
var direction := _aim_direction() var muzzle_position := _muzzle_position()
var muzzle_position := _muzzle_position(slot_index) var direction := _aim_direction_from(muzzle_position)
var endpoint := muzzle_position + direction * definition.weapon_range var endpoint := muzzle_position + direction * definition.weapon_range
var query := PhysicsRayQueryParameters2D.create( var query := PhysicsRayQueryParameters2D.create(
muzzle_position, muzzle_position,
@ -139,15 +139,13 @@ func _fire_laser(slot_index: int, definition: ItemDefinition, beam_damage: float
_laser_pulse_timers[slot_index] = definition.laser_pulse_duration _laser_pulse_timers[slot_index] = definition.laser_pulse_duration
_shot_timers[slot_index] = definition.fire_interval _shot_timers[slot_index] = definition.fire_interval
func _aim_direction() -> Vector2: func _aim_direction_from(origin: Vector2) -> Vector2:
var offset := ship.get_global_mouse_position() - ship.global_position var offset := ship.get_global_mouse_position() - origin
return offset.normalized() if offset.length_squared() > 0.001 else Vector2.UP.rotated(ship.rotation) return offset.normalized() if offset.length_squared() > 0.001 else Vector2.UP.rotated(ship.rotation)
func _muzzle_position(slot_index: int) -> Vector2: func _muzzle_position() -> Vector2:
var forward := Vector2.UP.rotated(ship.rotation) var forward := Vector2.UP.rotated(ship.rotation)
var right := Vector2.RIGHT.rotated(ship.rotation) return ship.global_position + forward * 28.0
var side_offset := -8.0 if slot_index == 0 else 8.0
return ship.global_position + forward * 28.0 + right * side_offset
func _consume_energy(amount: float) -> bool: func _consume_energy(amount: float) -> bool:
var current_energy := float(ship.get("energy")) var current_energy := float(ship.get("energy"))

View File

@ -14,6 +14,8 @@ var _distance_travelled := 0.0
var _already_hit: Dictionary = {} var _already_hit: Dictionary = {}
var _impact_handled := false var _impact_handled := false
var _engine_time := 0.0 var _engine_time := 0.0
var _smoke_emission_timer := 0.0
var _smoke_puffs: Array[Dictionary] = []
func _ready() -> void: func _ready() -> void:
body_entered.connect(_on_body_entered) body_entered.connect(_on_body_entered)
@ -71,8 +73,34 @@ func _physics_process(delta: float) -> void:
func _process(delta: float) -> void: func _process(delta: float) -> void:
if weapon_kind == ItemDefinition.WeaponKind.MISSILE: if weapon_kind == ItemDefinition.WeaponKind.MISSILE:
_engine_time += delta _engine_time += delta
_smoke_emission_timer += delta
while _smoke_emission_timer >= 0.028:
_smoke_emission_timer -= 0.028
_spawn_smoke_puff()
_update_smoke_puffs(delta)
queue_redraw() queue_redraw()
func _spawn_smoke_puff() -> void:
if _smoke_puffs.size() >= 64:
return
var side := Vector2(-direction.y, direction.x)
_smoke_puffs.append({
"position": global_position - direction * 8.0,
"velocity": direction * projectile_speed * 0.12 + side * randf_range(-9.0, 9.0),
"age": 0.0,
"life": randf_range(0.45, 0.75),
"size": randf_range(3.0, 5.0),
})
func _update_smoke_puffs(delta: float) -> void:
for puff_index in range(_smoke_puffs.size() - 1, -1, -1):
var puff := _smoke_puffs[puff_index]
puff["position"] = puff["position"] + puff["velocity"] * delta
puff["age"] = float(puff["age"]) + delta
_smoke_puffs[puff_index] = puff
if float(puff["age"]) >= float(puff["life"]):
_smoke_puffs.remove_at(puff_index)
func _find_enemy_in_acquisition_range() -> Node2D: func _find_enemy_in_acquisition_range() -> Node2D:
var nearest_enemy: Node2D var nearest_enemy: Node2D
var nearest_distance_squared := target_acquisition_range * target_acquisition_range var nearest_distance_squared := target_acquisition_range * target_acquisition_range
@ -86,6 +114,8 @@ func _find_enemy_in_acquisition_range() -> Node2D:
return nearest_enemy return nearest_enemy
func _draw() -> void: func _draw() -> void:
if weapon_kind == ItemDefinition.WeaponKind.MISSILE:
_draw_missile_smoke()
match weapon_kind: match weapon_kind:
ItemDefinition.WeaponKind.PLASMA: ItemDefinition.WeaponKind.PLASMA:
draw_circle(Vector2.ZERO, 6.0, Color(0.3, 0.85, 1.0, 0.95)) draw_circle(Vector2.ZERO, 6.0, Color(0.3, 0.85, 1.0, 0.95))
@ -95,38 +125,33 @@ func _draw() -> void:
ItemDefinition.WeaponKind.MISSILE: ItemDefinition.WeaponKind.MISSILE:
_draw_missile() _draw_missile()
func _draw_missile_smoke() -> void:
for puff in _smoke_puffs:
var progress := clampf(float(puff["age"]) / float(puff["life"]), 0.0, 1.0)
var fade := 1.0 - progress
var puff_position: Vector2 = to_local(puff["position"])
var puff_size := float(puff["size"]) * (0.8 + progress * 0.75)
draw_circle(puff_position, puff_size, Color(0.46, 0.58, 0.67, fade * 0.2))
draw_circle(puff_position, puff_size * 0.48, Color(0.67, 0.75, 0.8, fade * 0.12))
func _draw_missile() -> void: func _draw_missile() -> void:
var flicker := sin(_engine_time * 37.0) * 2.5 + sin(_engine_time * 23.0) * 1.5 var flicker := sin(_engine_time * 37.0) * 2.5 + sin(_engine_time * 23.0) * 1.5
var flame_tip := -20.0 - flicker var flame_tip := -20.0 - flicker
# Layered flame flickers behind the nozzle while the missile is in flight. # Layered exhaust uses tapered strokes so it flickers without polygon artifacts.
draw_colored_polygon(PackedVector2Array([ draw_line(Vector2(-8, 0), Vector2(flame_tip, 0), Color(1.0, 0.27, 0.045, 0.8), 6.0, true)
Vector2(-7, -2.5), Vector2(-14, -4.0), Vector2(flame_tip, 0), draw_line(Vector2(-8, 0), Vector2(flame_tip * 0.72, 0), Color(1.0, 0.78, 0.22, 0.95), 3.4, true)
Vector2(-14, 4.0), Vector2(-7, 2.5), draw_line(Vector2(-8, 0), Vector2(flame_tip * 0.42, 0), Color(0.92, 0.98, 1.0, 1.0), 1.6, true)
]), Color(1.0, 0.27, 0.045, 0.92))
draw_colored_polygon(PackedVector2Array([
Vector2(-7, -1.7), Vector2(-12, -2.2), Vector2(flame_tip + 5.0, 0),
Vector2(-12, 2.2), Vector2(-7, 1.7),
]), Color(1.0, 0.78, 0.22, 0.98))
draw_colored_polygon(PackedVector2Array([
Vector2(-7, -0.8), Vector2(-11, -1.0), Vector2(flame_tip + 10.0, 0),
Vector2(-11, 1.0), Vector2(-7, 0.8),
]), Color(0.92, 0.98, 1.0, 1.0))
# Stabilizing fins and metallic body, facing along the local +X axis. # Stabilizing fins and metallic body, facing along the local +X axis.
draw_colored_polygon(PackedVector2Array([ draw_line(Vector2(-5, -2.5), Vector2(-11, -7), Color(0.68, 0.17, 0.12, 1.0), 2.2, true)
Vector2(-5, -2.5), Vector2(-11, -7), Vector2(-10, -1.5), Vector2(-5, -1), draw_line(Vector2(-11, -7), Vector2(-9, -1.8), Color(0.68, 0.17, 0.12, 1.0), 2.2, true)
]), Color(0.68, 0.17, 0.12, 1.0)) draw_line(Vector2(-5, 2.5), Vector2(-11, 7), Color(0.68, 0.17, 0.12, 1.0), 2.2, true)
draw_colored_polygon(PackedVector2Array([ draw_line(Vector2(-11, 7), Vector2(-9, 1.8), Color(0.68, 0.17, 0.12, 1.0), 2.2, true)
Vector2(-5, 2.5), Vector2(-11, 7), Vector2(-10, 1.5), Vector2(-5, 1), draw_rect(Rect2(-8, -3.5, 14, 7), Color(0.72, 0.79, 0.84, 1.0), true)
]), Color(0.68, 0.17, 0.12, 1.0)) draw_rect(Rect2(3, -2.2, 3, 4.4), Color(0.91, 0.34, 0.2, 1.0), true)
draw_colored_polygon(PackedVector2Array([ draw_line(Vector2(6, -3.5), Vector2(12, 0), Color(0.91, 0.34, 0.2, 1.0), 2.6, true)
Vector2(12, 0), Vector2(6, -3.6), Vector2(-7, -3.6), draw_line(Vector2(12, 0), Vector2(6, 3.5), Color(0.91, 0.34, 0.2, 1.0), 2.6, true)
Vector2(-10, -2.2), Vector2(-10, 2.2), Vector2(-7, 3.6), Vector2(6, 3.6), draw_line(Vector2(-5, -2.4), Vector2(2, -2.4), Color(0.98, 0.99, 1.0, 0.85), 1.0, true)
]), Color(0.72, 0.79, 0.84, 1.0))
draw_colored_polygon(PackedVector2Array([
Vector2(12, 0), Vector2(6, -3.6), Vector2(6, 3.6),
]), Color(0.91, 0.34, 0.2, 1.0))
draw_line(Vector2(-5, -2.4), Vector2(5, -2.4), Color(0.98, 0.99, 1.0, 0.85), 1.0, true)
draw_rect(Rect2(-9.5, -1.1, 2.0, 2.2), Color(0.25, 0.31, 0.36, 1.0)) draw_rect(Rect2(-9.5, -1.1, 2.0, 2.2), Color(0.25, 0.31, 0.36, 1.0))
draw_circle(Vector2(1.0, 0), 1.35, Color(0.62, 0.93, 1.0, 1.0)) draw_circle(Vector2(1.0, 0), 1.35, Color(0.62, 0.93, 1.0, 1.0))