Added bullet indexing to create shot patterns

This commit is contained in:
Henry Faber 2026-06-13 12:05:13 +01:00
parent bdbc3b015f
commit 1725b8b754
13 changed files with 91 additions and 27 deletions

View file

@ -11,7 +11,7 @@ config_version=5
[application] [application]
config/name="Facsimile Wing" config/name="Facsimile Wing"
run/main_scene="uid://coix5dqblmu7r" run/main_scene="uid://bj4fytc3sy482"
config/features=PackedStringArray("4.6", "Forward Plus") config/features=PackedStringArray("4.6", "Forward Plus")
config/icon="res://icon.svg" config/icon="res://icon.svg"

View file

@ -5,11 +5,13 @@ extends Resource
@export var shot_name: String @export var shot_name: String
@export var bullet_scene: PackedScene = null @export var bullet_scene: PackedScene = null
#@export var sprite: Texture2D = preload("res://graphics/shot.png")
@export_category("Shot Data") @export_category("Shot Data")
@export var damage: int = 1 @export var damage: int = 1
@export var speed: int = 135 @export var speed: int = 135
@export var projectiles: int = 2 @export var projectiles: int = 2
@export var spacing: float = 35 @export var spacing: float = 35
@export var origin: int = -23 @export var origin: int = -23
@export_category("Stagger")
@export var horizontal_offset: float = 6.5 # Horizontal distance between projectiles
@export var stagger_offset: float = 5 # Time delay per projectile index

View file

@ -7,8 +7,9 @@
script = ExtResource("2_by0nb") script = ExtResource("2_by0nb")
shot_name = "Stock Shot" shot_name = "Stock Shot"
bullet_scene = ExtResource("1_by0nb") bullet_scene = ExtResource("1_by0nb")
speed = 375 speed = 355
projectiles = 3 projectiles = 3
spacing = 25.0 spacing = 32.0
origin = -20 origin = -25
stagger_offset = 0.75
metadata/_custom_type_script = "uid://7n1itonn35fm" metadata/_custom_type_script = "uid://7n1itonn35fm"

3
scenes/game.gd Normal file
View file

@ -0,0 +1,3 @@
extends Node2D
@onready var screensize = get_viewport().content_scale_size

1
scenes/game.gd.uid Normal file
View file

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

View file

@ -1,9 +1,11 @@
[gd_scene format=3 uid="uid://dqd8cxe7aj3b4"] [gd_scene format=3 uid="uid://dqd8cxe7aj3b4"]
[ext_resource type="Script" uid="uid://dkti4uwycpqrs" path="res://scenes/game.gd" id="1_lnu2h"]
[ext_resource type="PackedScene" uid="uid://bj4fytc3sy482" path="res://scenes/world.tscn" id="1_uwrxv"] [ext_resource type="PackedScene" uid="uid://bj4fytc3sy482" path="res://scenes/world.tscn" id="1_uwrxv"]
[ext_resource type="Texture2D" uid="uid://egqbrm636m4h" path="res://graphics/title.png" id="2_yqjtg"] [ext_resource type="Texture2D" uid="uid://egqbrm636m4h" path="res://graphics/title.png" id="2_yqjtg"]
[node name="Game" type="Node2D" unique_id=1673976895] [node name="Game" type="Node2D" unique_id=1673976895]
script = ExtResource("1_lnu2h")
[node name="World" parent="." unique_id=1317852169 instance=ExtResource("1_uwrxv")] [node name="World" parent="." unique_id=1317852169 instance=ExtResource("1_uwrxv")]

View file

@ -6,15 +6,23 @@ class_name Player extends Area2D
@onready var shoot_component: ShootComponent = %ShootComponent @onready var shoot_component: ShootComponent = %ShootComponent
@onready var weapon_component: WeaponComponent = %WeaponComponent @onready var weapon_component: WeaponComponent = %WeaponComponent
# Get the viewport size for positioning
@onready var screensize = get_viewport().content_scale_size
# Variables for Player shooting status # Variables for Player shooting status
@export var can_shoot: bool = true @export var can_shoot: bool = true
@export var is_shooting: bool = false @export var is_shooting: bool = false
@export var muzzle_flash: bool = false
# Variables for Player position calculations for equidistant bullets # Variables for Player position calculations for equidistant bullets
var previous_position: Vector2 var previous_position: Vector2
var ship_displacement: float var ship_displacement: float
var travel: float = 0 var travel: float = 0
func _ready() -> void:
## Set initial start position
position = Vector2(screensize.x / 2, screensize.y - 45)
func _process(delta) -> void: func _process(delta) -> void:
@ -28,6 +36,12 @@ func _process(delta) -> void:
if is_shooting == true: if is_shooting == true:
shoot_component.shoot() shoot_component.shoot()
$%MuzzleFlash.show()
if is_shooting == false:
$%MuzzleFlash.hide()
# Read Movement Component # Read Movement Component
movement_component.input = input_component.move_dir movement_component.input = input_component.move_dir

View file

