Разбиваем астероиды
Часть раздела Проекты путешествия по Godot на Coddy. Урок 18 из 36.
Попавший в камень выстрел должен расколоть его надвое. Камень сообщает о том, что он разбился, с помощью signal broken(rock) и broken.emit(self). self — это сам камень, поэтому обработчик знает, где он находился и как двигался.
spawn_rock соединяет каждый новый камень с помощью rock.broken.connect(_on_rock_broken), а эта функция создаёт два камня, направленных в разные стороны:
func _on_rock_broken(rock):
spawn_rock.call_deferred(rock.position, rock.velocity.rotated(0.8) * 1.5)
spawn_rock.call_deferred(rock.position, rock.velocity.rotated(-0.8) * 1.5)Сигнал поступает, пока Godot проверяет, какие области соприкасаются. Добавление области в этот момент останавливает игру с сообщением Can't change this state while flushing queries. call_deferred выполняет вызов в конце кадра, когда это безопасно.
Пока что раскалывается каждый камень, поэтому они никогда не заканчиваются. Дальше займёмся размерами.
Задание
СложноСделай так, чтобы камни, поражённые выстрелом, раскалывались надвое.
- В
rock.gdдобавьsignal broken(rock)и вызывайbroken.emit(self), когда пуля попадает в камень, передqueue_free(). - В
main.gdподключи сигналbrokenкаждого камня к_on_rock_brokenвspawn_rock. - В
_on_rock_broken(rock)создай два камня, как показано, используяcall_deferred.
Нажми «Играть» и выстрели в камень: два камня разлетятся в стороны. Затем нажми «Проверить».
Попробуйте сами
extends Node2D
const ROCK = preload("res://rock.tscn")
func _ready():
for i in 4:
spawn_rock(Vector2(randf_range(0, 640), 0), Vector2(randf_range(-90, 90), randf_range(40, 90)))
func spawn_rock(where, velocity):
var rock = ROCK.instantiate()
rock.position = where
rock.velocity = velocity
add_child(rock)
Все уроки раздела Проекты
Потренируйтесь самостоятельно: Песочница Godot