From 4219d50445eedb3aa63cc0da319f6bc909da02e6 Mon Sep 17 00:00:00 2001 From: Tomasz Boruc Date: Fri, 9 Oct 2026 20:25:33 +0200 Subject: [PATCH] Male poprawki --- resources/items/beam_laser.tres | 4 +- scripts/game/weapon_controller.gd | 26 +++++++---- scripts/game/weapon_projectile.gd | 75 +++++++++++++++++++++++++++++-- 3 files changed, 90 insertions(+), 15 deletions(-) diff --git a/resources/items/beam_laser.tres b/resources/items/beam_laser.tres index 79df894..81d0e64 100644 --- a/resources/items/beam_laser.tres +++ b/resources/items/beam_laser.tres @@ -7,12 +7,12 @@ script = ExtResource("1_definition") item_id = "beam_laser" display_name = "Laser wiązkowy" category = 0 -description = "Laser pulsacyjny. Każdy impuls zadaje obrażenia i zużywa 6 energii." +description = "Laser pulsacyjny o bardzo dużym zasięgu. Każdy impuls zużywa 12 energii." primary_stat = "damage" primary_value = 8.0 stat_suffix = " DMG" weapon_kind = 2 fire_interval = 0.2 weapon_range = 800.0 -energy_cost = 6.0 +energy_cost = 12.0 laser_pulse_duration = 0.08 diff --git a/scripts/game/weapon_controller.gd b/scripts/game/weapon_controller.gd index 8eb90de..e8f3f8f 100644 --- a/scripts/game/weapon_controller.gd +++ b/scripts/game/weapon_controller.gd @@ -84,21 +84,22 @@ func _physics_process(delta: float) -> void: and _shot_timers[slot_index] <= 0.0 and _consume_energy(definition.energy_cost) ): - _fire_projectile(definition, item.get_stat_total("damage")) + _fire_projectile(slot_index, definition, item.get_stat_total("damage")) _shot_timers[slot_index] = definition.weapon_cooldown _: if _shot_timers[slot_index] <= 0.0 and _consume_energy(definition.energy_cost): - _fire_projectile(definition, item.get_stat_total("damage")) + _fire_projectile(slot_index, definition, item.get_stat_total("damage")) _shot_timers[slot_index] = definition.fire_interval for slot_index in 2: _fire_just_pressed[slot_index] = false -func _fire_projectile(definition: ItemDefinition, projectile_damage: float) -> void: +func _fire_projectile(slot_index: int, definition: ItemDefinition, projectile_damage: float) -> void: var direction := _aim_direction() + var muzzle_position := _muzzle_position(slot_index) var projectile := PROJECTILE_SCENE.instantiate() projectile.call( "configure", - ship.global_position + direction * 30.0, + muzzle_position, direction, definition.weapon_kind, definition.projectile_speed, @@ -106,16 +107,17 @@ func _fire_projectile(definition: ItemDefinition, projectile_damage: float) -> v definition.weapon_range ) ship.get_parent().add_child(projectile) - WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), ship.global_position, definition.weapon_kind) + WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), muzzle_position, definition.weapon_kind) func _fire_laser(slot_index: int, definition: ItemDefinition, beam_damage: float) -> void: var line := _laser_lines[slot_index] if _shot_timers[slot_index] > 0.0 or float(ship.get("energy")) < definition.energy_cost: return var direction := _aim_direction() - var endpoint := ship.global_position + direction * definition.weapon_range + var muzzle_position := _muzzle_position(slot_index) + var endpoint := muzzle_position + direction * definition.weapon_range var query := PhysicsRayQueryParameters2D.create( - ship.global_position, + muzzle_position, endpoint, RAY_COLLISION_MASK, [ship.get_rid()] @@ -124,13 +126,13 @@ func _fire_laser(slot_index: int, definition: ItemDefinition, beam_damage: float if not result.is_empty(): endpoint = result["position"] line.clear_points() - line.add_point(ship.global_position) + line.add_point(muzzle_position) line.add_point(endpoint) line.visible = true if not _consume_energy(definition.energy_cost): line.visible = false return - WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), ship.global_position, ItemDefinition.WeaponKind.LASER) + WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), muzzle_position, ItemDefinition.WeaponKind.LASER) if not result.is_empty(): _apply_damage(result.get("collider"), beam_damage) _spawn_laser_impact(endpoint) @@ -141,6 +143,12 @@ func _aim_direction() -> Vector2: var offset := ship.get_global_mouse_position() - ship.global_position return offset.normalized() if offset.length_squared() > 0.001 else Vector2.UP.rotated(ship.rotation) +func _muzzle_position(slot_index: int) -> Vector2: + var forward := Vector2.UP.rotated(ship.rotation) + var right := Vector2.RIGHT.rotated(ship.rotation) + 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: var current_energy := float(ship.get("energy")) if current_energy < amount: diff --git a/scripts/game/weapon_projectile.gd b/scripts/game/weapon_projectile.gd index c37780f..e01b662 100644 --- a/scripts/game/weapon_projectile.gd +++ b/scripts/game/weapon_projectile.gd @@ -7,9 +7,13 @@ var projectile_speed := 600.0 var damage := 1.0 var max_range := 800.0 var weapon_kind := ItemDefinition.WeaponKind.PLASMA +var homing_target: Node2D +var homing_turn_speed := 3.2 +var target_acquisition_range := 360.0 var _distance_travelled := 0.0 var _already_hit: Dictionary = {} var _impact_handled := false +var _engine_time := 0.0 func _ready() -> void: body_entered.connect(_on_body_entered) @@ -22,7 +26,8 @@ func configure( kind: int, speed: float, projectile_damage: float, - projectile_range: float + projectile_range: float, + target: Node2D = null ) -> void: global_position = start_position direction = travel_direction.normalized() @@ -30,8 +35,20 @@ func configure( projectile_speed = speed damage = projectile_damage max_range = projectile_range + homing_target = target func _physics_process(delta: float) -> void: + if weapon_kind == ItemDefinition.WeaponKind.MISSILE: + if not is_instance_valid(homing_target): + homing_target = _find_enemy_in_acquisition_range() + if is_instance_valid(homing_target): + var to_target := homing_target.global_position - global_position + if to_target.length_squared() > 0.001: + var target_angle := to_target.angle() + direction = Vector2.RIGHT.rotated(rotate_toward( + direction.angle(), target_angle, homing_turn_speed * delta + )) + rotation = direction.angle() var step := projectile_speed * delta var previous_position := global_position var next_position := previous_position + direction * step @@ -51,6 +68,23 @@ func _physics_process(delta: float) -> void: if _distance_travelled >= max_range: queue_free() +func _process(delta: float) -> void: + if weapon_kind == ItemDefinition.WeaponKind.MISSILE: + _engine_time += delta + queue_redraw() + +func _find_enemy_in_acquisition_range() -> Node2D: + var nearest_enemy: Node2D + var nearest_distance_squared := target_acquisition_range * target_acquisition_range + for candidate in get_tree().get_nodes_in_group("enemies"): + if not candidate is Node2D or candidate.is_queued_for_deletion(): + continue + var distance_squared := global_position.distance_squared_to(candidate.global_position) + if distance_squared <= nearest_distance_squared: + nearest_distance_squared = distance_squared + nearest_enemy = candidate + return nearest_enemy + func _draw() -> void: match weapon_kind: ItemDefinition.WeaponKind.PLASMA: @@ -59,9 +93,42 @@ func _draw() -> void: ItemDefinition.WeaponKind.MACHINE_GUN: draw_rect(Rect2(-7.0, -2.0, 14.0, 4.0), Color(1.0, 0.82, 0.38, 1.0)) ItemDefinition.WeaponKind.MISSILE: - draw_colored_polygon(PackedVector2Array([ - Vector2(10, 0), Vector2(-7, -4), Vector2(-4, 0), Vector2(-7, 4), - ]), Color(1.0, 0.42, 0.2, 1.0)) + _draw_missile() + +func _draw_missile() -> void: + var flicker := sin(_engine_time * 37.0) * 2.5 + sin(_engine_time * 23.0) * 1.5 + var flame_tip := -20.0 - flicker + # Layered flame flickers behind the nozzle while the missile is in flight. + draw_colored_polygon(PackedVector2Array([ + Vector2(-7, -2.5), Vector2(-14, -4.0), Vector2(flame_tip, 0), + Vector2(-14, 4.0), Vector2(-7, 2.5), + ]), 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. + draw_colored_polygon(PackedVector2Array([ + Vector2(-5, -2.5), Vector2(-11, -7), Vector2(-10, -1.5), Vector2(-5, -1), + ]), Color(0.68, 0.17, 0.12, 1.0)) + draw_colored_polygon(PackedVector2Array([ + Vector2(-5, 2.5), Vector2(-11, 7), Vector2(-10, 1.5), Vector2(-5, 1), + ]), Color(0.68, 0.17, 0.12, 1.0)) + draw_colored_polygon(PackedVector2Array([ + Vector2(12, 0), Vector2(6, -3.6), Vector2(-7, -3.6), + Vector2(-10, -2.2), Vector2(-10, 2.2), Vector2(-7, 3.6), Vector2(6, 3.6), + ]), 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_circle(Vector2(1.0, 0), 1.35, Color(0.62, 0.93, 1.0, 1.0)) func _on_body_entered(body: Node2D) -> void: _hit_target(body)