further elaboration on bullets
This commit is contained in:
parent
da9111bcf2
commit
393c3b670a
16 changed files with 218 additions and 29 deletions
|
|
@ -28,7 +28,6 @@ Hud="*res://gui/hud.tscn"
|
||||||
|
|
||||||
window/size/viewport_width=240
|
window/size/viewport_width=240
|
||||||
window/size/viewport_height=320
|
window/size/viewport_height=320
|
||||||
window/vsync/vsync_mode=0
|
|
||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,73 @@
|
||||||
[gd_scene load_steps=11 format=3 uid="uid://dxsp66qpvm65b"]
|
[gd_scene load_steps=23 format=3 uid="uid://dxsp66qpvm65b"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://c50bfqprpitev" path="res://icon.svg" id="1_g7g4h"]
|
[ext_resource type="Texture2D" uid="uid://c50bfqprpitev" path="res://icon.svg" id="1_g7g4h"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c714s5d7d5765" path="res://objects/player/player.tscn" id="2_j8ivh"]
|
[ext_resource type="PackedScene" uid="uid://c714s5d7d5765" path="res://objects/player/player.tscn" id="2_j8ivh"]
|
||||||
[ext_resource type="Script" uid="uid://cj2fj7snls8aa" path="res://systems/bullets/bullet_set.gd" id="3_cf1so"]
|
[ext_resource type="Script" uid="uid://cj2fj7snls8aa" path="res://systems/bullets/bullet_set.gd" id="3_cf1so"]
|
||||||
|
[ext_resource type="Script" uid="uid://mivkgn34ox41" path="res://systems/bullets/actions/bullet_action.gd" id="4_1xo0o"]
|
||||||
|
[ext_resource type="Script" uid="uid://pn143vuxc7wp" path="res://systems/bullets/actions/despawn_action.gd" id="4_4oowd"]
|
||||||
[ext_resource type="Texture2D" uid="uid://du7gh3nk66mpo" path="res://graphics/bullets/normal_bullet/bullet_1.png" id="4_hlyn7"]
|
[ext_resource type="Texture2D" uid="uid://du7gh3nk66mpo" path="res://graphics/bullets/normal_bullet/bullet_1.png" id="4_hlyn7"]
|
||||||
[ext_resource type="Script" uid="uid://dntp60my5f65m" path="res://systems/bullets/behaviors/simple_linear_behavior.gd" id="4_t1bs8"]
|
[ext_resource type="Script" uid="uid://dntp60my5f65m" path="res://systems/bullets/behaviors/simple_linear_behavior.gd" id="4_t1bs8"]
|
||||||
[ext_resource type="Script" uid="uid://dtuc6qerbfset" path="res://systems/bullets/spawn_patterns/ring_pattern.gd" id="5_4oowd"]
|
[ext_resource type="Script" uid="uid://d238qii8i2byl" path="res://systems/bullets/spawn_patterns/line_pattern.gd" id="5_cf1so"]
|
||||||
[ext_resource type="Script" uid="uid://vus1a0flwtnm" path="res://systems/bullets/bullet_preset.gd" id="6_sle1e"]
|
[ext_resource type="Script" uid="uid://vus1a0flwtnm" path="res://systems/bullets/bullet_preset.gd" id="6_sle1e"]
|
||||||
|
[ext_resource type="Script" uid="uid://dtuc6qerbfset" path="res://systems/bullets/spawn_patterns/ring_pattern.gd" id="6_uu3sg"]
|
||||||
|
[ext_resource type="Script" uid="uid://oug6n1t6tnor" path="res://systems/bullets/actions/spawn_set_action.gd" id="8_377ep"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bqn0smy2jio3y" path="res://graphics/bullets/normal_bullet/bullet_3.png" id="8_uu3sg"]
|
||||||
|
[ext_resource type="Script" uid="uid://mair8nsxn7lp" path="res://systems/bullets/actions/multi_action.gd" id="10_etmxr"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_c0i5a"]
|
[sub_resource type="Resource" id="Resource_rbgfd"]
|
||||||
script = ExtResource("4_t1bs8")
|
script = ExtResource("4_t1bs8")
|
||||||
acceleration = 64.0
|
acceleration = 64.0
|
||||||
metadata/_custom_type_script = "uid://dntp60my5f65m"
|
metadata/_custom_type_script = "uid://dntp60my5f65m"
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_1xo0o"]
|
[sub_resource type="Resource" id="Resource_xksnv"]
|
||||||
script = ExtResource("5_4oowd")
|
script = ExtResource("6_uu3sg")
|
||||||
bullet_count = 5
|
bullet_count = 9
|
||||||
distance_offset = 16.0
|
|
||||||
direction_rotation = 3.9269908169872414
|
|
||||||
metadata/_custom_type_script = "uid://dtuc6qerbfset"
|
metadata/_custom_type_script = "uid://dtuc6qerbfset"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_i8wif"]
|
||||||
|
script = ExtResource("6_sle1e")
|
||||||
|
behavior = SubResource("Resource_rbgfd")
|
||||||
|
pattern = SubResource("Resource_xksnv")
|
||||||
|
textures = Array[Texture2D]([ExtResource("8_uu3sg")])
|
||||||
|
hitbox_size = Vector2i(6, 6)
|
||||||
|
metadata/_custom_type_script = "uid://vus1a0flwtnm"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_g0u1t"]
|
||||||
|
script = ExtResource("8_377ep")
|
||||||
|
preset = SubResource("Resource_i8wif")
|
||||||
|
metadata/_custom_type_script = "uid://oug6n1t6tnor"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_2fp3d"]
|
||||||
|
script = ExtResource("4_4oowd")
|
||||||
|
metadata/_custom_type_script = "uid://pn143vuxc7wp"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_ufsqg"]
|
||||||
|
script = ExtResource("10_etmxr")
|
||||||
|
actions = Array[ExtResource("4_1xo0o")]([SubResource("Resource_g0u1t"), SubResource("Resource_2fp3d")])
|
||||||
|
metadata/_custom_type_script = "uid://mair8nsxn7lp"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_c0i5a"]
|
||||||
|
script = ExtResource("4_t1bs8")
|
||||||
|
initial_speed = 128.0
|
||||||
|
acceleration = -64.0
|
||||||
|
min_speed = 0.0
|
||||||
|
action_speed_clamped = SubResource("Resource_ufsqg")
|
||||||
|
metadata/_custom_type_script = "uid://dntp60my5f65m"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_t1bs8"]
|
||||||
|
script = ExtResource("5_cf1so")
|
||||||
|
bullet_count = 1
|
||||||
|
line_width = 128.0
|
||||||
|
line_normal = Vector2(0.70710677, -0.70710677)
|
||||||
|
metadata/_custom_type_script = "uid://d238qii8i2byl"
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_uu3sg"]
|
[sub_resource type="Resource" id="Resource_uu3sg"]
|
||||||
script = ExtResource("6_sle1e")
|
script = ExtResource("6_sle1e")
|
||||||
behavior = SubResource("Resource_c0i5a")
|
behavior = SubResource("Resource_c0i5a")
|
||||||
pattern = SubResource("Resource_1xo0o")
|
pattern = SubResource("Resource_t1bs8")
|
||||||
textures = Array[Texture2D]([ExtResource("4_hlyn7")])
|
textures = Array[Texture2D]([ExtResource("4_hlyn7")])
|
||||||
hitbox_size = Vector2i(6, 6)
|
hitbox_size = Vector2i(6, 6)
|
||||||
rounds = 5
|
rounds = 100000
|
||||||
round_delay = 1.0
|
round_delay = 1.0
|
||||||
metadata/_custom_type_script = "uid://vus1a0flwtnm"
|
metadata/_custom_type_script = "uid://vus1a0flwtnm"
|
||||||
|
|
||||||
|
|
@ -40,7 +81,7 @@ texture = ExtResource("1_g7g4h")
|
||||||
position = Vector2(100, 99)
|
position = Vector2(100, 99)
|
||||||
|
|
||||||
[node name="BulletSet" type="Node2D" parent="."]
|
[node name="BulletSet" type="Node2D" parent="."]
|
||||||
position = Vector2(110, 192)
|
position = Vector2(111, 152)
|
||||||
script = ExtResource("3_cf1so")
|
script = ExtResource("3_cf1so")
|
||||||
preset = SubResource("Resource_uu3sg")
|
preset = SubResource("Resource_uu3sg")
|
||||||
metadata/_custom_type_script = "uid://cj2fj7snls8aa"
|
metadata/_custom_type_script = "uid://cj2fj7snls8aa"
|
||||||
|
|
|
||||||
12
systems/bullets/actions/bullet_action.gd
Normal file
12
systems/bullets/actions/bullet_action.gd
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
@abstract
|
||||||
|
class_name BulletAction
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
|
||||||
|
## Performs the action on a given [Bullet].
|
||||||
|
func perform(bullet: Bullet) -> void:
|
||||||
|
_perform(bullet)
|
||||||
|
|
||||||
|
|
||||||
|
## Called to perform the action on a given [Bullet].
|
||||||
|
@abstract func _perform(bullet: Bullet) -> void
|
||||||
1
systems/bullets/actions/bullet_action.gd.uid
Normal file
1
systems/bullets/actions/bullet_action.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://mivkgn34ox41
|
||||||
7
systems/bullets/actions/despawn_action.gd
Normal file
7
systems/bullets/actions/despawn_action.gd
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
class_name DespawnAction
|
||||||
|
extends BulletAction
|
||||||
|
## Removes and recycles the [Bullet] when triggered.
|
||||||
|
|
||||||
|
|
||||||
|
func _perform(bullet: Bullet) -> void:
|
||||||
|
bullet.recycle()
|
||||||
1
systems/bullets/actions/despawn_action.gd.uid
Normal file
1
systems/bullets/actions/despawn_action.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://pn143vuxc7wp
|
||||||
12
systems/bullets/actions/multi_action.gd
Normal file
12
systems/bullets/actions/multi_action.gd
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
class_name MultiAction
|
||||||
|
extends BulletAction
|
||||||
|
## Performs a set of [BulletAction]s in order when triggered.
|
||||||
|
|
||||||
|
|
||||||
|
## [BulletAction]s to perform when triggered.
|
||||||
|
@export var actions: Array[BulletAction]
|
||||||
|
|
||||||
|
|
||||||
|
func _perform(bullet: Bullet) -> void:
|
||||||
|
for action in actions:
|
||||||
|
action.perform(bullet)
|
||||||
1
systems/bullets/actions/multi_action.gd.uid
Normal file
1
systems/bullets/actions/multi_action.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://mair8nsxn7lp
|
||||||
26
systems/bullets/actions/spawn_set_action.gd
Normal file
26
systems/bullets/actions/spawn_set_action.gd
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
class_name SpawnSetAction
|
||||||
|
extends BulletAction
|
||||||
|
## Spawns a new [BulletSet] at the [Bullet]'s position when triggered.
|
||||||
|
|
||||||
|
|
||||||
|
## The [BulletPreset] to use for the spawned [BulletSet].
|
||||||
|
@export var preset: BulletPreset
|
||||||
|
|
||||||
|
## If [code]true[/code], the spawned [BulletSet] will be rotated to face the
|
||||||
|
## [Bullet]'s direction.
|
||||||
|
@export var match_direction: bool = false
|
||||||
|
|
||||||
|
## If [code]true[/code], the spawned [BulletSet] will be added as a child of
|
||||||
|
## the [Bullet]'s parent [BulletSet]. If [code]false[/code], it will be added
|
||||||
|
## as a child of that [BulletSet]'s parent [Node].
|
||||||
|
@export var local_coords: bool = false
|
||||||
|
|
||||||
|
|
||||||
|
func _perform(bullet: Bullet) -> void:
|
||||||
|
var bullet_set = BulletSet.new()
|
||||||
|
bullet_set.preset = preset
|
||||||
|
bullet_set.global_position = bullet.global_position
|
||||||
|
if local_coords:
|
||||||
|
bullet.get_parent().add_child(bullet_set)
|
||||||
|
else:
|
||||||
|
bullet.get_parent().get_parent().add_child(bullet_set)
|
||||||
1
systems/bullets/actions/spawn_set_action.gd.uid
Normal file
1
systems/bullets/actions/spawn_set_action.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://oug6n1t6tnor
|
||||||
|
|
@ -3,10 +3,30 @@ class_name BulletBehavior
|
||||||
extends Resource
|
extends Resource
|
||||||
|
|
||||||
|
|
||||||
## Called when a bullet is spawned with this behavior in order to set up
|
## Performs behavior-specific initialization for a [Bullet].
|
||||||
## behavior-specific state.
|
func init_bullet(bullet: Bullet) -> void:
|
||||||
@warning_ignore("unused_parameter")
|
bullet.recycled.connect(deinit_bullet.bind(bullet), CONNECT_ONE_SHOT)
|
||||||
func init_bullet(bullet: Bullet) -> void: pass
|
_init_bullet(bullet)
|
||||||
|
|
||||||
## Called to process a tick of a bullet's movement.
|
|
||||||
@abstract func process_bullet(bullet: Bullet, delta: float) -> void
|
## Cleans up behavior-specific state for a [Bullet].
|
||||||
|
func deinit_bullet(bullet: Bullet) -> void:
|
||||||
|
_deinit_bullet(bullet)
|
||||||
|
|
||||||
|
|
||||||
|
## Processes one tick of a [Bullet]'s movement.
|
||||||
|
func process_bullet(bullet: Bullet, delta: float) -> void:
|
||||||
|
_process_bullet(bullet, delta)
|
||||||
|
|
||||||
|
|
||||||
|
## Called when a [Bullet] is spawned with this behavior in order to set up
|
||||||
|
## behavior-specific state.
|
||||||
|
@abstract func _init_bullet(bullet: Bullet) -> void
|
||||||
|
|
||||||
|
|
||||||
|
## Called when a [Bullet] is recycled in order to clean up behavior-specific state.
|
||||||
|
@abstract func _deinit_bullet(bullet: Bullet) -> void
|
||||||
|
|
||||||
|
|
||||||
|
## Called to process a tick of a [Bullet]'s movement.
|
||||||
|
@abstract func _process_bullet(bullet: Bullet, delta: float) -> void
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,41 @@ extends BulletBehavior
|
||||||
## Rate at which the bullet will speed up.
|
## Rate at which the bullet will speed up.
|
||||||
@export_custom(0, "suffix:px/s²") var acceleration: float = 0.0
|
@export_custom(0, "suffix:px/s²") var acceleration: float = 0.0
|
||||||
|
|
||||||
|
## Speed will be clamped between [member min_speed] and [member max_speed].
|
||||||
|
@export_custom(0, "suffix:px/s") var min_speed: float = -INF
|
||||||
|
## Speed will be clamped between [member min_speed] and [member max_speed].
|
||||||
|
@export_custom(0, "suffix:px/s") var max_speed: float = INF
|
||||||
|
|
||||||
func process_bullet(bullet: Bullet, delta: float) -> void:
|
@export_group("Actions", "action_")
|
||||||
var speed = initial_speed + acceleration * bullet.time_elapsed
|
@export var action_speed_clamped: BulletAction
|
||||||
bullet.position += bullet.direction * speed * delta
|
|
||||||
|
|
||||||
|
var _bullet_data: Dictionary[Bullet, Data] = {}
|
||||||
|
|
||||||
|
|
||||||
|
func _init_bullet(bullet: Bullet) -> void:
|
||||||
|
var data = Data.new()
|
||||||
|
data.speed = initial_speed
|
||||||
|
_bullet_data[bullet] = data
|
||||||
|
|
||||||
|
|
||||||
|
func _deinit_bullet(bullet: Bullet) -> void:
|
||||||
|
_bullet_data.erase(bullet)
|
||||||
|
|
||||||
|
|
||||||
|
func _process_bullet(bullet: Bullet, delta: float) -> void:
|
||||||
|
if not _bullet_data.has(bullet):
|
||||||
|
return
|
||||||
|
var data = _bullet_data[bullet]
|
||||||
|
data.speed += acceleration * delta
|
||||||
|
if not data.already_clamped and (data.speed <= min_speed or data.speed >= max_speed):
|
||||||
|
data.already_clamped = true
|
||||||
|
if action_speed_clamped:
|
||||||
|
action_speed_clamped.perform(bullet)
|
||||||
|
data.speed = clampf(data.speed, min_speed, max_speed)
|
||||||
|
bullet.position += bullet.direction * data.speed * delta
|
||||||
|
|
||||||
|
|
||||||
|
class Data:
|
||||||
|
var speed: float
|
||||||
|
var already_clamped: bool = false
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@ class_name Bullet
|
||||||
extends Area2D
|
extends Area2D
|
||||||
|
|
||||||
|
|
||||||
|
## Emitted whenever a bullet is recycled.
|
||||||
|
signal recycled()
|
||||||
|
|
||||||
|
|
||||||
## The number of bullets to allocate at startup.
|
## The number of bullets to allocate at startup.
|
||||||
const INITIAL_ALLOCATED_BULLETS: int = 2000
|
const INITIAL_ALLOCATED_BULLETS: int = 2000
|
||||||
|
|
||||||
|
|
@ -51,9 +55,10 @@ static func create(
|
||||||
direction: Vector2 = Vector2.RIGHT,
|
direction: Vector2 = Vector2.RIGHT,
|
||||||
face_direction: bool = false,
|
face_direction: bool = false,
|
||||||
) -> Bullet:
|
) -> Bullet:
|
||||||
var bullet: Bullet = _cached_bullets.pop_back()
|
#var bullet: Bullet = _cached_bullets.pop_back()
|
||||||
if not bullet:
|
#if not bullet:
|
||||||
bullet = Bullet.new()
|
#bullet = Bullet.new()
|
||||||
|
var bullet := Bullet.new()
|
||||||
|
|
||||||
bullet.texture = texture
|
bullet.texture = texture
|
||||||
bullet.hitbox_size = hitbox_size
|
bullet.hitbox_size = hitbox_size
|
||||||
|
|
@ -67,8 +72,11 @@ static func create(
|
||||||
## Removes the bullet from the scene tree and returns it to the bullet cache to be
|
## Removes the bullet from the scene tree and returns it to the bullet cache to be
|
||||||
## re-used later.
|
## re-used later.
|
||||||
func recycle() -> void:
|
func recycle() -> void:
|
||||||
get_parent().remove_child(self)
|
#if is_inside_tree():
|
||||||
_cached_bullets.append(self)
|
#get_parent().remove_child(self)
|
||||||
|
#_cached_bullets.append(self)
|
||||||
|
queue_free()
|
||||||
|
recycled.emit()
|
||||||
|
|
||||||
|
|
||||||
static func _static_init() -> void:
|
static func _static_init() -> void:
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,11 @@ func _ready() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
|
if get_child_count() == 0:
|
||||||
|
queue_free()
|
||||||
for bullet in get_children():
|
for bullet in get_children():
|
||||||
if bullet is Bullet:
|
if bullet is Bullet:
|
||||||
preset.behavior.process_bullet(bullet, delta)
|
preset.behavior.process_bullet(bullet, delta)
|
||||||
else:
|
|
||||||
push_error("BulletSet does not support having non-bullet children. Removing child: ", bullet)
|
|
||||||
bullet.queue_free()
|
|
||||||
|
|
||||||
|
|
||||||
func add_bullet(bullet: Bullet) -> void:
|
func add_bullet(bullet: Bullet) -> void:
|
||||||
|
|
|
||||||
26
systems/bullets/spawn_patterns/line_pattern.gd
Normal file
26
systems/bullets/spawn_patterns/line_pattern.gd
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
class_name LinePattern
|
||||||
|
extends BulletSpawnPattern
|
||||||
|
|
||||||
|
|
||||||
|
@export var bullet_count: int
|
||||||
|
@export var line_width: float
|
||||||
|
@export_custom(0, "direction") var line_normal: Vector2 = Vector2.RIGHT
|
||||||
|
|
||||||
|
|
||||||
|
func spawn_bullets(bullet_set: BulletSet, preset: BulletPreset) -> void:
|
||||||
|
for i in bullet_count:
|
||||||
|
var bullet = Bullet.create(
|
||||||
|
preset.textures.pick_random(),
|
||||||
|
preset.hitbox_size,
|
||||||
|
line_normal,
|
||||||
|
preset.face_direction
|
||||||
|
)
|
||||||
|
|
||||||
|
var line = line_normal.orthogonal()
|
||||||
|
var weight = float(i) / float(bullet_count - 1)
|
||||||
|
weight -= 0.5
|
||||||
|
if bullet_count == 1:
|
||||||
|
weight = 0.0
|
||||||
|
bullet.position = line * weight * line_width
|
||||||
|
|
||||||
|
bullet_set.add_bullet(bullet)
|
||||||
1
systems/bullets/spawn_patterns/line_pattern.gd.uid
Normal file
1
systems/bullets/spawn_patterns/line_pattern.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://d238qii8i2byl
|
||||||
Loading…
Add table
Add a link
Reference in a new issue