您要实例化多少个实例以及多久实例化一次?
你说:
问题是对象被实例化了很多次。
但是多少次是很多?
我会回答想到的案例。此外,其中一些可以组合。
如果这个答案没有涵盖你想要的……你需要更具体。除此之外,希望你可以考虑这些工具来解决这个问题:
- 在
is_action_pressed 和is_action_just_pressed 之间进行选择。
-
Timers的使用(实际对象或临时用delta)。
- 信号(包括但不限于实际
Timers的timeout信号)。
说到信号,下面的所有方法都不需要实例的特殊知识(除了它是一些Node2D)。您可以将自定义信号添加到实例并连接到它们以了解何时可以创建更多实例。
您可以做的另一件事是保存对实例的引用以询问它们(例如,您可以使用is_instance_valid)。但是,我在下面介绍了一种使用tree_exited 信号的方法,我认为这种方法更通用。
您还可以通过调用方法跟踪来利用 AnimationPlayer。例如,如果您需要在动画的特定帧上添加实例。
每个输入一次
只要按下输入,此代码就会实例化每个物理帧:
func _physics_process(delta:float) -> void:
if Input.is_action_pressed("ui_accept"):
createLaser()
如果您只想在按下输入时实例化第一个物理帧,请使用is_action_just_pressed:
func _physics_process(delta:float) -> void:
if Input.is_action_just_pressed("ui_accept"):
createLaser()
每隔一段时间一次
我们可以使用与子弹寿命相同的临时计时器策略:
var instance_period:float = 10.0
var instance_elapsed:float = 0.0
func _physics_process(delta:float) -> void:
instance_elapsed += delta
if Input.is_action_pressed("ui_accept") and instance_elapsed > instance_period:
createLaser()
instance_elapsed = 0.0
只有一次
如果你只想要一个,我们可以保存一个布尔变量来知道我们是否已经实例化:
var did_instance:bool = false
func _physics_process(delta:float) -> void:
if Input.is_action_pressed("ui_accept") and not did_instance:
createLaser()
did_instance = true
只有固定的次数
你可以使用整数倒计时:
export var yet_to_instance:int = 10
func _physics_process(delta:float) -> void:
if Input.is_action_pressed("ui_accept") and yet_to_instance > 0:
createLaser()
yet_to_instance -= 1
我将其设为导出变量,以便您可以从 Inspector 面板对其进行编辑。
*此方法与“每次输入一次”(即使用is_action_just_pressed)很好地结合在一起。当数字为 1 时,您也可以考虑“仅一次”的特殊情况。
只有一次充电次数
这是一种将临时计时器与固定实例次数相结合的特殊方式:
var recharge_period:float = 10.0
var recharge_elapsed:float = 0.0
export var max_to_instance:int = 10
onready var yet_to_instance:int = max_to_instance
func _physics_process(delta:float) -> void:
if Input.is_action_pressed("ui_accept") and yet_to_instance > 0:
createLaser()
yet_to_instance -= 1
# recharge_elapsed = 0.0
recharge_elapsed += delta
if recharge_elapsed > recharge_period:
if yet_to_instance < max_to_instance:
yet_to_instance += 1
recharge_elapsed = 0.0
通过这种方式,您可以创建的实例数量最多可增加超时。如果您想在输入时阻止该数字增加,则可以取消注释 # instance_elapsed = 0.0。 您可以将其视为自动重新加载。
此方法与“每次输入一次”(即使用 is_action_just_pressed)很好地结合在一起。或者使用“每隔一段时间”(即临时时间)来限制实例率。
最多活一个量
我们将连接到tree_exited 信号以更新我们的计数:
const laser = preload("res://scenes/space_ship/laser/Laser.tscn")
export var max_to_instance:int = 20
func _physics_process(delta:float) -> void:
if Input.is_action_pressed("ui_accept") and max_to_instance > 0:
createLaser()
func createLaser() -> void:
createLaserFrom($Cannons/left_cannon)
createLaserFrom($Cannons/right_cannon)
func createLaserFrom(cannon:Node2D) -> void:
var fired_laser = laser.instance()
max_to_instance -= 1
fire_laser.connect("tree_exited", self, "laser_exited")
get_parent().add_child(fired_laser)
fired_laser.global_position = cannon.global_position
func laser_exited() -> void:
max_to_instance += 1
这种方法与“每次输入一次”(即使用is_action_just_pressed)很好地结合在一起。或者使用“每隔一段时间”(即临时时间)来限制实例率。