Menu
CoddyTech

Разбиваем астероиды

Часть раздела Проекты путешествия по 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 выполняет вызов в конце кадра, когда это безопасно.

Пока что раскалывается каждый камень, поэтому они никогда не заканчиваются. Дальше займёмся размерами.

challenge icon

Задание

Сложно

Сделай так, чтобы камни, поражённые выстрелом, раскалывались надвое.

  1. В rock.gd добавь signal broken(rock) и вызывай broken.emit(self), когда пуля попадает в камень, перед queue_free().
  2. В main.gd подключи сигнал broken каждого камня к _on_rock_broken в spawn_rock.
  3. В _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