@ -90,6 +90,9 @@ size = Vector2(6, 5.75)
[node name="Player" type="Area2D" unique_id=652131079] [node name="Player" type="Area2D" unique_id=652131079]
script = ExtResource("1_ur7pv") script = ExtResource("1_ur7pv")
can_shoot = null
is_shooting = null
muzzle_flash = null
[node name="Ship" type="Sprite2D" parent="." unique_id=1155866924] [node name="Ship" type="Sprite2D" parent="." unique_id=1155866924]
unique_name_in_owner = true unique_name_in_owner = true

20
scenes/weapon_stock.gd Normal file
View file

@ -0,0 +1,20 @@
extends Area2D
@onready var bullet: PackedScene = load("res://scenes/weapon_stock.tscn")
@onready var shot_data: = load("res://resources/player_weapons/weapon_shot_stock.tres")
# Time offset when this bullet was fired (relative to other bullets)
var time_offset: float = 0.5
#func activate():
# Bullet does its damage/projectile work
func _process(delta):
#Calculation position along Y axis
position.y -= shot_data.speed * delta # Original Speed
#position.y -= 330 * delta # non-shot_data testing
func _on_visible_on_screen_notifier_2d_screen_exited() -> void:
queue_free()

View file

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

View file

@ -1,6 +1,6 @@
[gd_scene format=3 uid="uid://ddpclu2vdy2ve"] [gd_scene format=3 uid="uid://ddpclu2vdy2ve"]
[ext_resource type="Script" uid="uid://d1rwqotmrag1r" path="res://Deprecated/stock_weapon.gd" id="1_u1d5o"] [ext_resource type="Script" uid="uid://c5blhfopjpfny" path="res://scenes/weapon_stock.gd" id="1_u1d5o"]
[ext_resource type="Texture2D" uid="uid://ti1uy42vnnhw" path="res://graphics/shot.png" id="2_5bykt"] [ext_resource type="Texture2D" uid="uid://ti1uy42vnnhw" path="res://graphics/shot.png" id="2_5bykt"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_mvdrj"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_mvdrj"]

View file

@ -12,7 +12,7 @@ class_name MovementComponent extends Node
var input = Input.get_vector("left", "right", "up","down") var input = Input.get_vector("left", "right", "up","down")
func tick(delta: float): func tick(delta: float):
# Check to see if there's a player to move # Check to see if there's a player to move
if player == null: return if player == null: return

View file

@ -1,32 +1,49 @@
class_name ShootComponent extends Node class_name ShootComponent extends Node
@export var stagger_offset: float = 0.5 # Time delay per projectile index (seconds)
@export var horizontal_offset: float = 1.0 # Horizontal distance per projectile index
@onready var weapon_component: Node = %WeaponComponent @onready var weapon_component: Node = %WeaponComponent
@onready var player = $".." @onready var player = $".."
# Change from instantiating WeaponComponent to instantiating Shot nodes
func shoot(): func shoot():
var weapon_data = weapon_component.data # WeaponShot resource configuration var weapon_data = weapon_component.data # WeaponShot resource configuration
var current_time = Time.get_ticks_msec() / 1000.0
var total_projectiles = weapon_data.projectiles
if player.travel > weapon_data.spacing: if player.travel > weapon_data.spacing:
for b in range(weapon_data.projectiles):
# Get the Shot scene from the WeaponShot resource
var bullet_scene = weapon_data.bullet_scene # Or however you store it
# Instantiate the bullet based data
var bullet := bullet_scene.instantiate() as Node
get_tree().root.add_child(bullet)
# Set up the bullet from resource data # Calculate center index for symmetrical staggering
#bullet.shot_data = weapon_data # Pass the configuration var center_index = (total_projectiles - 1) / 2.0
# Adjust bullet spacing before firing if total_projectiles > 0:
bullet.position = player.position + Vector2((b - (weapon_data.projectiles - 1) / 2.0) * round(round((weapon_data.projectiles + weapon_data.spacing / 2)) / 2 - 2), weapon_data.origin) for b in range(total_projectiles):
print(b, bullet.position.x) var bullet_scene = weapon_data.bullet_scene
print(weapon_data.shot_name + " "+"fired!") var bullet := bullet_scene.instantiate() as Node
get_tree().root.add_child(bullet)
# Subtract projectile spacing from current Player travel for next # Calculate index relative to center (0 = center, -1/+1 = first from center)
player.travel -= weapon_data.spacing var index_from_center: int = b - center_index
else: return # Calculate timing offset for staggered firing
# Negative = fire before center (left), positive = fire after center (right)
var time_offset: float = index_from_center * stagger_offset
# Calculate horizontal offset for symmetrical spread (left = negative, right = positive)
horizontal_offset = index_from_center * weapon_data.spacing_horizontal
# Calculate vertical offset from center point (creates symmetrical vertical spread)
# Bullets on either side of center get offset by distance_from_center * spacing / 2
# This keeps the center bullet at origin and creates symmetrical vertical spread
var distance_from_center: float = abs(index_from_center)
var vertical_offset: float = (distance_from_center * weapon_data.origin * -1) / 2
# Final position combines symmetrical horizontal spread with symmetrical vertical spacing
bullet.position = player.position + Vector2(horizontal_offset, weapon_data.origin + vertical_offset)
## Set timing properties on the bullet
#bullet.time_offset = time_offset
#bullet.fire_time = current_time + time_offset
# Subtract projectile spacing from current Player travel for next
player.travel -= weapon_data.spacing