Сколько экземпляров и как часто вы хотите запускать?
Вы говорите:
Проблема в том, что экземпляр объекта создается много раз.
Но сколько раз это много?
Я отвечу на вопросы, которые приходят на ум. Кроме того, некоторые из них можно комбинировать.
Если этот ответ не охватывает то, что вы хотите… Вам нужно будет уточнить. Обнажив это, надеюсь, вы сможете понять это, используя следующие инструменты:
- Выбор между
is_action_pressed
и is_action_just_pressed
.
- Использование
Timer
s (фактический объект или импровизированный с delta
).
- Сигналы (включая, помимо прочего,
timeout
сигналы фактических Timer
s).
Говоря о сигналах, все нижеприведенные подходы не требуют специальных знаний экземпляра (за исключением того, что он какой-то 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
Я сделал это переменной экспорта, чтобы вы могли редактировать ее с панели инспектора.
*Этот подход хорошо сочетается с "Один раз на вход" (т. е. используйте 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
). Или, в качестве альтернативы, с параметром "Один раз так часто" (т. е. временное время), чтобы ограничить количество экземпляров.
Время от времени Мы можем использовать ту же стратегию импровизированного таймера, которую вы используете для срока службы пули:
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
Вот мой ответ! Благодарю вас! Проблема заключалась в следующем: экземпляры создавались много раз за короткое время, и я хотел добавить охлаждение. Спасибо за Ваш ответ!