Updated the bullet spawning position to beging from the sprite height

modified by the weapon's origin variable.
This commit is contained in:
Henry Faber 2026-06-28 08:05:30 +01:00
parent 64e685a3c1
commit 9554af183c
7 changed files with 38 additions and 27 deletions

View file

@ -2,6 +2,6 @@ extends Node
@warning_ignore_start("unused_signal") # since otherwise Godot will throw a warning that the signal is unused in current scope
signal weapon_changed(weapon_name: String, player_node: Node2D, player_sprite_size: Vector2, origin_offset: Vector2)
signal weapon_changed(weapon_name: String, player_node: Node2D, player_sprite_size: Vector2, origin_offset: float)
@warning_ignore_restore("unused_signal")

View file

@ -6,7 +6,7 @@ class_name NotificationDisplay extends Control
var _player: Node2D = null
var _sprite_size: Vector2 = Vector2.ZERO
var _origin_offset: Vector2 = Vector2.ZERO
var _origin_offset: float = 0.0
var _follow_player: bool = false
var _connector_line: Line2D = null
@ -23,7 +23,7 @@ func _ready() -> void:
_container.add_theme_constant_override("margin_right", 4)
func show_notification(weapon_name: String, player_node: Node2D, player_sprite_size: Vector2, origin_offset: Vector2) -> void:
func show_notification(weapon_name: String, player_node: Node2D, player_sprite_size: Vector2, origin_offset: float) -> void:
modulate.a = 0.0
label.add_theme_font_size_override("font_size", 8)
@ -107,7 +107,7 @@ func _update_position() -> void:
var player_pos = _player.position
# Y position uses the weapon origin offset from player center
var notif_y = player_pos.y + _origin_offset.y - (size.y / 2.0)
var notif_y = player_pos.y + _origin_offset - (size.y / 2.0)
# X position is 10px to the right of player's sprite edge
var right_edge = player_pos.x + (_sprite_size.x / 2.0)
@ -164,7 +164,7 @@ func _update_connector() -> void:
# Point 2: player's origin + ENDPOINT_OFFSET, converted to notification's local space
const ENDPOINT_OFFSET = Vector2(4, 7) # offset from player's origin to connector endpoint
var target = _player.position + Vector2(+ENDPOINT_OFFSET.x, _origin_offset.y + ENDPOINT_OFFSET.y)
var target = _player.position + Vector2(+ENDPOINT_OFFSET.x, _origin_offset + ENDPOINT_OFFSET.y)
var point2 = target - position
_connector_line.points = PackedVector2Array([point0, point1, point2])

View file

@ -8,7 +8,7 @@ func _ready() -> void:
EventBus.weapon_changed.connect(_on_weapon_changed)
func _on_weapon_changed(weapon_name: String, player_node: Node2D, player_sprite_size: Vector2, origin_offset: Vector2) -> void:
func _on_weapon_changed(weapon_name: String, player_node: Node2D, player_sprite_size: Vector2, origin_offset: float) -> void:
if notification_scene == null:
return

View file

@ -17,6 +17,19 @@ func shoot():
player.travel = 0.0
func _get_spawn_position(weapon_data: WeaponShot) -> Vector2:
# Determine sprite height with a region_rect → texture fallback.
var sprite_height: float = 0.0
if ship.region_rect.has_area():
sprite_height = ship.region_rect.size.y
else:
sprite_height = ship.texture.get_height()
# Top edge of the sprite in world space, then offset by origin.
var top_edge = ship.global_position.y - (sprite_height / 2.0)
return Vector2(ship.global_position.x, top_edge + weapon_data.origin)
# Standard projectile logic (delegates to WeaponFireHelper)
func _shoot_standard(weapon_data: WeaponShot, current_time: float):
var total_projectiles: int = weapon_data.projectiles
@ -26,8 +39,8 @@ func _shoot_standard(weapon_data: WeaponShot, current_time: float):
var bullet := weapon_data.bullet_scene.instantiate() as Area2D
get_tree().root.add_child(bullet)
# Delegate math to the helper, with spawn position offset by weapon origin
var spawn_position = ship.global_position + weapon_data.origin
# Delegate math to the helper
var spawn_position = _get_spawn_position(weapon_data)
var props = fire_helper.compute_standard_props(weapon_data, b, spawn_position, current_time)
bullet.position = props.position
bullet.angle = props.angle
@ -50,7 +63,7 @@ func _shoot_grouped(weapon_data: WeaponShot, current_time: float):
get_tree().root.add_child(bullet)
# Apply computed properties for the original bullet
var spawn_position = ship.global_position + weapon_data.origin
var spawn_position = _get_spawn_position(weapon_data)
var props = fire_helper.compute_grouped_props(group, weapon_data, b, spawn_position, current_time, false)
bullet.position = props.position
bullet.angle = props.angle
@ -66,7 +79,7 @@ func _shoot_grouped(weapon_data: WeaponShot, current_time: float):
get_tree().root.add_child(mirror_bullet)
# Apply computed properties for the mirrored bullet
var mirror_spawn = ship.global_position + weapon_data.origin
var mirror_spawn = _get_spawn_position(weapon_data)
var mirror_props = fire_helper.compute_grouped_props(group, weapon_data, b, mirror_spawn, current_time, true)
mirror_bullet.position = mirror_props.position
mirror_bullet.angle = mirror_props.angle

