检测敌人是否被子弹击中
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
您可能还想实例化一些其他场景(例如尸体或爆炸)或播放动画或类似的东西。
我正在尝试通过制作一个简单的 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
您可能还想实例化一些其他场景(例如尸体或爆炸)或播放动画或类似的东西。