Reputation: 91
I am trying to learn Godot by making a simple 2D shooter, but am running into a problem. I do not know how to detect if an enemy has been shot by a bullet. My bullets are Area2D nodes with a Sprite, and CollisionShape2D node attached. My enemies are KinematicBody2D nodes with a Sprite, and CollisionShape2D node attached. The enemy also has a timer attached, but that is not important.
Here is the enemy code:
extends KinematicBody2D
var speed = 200
var velocity = Vector2(-0.5, 1)
var bullet_preload = preload("res://Enemy/EnemyBullet.tscn")
func _ready():
randomize()
velocity.y = [1, -1][randi() % 2]
func _physics_process(delta):
var collision = move_and_collide(velocity * speed * delta)
if collision:
velocity = velocity.bounce(collision.normal)
if position.x < -20:
print("Enemy Despawned")
queue_free()
if $ShootDelay.time_left == 0:
var bullet = bullet_preload.instance()
bullet.position.x = position.x - 18
bullet.position.y = position.y + 6
get_parent().add_child(bullet)
$ShootDelay.start()
Here is my player bullet code:
extends Area2D
var speed = 600
var velocity = Vector2(1, 0)
func _process(delta):
position.x += speed * delta
if position.x > 1044:
queue_free()
func _on_PlayerBullet_body_entered(body):
queue_free()
It may be important to note that the player bullet and enemy scenes are not in the same scene tree, and there is no way (that I know of) of sending a signal between them. They are both being instanced to my main root node that contains the entire game via code.
If I need to include other details, please let me know.
Upvotes: 2
Views: 1667
Reputation: 40295
On your _on_PlayerBullet_body_entered
you a body
that has a reference to whatever the Area2D
collided with, you can use it to communicate with it.
For example, you can call a method on it. Which could, of course could be queue_free
:
func _on_PlayerBullet_body_entered(body):
body.queue_free()
queue_free()
However, I'm going to suggest against it. Instead let us come up with a method that you can implement to have whatever behavior you want:
func _on_PlayerBullet_body_entered(body):
body.shot()
queue_free()
Of course, we have the problem that we are not sure if it has that method… So, let us check for it:
func _on_PlayerBullet_body_entered(body):
if body.has_method(shot):
body.shot()
queue_free()
Then you would add that method on the objects that react to the bullet impact. Back to queue_free
, it could be:
func shot() -> void:
queue_free()
Or you could have it be something like this:
var health := 5
func shot() -> void:
health -= 1
if health <= 0:
queue_free()
Or, you could have it set a flag and deal with it on _physics_process
or where and whenever appropiate:
var was_shot := 5
func _physics_process(_delta) -> void:
if was_shot:
queue_free()
func shot() -> void:
was_shot = true
Of course, aside form queue_free
you may want to instance some other scene (e.g. a corpse or an explosion) or play an animation or something like that.
Upvotes: 3