检测敌人是否被子弹击中

Detecting if an enemy was shot by bullet

我正在尝试通过制作一个简单的 2D 射击游戏来学习 Godot,但是 运行 遇到了问题。我不知道如何检测敌人是否被子弹击中。我的项目符号是带有 Sprite 的 Area2D 节点和附加的 CollisionShape2D 节点。我的敌人是带有 Sprite 的 KinematicBody2D 节点和附加的 CollisionShape2D 节点。敌人也附有计时器,但这并不重要。

敌人代码如下:

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()

这是我的播放器子弹代码:

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()

值得注意的是,玩家子弹和敌人场景不在同一场景树中,而且(据我所知)无法在它们之间发送信号。它们都通过代码实例化到我的主根节点,该节点包含整个游戏。

如果我需要包含其他详细信息,请告诉我。

在你的 _on_PlayerBullet_body_entered 上你有一个 body 引用了 Area2D 碰撞的任何东西,你可以用它来与之通信。

例如,您可以在其上调用方法。这当然可以是 queue_free:

func _on_PlayerBullet_body_entered(body):
    body.queue_free()
    queue_free()

但是,我要反对它。相反,让我们想出一个方法,您可以实现该方法以获得您想要的任何行为:

func _on_PlayerBullet_body_entered(body):
    body.shot()
    queue_free()

当然,我们有一个问题,我们不确定它是否有那个方法......所以,让我们检查一下:

func _on_PlayerBullet_body_entered(body):
    if body.has_method(shot):
        body.shot()

    queue_free()

然后您将在对子弹冲击做出反应的对象上添加该方法。回到queue_free,可能是:

func shot() -> void:
    queue_free()

或者你可以这样写:

var health := 5

func shot() -> void:
    health -= 1
    if health <= 0:
        queue_free()

或者,您可以让它设置一个标志并在 _physics_process 或任何合适的时间和地点处理它:

var was_shot := 5

func _physics_process(_delta) -> void:
    if was_shot:
        queue_free()

func shot() -> void:
    was_shot = true

当然,除了形式 queue_free 您可能还想实例化一些其他场景(例如尸体或爆炸)或播放动画或类似的东西。