View file

@ -21,7 +21,7 @@ func _ready() -> void:
func _emit_weapon_changed() -> void:
var ship: Sprite2D = get_parent().get_node("Ship")
var sprite_size = ship.get_rect().size
var origin_offset: Vector2 = weapon_data.origin if weapon_data else Vector2.ZERO
var origin_offset: float = weapon_data.origin if weapon_data else 0.0
EventBus.weapon_changed.emit(weapon_data.shot_name, get_parent(), sprite_size, origin_offset)

View file

@ -15,11 +15,11 @@ func compute_standard_props(weapon_data: WeaponShot, projectile_index: int, spaw
# Timing: center-first, pairs outward
var time_offset: float = abs(index_from_center) * weapon_data.stagger_offset
# Vertical spacing creates the ^ (inverted-V) geometry: outer projectiles fire higher
# than the center projectile. Negate the offset so outer bullets are pushed upward
# (lower y values in Godot), creating a ^ pattern relative to the origin.
# Vertical spacing creates the ^ (inverted-V) geometry: outer projectiles fire lower
# (higher Y values, further from the player) than the center projectile, which sits
# higher on screen (lower Y values). This creates a ^ pattern relative to the origin.
var vertical_offset: float = (abs(index_from_center) * weapon_data.projectile_vertical_spacing) / 2.0
var position: Vector2 = spawn_position + Vector2(bullet_horizontal_offset, -vertical_offset)
var position: Vector2 = spawn_position + Vector2(bullet_horizontal_offset, +vertical_offset)
# Angle (only when projectiles >= 3, division-by-zero guard)
var bullet_angle: float = 0.0
@ -68,8 +68,11 @@ func compute_grouped_props(group: WeaponProjectileGroup, weapon_data: WeaponShot
else:
bullet_angle += spread_contribution
# Position: horizontal offset only (vertical position comes from spawn_position)
var position: Vector2 = spawn_position + Vector2(bullet_horizontal_offset, 0)
# Vertical spacing creates the ^ (inverted-V) geometry: outer projectiles fire lower
# (higher Y values, further from the player) than the center projectile, which sits
# higher on screen (lower Y values). This creates a ^ pattern relative to the origin.
var vertical_offset: float = (abs(index_from_center) * weapon_data.projectile_vertical_spacing) / 2.0
var position: Vector2 = spawn_position + Vector2(bullet_horizontal_offset, +vertical_offset)
# Timing: group delay + within-group stagger
var time_offset: float = group.group_delay + abs(index_from_center) * group.stagger_offset

View file

@ -10,16 +10,11 @@ extends Resource
# Vertical spacing between projectiles in a burst (used by WeaponFireHelper to compute the ^ pattern).
# This controls spatial burst geometry, NOT temporal spacing between continuous fire bursts.
@export var projectile_vertical_spacing: float = 35
# Spawn offset strictly relative to the ship node's global position (origin).
# This offset is measured from the ship node's center, not the sprite texture.
# x is usually 0 (horizontal centering), y controls vertical fire position.
# Negative Y moves bullets "above" the ship (in front of it); positive Y
# moves them "below" (behind it). The default of (0, -25) places the burst
# 25 pixels above (in front of) the ship center.
# All weapon resources in this project use the default. Custom weapons with
# explicit origin.y > 0 (positive) will have their burst pattern appear
# behind or below the ship -- verify visually if adjusting.
@export var origin: Vector2 = Vector2(0, -25)
# Vertical offset from the top of the player's sprite where bullets spawn.
# Measured in pixels; negative values fire in front of (above) the ship,
# positive values fire behind (below) it. The default of -25 places the
# burst 25 pixels above the sprite's top edge.
@export var origin: float = -25.0
@export_category("Spread")
# Horizontal distance between projectiles