From 3880288d57f1ce440108cc4cfb827cc3b725bf74 Mon Sep 17 00:00:00 2001 From: Charles Heckroth Date: Sat, 17 Aug 2024 10:42:05 +0900 Subject: [PATCH 1/7] Add ProjectileEffect base class and basic functionality Adds a new Node type and class called ProjectileEffect. Includes the usage of this class in the player and projectile scenes. Does not include any actual projectile effects yet. --- projectiles/projectile_effect.gd | 64 ++++++++++++++++++++++++++++++ projectiles/projectile_effect.tscn | 6 +++ units/player.gd | 15 ++++++- units/projectile.gd | 22 +++++++++- 4 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 projectiles/projectile_effect.gd create mode 100644 projectiles/projectile_effect.tscn diff --git a/projectiles/projectile_effect.gd b/projectiles/projectile_effect.gd new file mode 100644 index 0000000..6bf7551 --- /dev/null +++ b/projectiles/projectile_effect.gd @@ -0,0 +1,64 @@ +class_name ProjectileEffect +extends Node +# A ProjectileEffect is a set of post-processors meant to be run on every instance of a Projectile. +# This by itself does nothing but is meant to be extended by various types of projectile effect. +# Each effect will compound on the others. Each function will be called by the Projectile scene, +# in order of Effect Priority +# TODO:: Effect Priority as an enum? (to discourage "priority: 9999999") + +# Each modifier is a combination of a double value and a modification type. +# This is to indicate if a modification is additive or multiplicitive. +# The default for all modifiers is MULTIPLICITIVE : 1, ultimately resulting in no effect. +# (To subtract and divide, use negative values and decimals < 1) +enum MODIFICATION_TYPE { + ADD, + MULTIPLY +} +@export var effect_priority = -1 +@export var speed_modifier_type = MODIFICATION_TYPE.MULTIPLY +@export var speed_modifier = 1 +@export var damage_modifier_type = MODIFICATION_TYPE.MULTIPLY +@export var damage_modifier = 1 +@export var scale_modifier_type = MODIFICATION_TYPE.MULTIPLY +@export var scale_modifier = 1 + + +# Modify the logic that adds the projectile as a child to the scene. +# This can be used to change spawn locations, quantities, etc. +func modify_creation(owner: Node): + pass + +# Modify the physics logic of the projectile. This function will be called +# during the _physics_process. +# Uses exported variables by default, and should only be overridden if you're +# doing something really interesting. +func modify_physics(position_modifier: Vector2) -> Vector2: + # TODO:: How does godot mutability work? we do NOT want to modify the original modifier + var return_modifier = position_modifier + if speed_modifier_type == MODIFICATION_TYPE.MULTIPLY: + return_modifier *= speed_modifier + elif speed_modifier_type == MODIFICATION_TYPE.ADD: + return_modifier += speed_modifier + return return_modifier + + +# Simple changes to the appearance using built-in features. +# By default, +func modify_appearance(): + pass + + +# To change the sprite itself, elements of the animation, or otherwise add effects +# Hard changes, rather than additions, will not +func modify_animation(): + pass + + +# Called when the node enters the scene tree for the first time. +func _enter_tree(): + var projectile = get_owner() + if projectile: + # Projectile scenes are instantiated before being added to the tree + # This function will effectively be called twice, but some operations + # require the parent node to be present first. + projectile.scale_projectile(modify_appearance(projectile.scale)) diff --git a/projectiles/projectile_effect.tscn b/projectiles/projectile_effect.tscn new file mode 100644 index 0000000..75f50de --- /dev/null +++ b/projectiles/projectile_effect.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://bwxewmel1e8si"] + +[ext_resource type="Script" path="res://projectiles/projectile_effect.gd" id="1_eosdr"] + +[node name="ProjectileEffect" type="Node"] +script = ExtResource("1_eosdr") diff --git a/units/player.gd b/units/player.gd index ac4bf2b..fee8fe0 100644 --- a/units/player.gd +++ b/units/player.gd @@ -9,11 +9,22 @@ const HORIZONTAL_BUFFER = 75 @export var Projectile : PackedScene @onready var projectile_spawner = $ProjectileSpawner +var DoubleLaserEffect : PackedScene = preload("res://projectiles/double_laser.tscn") +var HugeLaserEffect : PackedScene = preload("res://projectiles/huge_laser.tscn") +var FastLaserEffect : PackedScene = preload("res://projectiles/fast_laser.tscn") # Called when the node enters the scene tree for the first time. func _ready(): Projectile = load("res://units/projectile.tscn") +func fire(): + print('fired!') + var p = Projectile.instantiate() + # Effects must be instantiated for each projectile. + # Finding a way to manage "which effects we need to instantiate" and + # "Which effects are actually on this projectile" is key + var effects = [DoubleLaserEffect, HugeLaserEffect, FastLaserEffect] + p.spawn(owner, effects, transform) # Called every frame. 'delta' is the elapsed time since the previous frame. func _physics_process(delta): @@ -32,6 +43,6 @@ func _physics_process(delta): if Input.is_action_just_pressed("fire"): print('fired!') var p = Projectile.instantiate() - owner.add_child(p) + p.spawn(owner, projectile_effects) + # TODO:: This transform should probably be modifiable by projectile effects too? p.transform = projectile_spawner.global_transform - diff --git a/units/projectile.gd b/units/projectile.gd index b261e43..246fb5c 100644 --- a/units/projectile.gd +++ b/units/projectile.gd @@ -1,11 +1,29 @@ extends Area2D const SPEED = 750 +var projectile_effects: Array[ProjectileEffect] = [] -func _physics_process(delta): - position += transform.x * SPEED * delta +func spawn(owner: Node, spawn_with_projectile_effects: Array, parent_transform: Transform2D): + var local_transform = parent_transform + for effect in spawn_with_projectile_effects: + var instance = effect.instantiate() + projectile_effects.append(instance) + add_child(instance) + instance.set_owner(self) + instance.modify_creation(owner, spawn_with_projectile_effects, local_transform) + # Spawn the default projectile + # TODO:: Projectile spawn modification may want to prevent the default from spawning + # how do? + owner.add_child(self) + projectile_effects = projectile_effects + +func _physics_process(delta): + var position_modifier = transform.x * SPEED * delta + for effect in projectile_effects: + position_modifier = effect.modify_physics(position_modifier) + set_position(position + position_modifier) func _on_area_entered(area): # TODO: apply effects on enemy hit. For now just despawn. From ccca142878d7281b2c1c43c54413d17fdd13b3c2 Mon Sep 17 00:00:00 2001 From: Charles Heckroth Date: Sat, 17 Aug 2024 13:19:02 +0900 Subject: [PATCH 2/7] Add a double laser projectile effect. This effect adds an identical lazer ouput offset from the original laser. It also makes some modifications to how the firing mechanism and effects dispatch is handled, to make it easier to offload effect mechanism management to each effect. --- projectiles/double_laser.gd | 21 +++++++++++++++++++++ projectiles/double_laser.tscn | 6 ++++++ projectiles/projectile_effect.gd | 2 +- units/player.gd | 13 +++---------- units/projectile.gd | 15 +++++++-------- 5 files changed, 38 insertions(+), 19 deletions(-) create mode 100644 projectiles/double_laser.gd create mode 100644 projectiles/double_laser.tscn diff --git a/projectiles/double_laser.gd b/projectiles/double_laser.gd new file mode 100644 index 0000000..08584f8 --- /dev/null +++ b/projectiles/double_laser.gd @@ -0,0 +1,21 @@ +class_name EffectDoubleLaser +extends ProjectileEffect + +var Projectile : PackedScene = preload("res://units/projectile.tscn") +@export var laser_offset = Vector2(0, -50) +const is_double_laser = true + +func check_not_double_laser(effect: ProjectileEffect) -> bool: + # TODO:: Filter on type? This implementation is Bad + if "is_double_laser" in effect: + return not effect.is_double_laser + return true + +func modify_creation(owner: Node, projectile_effects: Array[ProjectileEffect], transform: Transform2D): + var p = Projectile.instantiate() + # TODO:: Stacking double-lasers? would mean we only want to filter 1 out of this list. + var non_recursive_effects = projectile_effects.filter(check_not_double_laser) + var doubled_transform = transform + # TODO:: Do we want to offset the laser, or do we want to angle out of the same point of origin? + doubled_transform.origin += laser_offset + p.spawn(owner, non_recursive_effects, doubled_transform) diff --git a/projectiles/double_laser.tscn b/projectiles/double_laser.tscn new file mode 100644 index 0000000..3db6955 --- /dev/null +++ b/projectiles/double_laser.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://dgp68vbl25onx"] + +[ext_resource type="Script" path="res://projectiles/double_laser.gd" id="1_wqupk"] + +[node name="DoubleLaser" type="Node"] +script = ExtResource("1_wqupk") diff --git a/projectiles/projectile_effect.gd b/projectiles/projectile_effect.gd index 6bf7551..d621cc3 100644 --- a/projectiles/projectile_effect.gd +++ b/projectiles/projectile_effect.gd @@ -25,7 +25,7 @@ enum MODIFICATION_TYPE { # Modify the logic that adds the projectile as a child to the scene. # This can be used to change spawn locations, quantities, etc. -func modify_creation(owner: Node): +func modify_creation(owner: Node, projectile_effects: Array[ProjectileEffect], transform: Transform2D): pass # Modify the physics logic of the projectile. This function will be called diff --git a/units/player.gd b/units/player.gd index fee8fe0..c05fc7a 100644 --- a/units/player.gd +++ b/units/player.gd @@ -16,15 +16,12 @@ var FastLaserEffect : PackedScene = preload("res://projectiles/fast_laser.tscn") # Called when the node enters the scene tree for the first time. func _ready(): Projectile = load("res://units/projectile.tscn") + _add_test_effects() func fire(): print('fired!') var p = Projectile.instantiate() - # Effects must be instantiated for each projectile. - # Finding a way to manage "which effects we need to instantiate" and - # "Which effects are actually on this projectile" is key - var effects = [DoubleLaserEffect, HugeLaserEffect, FastLaserEffect] - p.spawn(owner, effects, transform) + p.spawn(owner, projectile_effects, transform) # Called every frame. 'delta' is the elapsed time since the previous frame. func _physics_process(delta): @@ -41,8 +38,4 @@ func _physics_process(delta): position.x += HORIZONTAL_SPEED * delta if Input.is_action_just_pressed("fire"): - print('fired!') - var p = Projectile.instantiate() - p.spawn(owner, projectile_effects) - # TODO:: This transform should probably be modifiable by projectile effects too? - p.transform = projectile_spawner.global_transform + fire() diff --git a/units/projectile.gd b/units/projectile.gd index 246fb5c..2dd555a 100644 --- a/units/projectile.gd +++ b/units/projectile.gd @@ -4,19 +4,18 @@ const SPEED = 750 var projectile_effects: Array[ProjectileEffect] = [] -func spawn(owner: Node, spawn_with_projectile_effects: Array, parent_transform: Transform2D): - var local_transform = parent_transform - for effect in spawn_with_projectile_effects: - var instance = effect.instantiate() - projectile_effects.append(instance) - add_child(instance) - instance.set_owner(self) - instance.modify_creation(owner, spawn_with_projectile_effects, local_transform) +func spawn(owner: Node, spawn_with_projectile_effects: Array[ProjectileEffect], parent_transform: Transform2D): + # Execute any spawn modification effects for the projectile + print("spawned!") + projectile_effects = spawn_with_projectile_effects + for effect in projectile_effects: + effect.modify_creation(owner, projectile_effects, parent_transform) # Spawn the default projectile # TODO:: Projectile spawn modification may want to prevent the default from spawning # how do? owner.add_child(self) projectile_effects = projectile_effects + transform = parent_transform func _physics_process(delta): From 756ecd3d26f8605859994fe9b93767efb79a7bcd Mon Sep 17 00:00:00 2001 From: Charles Heckroth Date: Sat, 17 Aug 2024 21:21:18 +0900 Subject: [PATCH 3/7] Add Huge Laser projectile effect This adds a projectile effect that makes lasers huge. It includes refactoring to the projectile effect engine to allow effects to directly influence the parent node's size --- projectiles/huge_laser.gd | 2 ++ projectiles/huge_laser.tscn | 7 +++++++ projectiles/projectile_effect.gd | 33 +++++++++++++++++++------------- units/projectile.gd | 6 ++++-- 4 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 projectiles/huge_laser.gd create mode 100644 projectiles/huge_laser.tscn diff --git a/projectiles/huge_laser.gd b/projectiles/huge_laser.gd new file mode 100644 index 0000000..233c391 --- /dev/null +++ b/projectiles/huge_laser.gd @@ -0,0 +1,2 @@ +class_name HugeLaser +extends ProjectileEffect diff --git a/projectiles/huge_laser.tscn b/projectiles/huge_laser.tscn new file mode 100644 index 0000000..093cff2 --- /dev/null +++ b/projectiles/huge_laser.tscn @@ -0,0 +1,7 @@ +[gd_scene load_steps=2 format=3 uid="uid://i6l7jkbauvmf"] + +[ext_resource type="Script" path="res://projectiles/huge_laser.gd" id="1_ouvu5"] + +[node name="HugeLaser" type="Node"] +script = ExtResource("1_ouvu5") +scale_modifier = 10 diff --git a/projectiles/projectile_effect.gd b/projectiles/projectile_effect.gd index d621cc3..3c111a3 100644 --- a/projectiles/projectile_effect.gd +++ b/projectiles/projectile_effect.gd @@ -25,31 +25,38 @@ enum MODIFICATION_TYPE { # Modify the logic that adds the projectile as a child to the scene. # This can be used to change spawn locations, quantities, etc. -func modify_creation(owner: Node, projectile_effects: Array[ProjectileEffect], transform: Transform2D): +func modify_creation(owner: Node, projectile_effects: Array, transform: Transform2D): pass +func _calculate_vector_modification( + base_value: Vector2, + modifier_value: int, + modifier_type: MODIFICATION_TYPE +): + # TODO:: How does godot mutability work? we do NOT want to modify the original modifier + var local_modifier = base_value + if modifier_type == MODIFICATION_TYPE.MULTIPLY: + local_modifier *= modifier_value + elif modifier_type == MODIFICATION_TYPE.ADD: + local_modifier += modifier_value + return local_modifier + # Modify the physics logic of the projectile. This function will be called # during the _physics_process. # Uses exported variables by default, and should only be overridden if you're # doing something really interesting. -func modify_physics(position_modifier: Vector2) -> Vector2: - # TODO:: How does godot mutability work? we do NOT want to modify the original modifier - var return_modifier = position_modifier - if speed_modifier_type == MODIFICATION_TYPE.MULTIPLY: - return_modifier *= speed_modifier - elif speed_modifier_type == MODIFICATION_TYPE.ADD: - return_modifier += speed_modifier - return return_modifier +func modify_physics(physics_vector: Vector2) -> Vector2: + return _calculate_vector_modification(physics_vector, speed_modifier, speed_modifier_type) # Simple changes to the appearance using built-in features. -# By default, -func modify_appearance(): - pass +# By default, modifies the scale of the projectile. +func modify_appearance(scale: Vector2) -> Vector2: + return _calculate_vector_modification(owner.scale, scale_modifier, scale_modifier_type) # To change the sprite itself, elements of the animation, or otherwise add effects -# Hard changes, rather than additions, will not +# Hard changes, rather than additions, will be subject to effect_priority. func modify_animation(): pass diff --git a/units/projectile.gd b/units/projectile.gd index 2dd555a..fea3bc2 100644 --- a/units/projectile.gd +++ b/units/projectile.gd @@ -8,14 +8,16 @@ func spawn(owner: Node, spawn_with_projectile_effects: Array[ProjectileEffect], # Execute any spawn modification effects for the projectile print("spawned!") projectile_effects = spawn_with_projectile_effects + var local_transform = parent_transform for effect in projectile_effects: - effect.modify_creation(owner, projectile_effects, parent_transform) + add_child(effect.instantiate()) + effect.modify_creation(owner, projectile_effects, local_transform) # Spawn the default projectile # TODO:: Projectile spawn modification may want to prevent the default from spawning # how do? owner.add_child(self) projectile_effects = projectile_effects - transform = parent_transform + transform = local_transform func _physics_process(delta): From 6090e51fa957137a13bd3df81256236f15277e20 Mon Sep 17 00:00:00 2001 From: Charles Heckroth Date: Sun, 18 Aug 2024 12:02:46 +0900 Subject: [PATCH 4/7] Add projectile scaling workaround Adds a workaround that manually scales the children of the Projectile scene. This is due to a problem where the projectile root node scale does not propagate down to the sprite or collision shape within it. https://github.com/godotengine/godot/issues/5734 --- units/projectile.gd | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/units/projectile.gd b/units/projectile.gd index fea3bc2..4172173 100644 --- a/units/projectile.gd +++ b/units/projectile.gd @@ -10,7 +10,8 @@ func spawn(owner: Node, spawn_with_projectile_effects: Array[ProjectileEffect], projectile_effects = spawn_with_projectile_effects var local_transform = parent_transform for effect in projectile_effects: - add_child(effect.instantiate()) + add_child(effect) + effect.set_owner(self) effect.modify_creation(owner, projectile_effects, local_transform) # Spawn the default projectile # TODO:: Projectile spawn modification may want to prevent the default from spawning @@ -19,6 +20,13 @@ func spawn(owner: Node, spawn_with_projectile_effects: Array[ProjectileEffect], projectile_effects = projectile_effects transform = local_transform +func scale_projectile(new_scale: Vector2): + $Sprite2D.scale = new_scale + $CollisionShape2D.scale = new_scale + +func _ready(): + if scale != Vector2.ONE: + scale_projectile(scale) func _physics_process(delta): var position_modifier = transform.x * SPEED * delta @@ -30,3 +38,6 @@ func _on_area_entered(area): # TODO: apply effects on enemy hit. For now just despawn. queue_free() area.owner.queue_free() + +func _integrate_forces(delta): + scale = Vector2(100, 100) From 0c1217ec43e5876a0adf3f4349222f4075b936a4 Mon Sep 17 00:00:00 2001 From: Charles Heckroth Date: Sun, 18 Aug 2024 15:10:53 +0900 Subject: [PATCH 5/7] Refactor to use packedscene instead of node type This refactors the projectile effect system to use packed scenes instead of the base class node type ProjectileEffect. This is due to the requirement for these scenes to be instantiated for each projectile, not a shared resource. Without this change, effects that modify the scene tree (such as HUGE LASER) do not work. --- projectiles/double_laser.gd | 9 ++++++--- units/player.gd | 8 ++++++-- units/projectile.gd | 17 ++++++++++------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/projectiles/double_laser.gd b/projectiles/double_laser.gd index 08584f8..56121bf 100644 --- a/projectiles/double_laser.gd +++ b/projectiles/double_laser.gd @@ -2,16 +2,19 @@ class_name EffectDoubleLaser extends ProjectileEffect var Projectile : PackedScene = preload("res://units/projectile.tscn") + @export var laser_offset = Vector2(0, -50) const is_double_laser = true -func check_not_double_laser(effect: ProjectileEffect) -> bool: +func check_not_double_laser(effect: PackedScene) -> bool: # TODO:: Filter on type? This implementation is Bad if "is_double_laser" in effect: return not effect.is_double_laser - return true -func modify_creation(owner: Node, projectile_effects: Array[ProjectileEffect], transform: Transform2D): + # TODO:: Hacky? but const on the node does not work for packed scenes + return effect.resource_path != "res://projectiles/double_laser.tscn" + +func modify_creation(owner: Node, projectile_effects: Array, transform: Transform2D): var p = Projectile.instantiate() # TODO:: Stacking double-lasers? would mean we only want to filter 1 out of this list. var non_recursive_effects = projectile_effects.filter(check_not_double_laser) diff --git a/units/player.gd b/units/player.gd index c05fc7a..e704f29 100644 --- a/units/player.gd +++ b/units/player.gd @@ -9,9 +9,9 @@ const HORIZONTAL_BUFFER = 75 @export var Projectile : PackedScene @onready var projectile_spawner = $ProjectileSpawner +var FastLaserEffect : PackedScene = preload("res://projectiles/fast_laser.tscn") var DoubleLaserEffect : PackedScene = preload("res://projectiles/double_laser.tscn") var HugeLaserEffect : PackedScene = preload("res://projectiles/huge_laser.tscn") -var FastLaserEffect : PackedScene = preload("res://projectiles/fast_laser.tscn") # Called when the node enters the scene tree for the first time. func _ready(): @@ -21,7 +21,11 @@ func _ready(): func fire(): print('fired!') var p = Projectile.instantiate() - p.spawn(owner, projectile_effects, transform) + # Effects must be instantiated for each projectile. + # Finding a way to manage "which effects we need to instantiate" and + # "Which effects are actually on this projectile" is key + var effects = [DoubleLaserEffect, HugeLaserEffect] + p.spawn(owner, effects, transform) # Called every frame. 'delta' is the elapsed time since the previous frame. func _physics_process(delta): diff --git a/units/projectile.gd b/units/projectile.gd index 4172173..5b3b775 100644 --- a/units/projectile.gd +++ b/units/projectile.gd @@ -1,18 +1,20 @@ extends Area2D const SPEED = 750 -var projectile_effects: Array[ProjectileEffect] = [] +var projectile_effects: Array = [] -func spawn(owner: Node, spawn_with_projectile_effects: Array[ProjectileEffect], parent_transform: Transform2D): +func spawn(owner: Node, spawn_with_projectile_effects: Array, parent_transform: Transform2D): # Execute any spawn modification effects for the projectile print("spawned!") - projectile_effects = spawn_with_projectile_effects + #projectile_effects = spawn_with_projectile_effects var local_transform = parent_transform - for effect in projectile_effects: - add_child(effect) - effect.set_owner(self) - effect.modify_creation(owner, projectile_effects, local_transform) + for effect in spawn_with_projectile_effects: + var instance = effect.instantiate() + projectile_effects.append(instance) + add_child(instance) + instance.set_owner(self) + instance.modify_creation(owner, spawn_with_projectile_effects, local_transform) # Spawn the default projectile # TODO:: Projectile spawn modification may want to prevent the default from spawning # how do? @@ -23,6 +25,7 @@ func spawn(owner: Node, spawn_with_projectile_effects: Array[ProjectileEffect], func scale_projectile(new_scale: Vector2): $Sprite2D.scale = new_scale $CollisionShape2D.scale = new_scale + scale = new_scale func _ready(): if scale != Vector2.ONE: From f08db8e4b1d611d1b2de874721f0bc4bf866b322 Mon Sep 17 00:00:00 2001 From: Charles Heckroth Date: Sun, 18 Aug 2024 19:02:30 +0900 Subject: [PATCH 6/7] Add Fast Laser Effect Adds a new effect that hooks in to the physics system to make lasers go pewpew faser --- projectiles/fast_laser.tscn | 7 +++++++ units/player.gd | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 projectiles/fast_laser.tscn diff --git a/projectiles/fast_laser.tscn b/projectiles/fast_laser.tscn new file mode 100644 index 0000000..95d660d --- /dev/null +++ b/projectiles/fast_laser.tscn @@ -0,0 +1,7 @@ +[gd_scene load_steps=2 format=3 uid="uid://dj6jn0ia62yba"] + +[ext_resource type="Script" path="res://projectiles/projectile_effect.gd" id="1_jlt11"] + +[node name="FastLaser" type="Node"] +script = ExtResource("1_jlt11") +speed_modifier = 3 diff --git a/units/player.gd b/units/player.gd index e704f29..d400c8e 100644 --- a/units/player.gd +++ b/units/player.gd @@ -9,14 +9,13 @@ const HORIZONTAL_BUFFER = 75 @export var Projectile : PackedScene @onready var projectile_spawner = $ProjectileSpawner -var FastLaserEffect : PackedScene = preload("res://projectiles/fast_laser.tscn") var DoubleLaserEffect : PackedScene = preload("res://projectiles/double_laser.tscn") var HugeLaserEffect : PackedScene = preload("res://projectiles/huge_laser.tscn") +var FastLaserEffect : PackedScene = preload("res://projectiles/fast_laser.tscn") # Called when the node enters the scene tree for the first time. func _ready(): Projectile = load("res://units/projectile.tscn") - _add_test_effects() func fire(): print('fired!') @@ -24,7 +23,7 @@ func fire(): # Effects must be instantiated for each projectile. # Finding a way to manage "which effects we need to instantiate" and # "Which effects are actually on this projectile" is key - var effects = [DoubleLaserEffect, HugeLaserEffect] + var effects = [DoubleLaserEffect, HugeLaserEffect, FastLaserEffect] p.spawn(owner, effects, transform) # Called every frame. 'delta' is the elapsed time since the previous frame. From 82f3f7f431b40e83e6dd0eaa08e5515d763ba86f Mon Sep 17 00:00:00 2001 From: Charles Heckroth Date: Mon, 19 Aug 2024 21:00:06 +0900 Subject: [PATCH 7/7] Move projectiles to layer 2, add enemy mask 2 This moves projectiles to a new collision layer, and adds that layer to the mask for enemies. This is to do two things: (1) Prevent lasers from colliding with themselves ("Huge" and "Double" lasers can overlap), (2) allow enemies to queue_free themselves, instead of leaving that burden on the projectile --- units/enemy.gd | 3 +++ units/enemy.tscn | 4 +++- units/projectile.gd | 1 - units/projectile.tscn | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/units/enemy.gd b/units/enemy.gd index acad858..1c4085b 100644 --- a/units/enemy.gd +++ b/units/enemy.gd @@ -10,3 +10,6 @@ func _physics_process(delta): func _on_visible_on_screen_notifier_2d_screen_exited(): queue_free() + +func _on_area_entered(area): + queue_free() diff --git a/units/enemy.tscn b/units/enemy.tscn index 43a387d..b6cd286 100644 --- a/units/enemy.tscn +++ b/units/enemy.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=4 format=3 uid="uid://4fjgeuv7aun7"] +[gd_scene load_steps=4 format=3 uid="uid://bdsjg08y1h6yh"] [ext_resource type="Script" path="res://units/enemy.gd" id="1_6h8a0"] [ext_resource type="Texture2D" uid="uid://dqkvsqmwue64p" path="res://units/PNG_Parts&Spriter_Animation/Ship1/Ship1.png" id="1_ndkjl"] @@ -13,6 +13,7 @@ script = ExtResource("1_6h8a0") texture = ExtResource("1_ndkjl") [node name="Area2D" type="Area2D" parent="."] +collision_mask = 3 [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] position = Vector2(0, -0.75) @@ -20,4 +21,5 @@ shape = SubResource("RectangleShape2D_mvxux") [node name="VisibleOnScreenNotifier2D" type="VisibleOnScreenNotifier2D" parent="."] +[connection signal="area_entered" from="Area2D" to="." method="_on_area_entered"] [connection signal="screen_exited" from="VisibleOnScreenNotifier2D" to="." method="_on_visible_on_screen_notifier_2d_screen_exited"] diff --git a/units/projectile.gd b/units/projectile.gd index 5b3b775..edfa3da 100644 --- a/units/projectile.gd +++ b/units/projectile.gd @@ -40,7 +40,6 @@ func _physics_process(delta): func _on_area_entered(area): # TODO: apply effects on enemy hit. For now just despawn. queue_free() - area.owner.queue_free() func _integrate_forces(delta): scale = Vector2(100, 100) diff --git a/units/projectile.tscn b/units/projectile.tscn index b3301d4..833b8cb 100644 --- a/units/projectile.tscn +++ b/units/projectile.tscn @@ -8,6 +8,7 @@ radius = 4.0 [node name="Projectile" type="Area2D"] position = Vector2(68, 1) +collision_layer = 2 script = ExtResource("1_t6pyo") [node name="Sprite2D" type="Sprite2D" parent="."]