lesson_02_gdscript/project/ в Godotscenes/main.tscn — игровое поле с MovableObject (Sprite2D с текстурой circle.svg)scenes/draggable_piece.tscn — объект для перетаскивания (Sprite2D с текстурой star.svg)scripts/ — скелеты с TODO-комментариямиsprites/ — SVG-спрайты (circle.svg, square.svg, star.svg)Примечание: Текстуры уже назначены на Sprite2D в сценах. Godot автоматически импортирует SVG-файлы как текстуры.
Цель: научиться обрабатывать ввод и перемещать узлы.
scripts/movable_object.gdextends Sprite2D
@export var speed: float = 200.0
func _process(delta: float) -> void:
# TODO 1: Создайте переменную direction типа Vector2, равную Vector2.ZERO
# TODO 2: Если нажата "ui_right", увеличьте direction.x на 1
# TODO 3: Если нажата "ui_left", уменьшите direction.x на 1
# TODO 4: Если нажата "ui_up", уменьшите direction.y на 1 (ось Y перевёрнута!)
# TODO 5: Если нажата "ui_down", увеличьте direction.y на 1
# TODO 6: Нормализуйте direction и прибавьте к position (с учётом speed и delta)
pass
Объект перемещается стрелками клавиатуры с одинаковой скоростью в любом направлении.
Цель: реализовать перетаскивание объекта — ключевая механика для головоломок.
scripts/draggable_piece.gdsignal piece_placed(piece_position: Vector2) — это для бонусного задания, пока его можно игнорировать.extends Sprite2D
var dragging: bool = false
var drag_offset: Vector2 = Vector2.ZERO
func _input(event: InputEvent) -> void:
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT:
if event.pressed:
# TODO 1: Проверить, находится ли мышь над спрайтом
# Подсказка: используйте функцию _is_mouse_over()
# Если да — установите dragging = true и вычислите drag_offset
pass
else:
# TODO 2: Отпустили кнопку — прекратить перетаскивание
pass
# TODO 3: Если event — это InputEventMouseMotion И dragging == true,
# обновите global_position = event.position + drag_offset
pass
# Проверяет, находится ли мышь над текстурой спрайта
func _is_mouse_over() -> bool:
var mouse_pos := get_global_mouse_position()
if texture == null:
return false
var size := texture.get_size() * scale
var rect := Rect2(global_position - size / 2, size)
return rect.has_point(mouse_pos)
Объект можно схватить мышью и перетащить в любое место.
Цель: связать узлы через сигналы — кнопка запускает действие.
Откройте сцену scenes/main.tscn
В сцене уже есть:
SpawnButton (Button) — кнопка «Создать объект»ResetButton (Button) — кнопка «Сброс»SpawnArea (Node2D) — область, где появляются объектыCounter (Label) — счётчик созданных объектовОткройте скрипт scripts/main.gd и реализуйте:
extends Node2D
# Сцена объекта, который будем создавать
@export var piece_scene: PackedScene
var spawn_count: int = 0
func _ready() -> void:
# TODO 1: Подключите сигнал pressed кнопки $SpawnButton к функции _on_spawn_pressed
# Пример: $SpawnButton.pressed.connect(_on_spawn_pressed)
# TODO 2: Подключите сигнал pressed кнопки $ResetButton к функции _on_reset_pressed
# TODO 9 (задание 4): Настройте автоспаун
# $AutoSpawnTimer.wait_time = 3.0
# $AutoSpawnTimer.timeout.connect(_on_auto_spawn_timer)
pass
func _on_spawn_pressed() -> void:
if piece_scene == null:
print("Ошибка: piece_scene не назначена! Перетащите сцену в инспекторе.")
return
# TODO 3: Создайте экземпляр piece_scene (piece_scene.instantiate())
# TODO 4: Установите его позицию (случайная внутри SpawnArea)
# Подсказка: Vector2(randf_range(100, 900), randf_range(100, 500))
# TODO 5: Добавьте экземпляр как дочерний узел к $SpawnArea
# TODO 6: Увеличьте spawn_count и обновите текст $Counter
pass
func _on_reset_pressed() -> void:
# TODO 7: Удалите все дочерние узлы из $SpawnArea
# Подсказка: for child in $SpawnArea.get_children(): child.queue_free()
# TODO 8: Обнулите spawn_count и обновите $Counter
pass
func _on_auto_spawn_timer() -> void:
# TODO 10 (задание 4): Вызвать _on_spawn_pressed() для автоматического создания
# _on_spawn_pressed()
pass
piece_scene — перетащите scenes/draggable_piece.tscn в поле.Цель: использовать Timer для периодических действий.
В сцене main.tscn уже есть узел AutoSpawnTimer (Timer). Проверьте его настройки в инспекторе:
3.0 (каждые 3 секунды)false (повторять)falseВ main.gd раскомментируйте TODO 9 (подключение таймера в _ready()) и TODO 10 (функция _on_auto_spawn_timer()).
Для запуска автоспауна добавьте в _ready() после TODO 9:
# $AutoSpawnTimer.start() # Запустить автоспаун сразу при старте
ToggleAutoButton в сценуpressed к функции, которая вызывает $AutoSpawnTimer.start() или $AutoSpawnTimer.stop()Объекты появляются автоматически каждые 3 секунды (когда таймер запущен).
В draggable_piece.gd объявите сигнал:
signal piece_placed(piece_position: Vector2)
Отправляйте его при отпускании мыши:
piece_placed.emit(global_position)
В main.gd при создании объекта подключитесь к этому сигналу:
var piece = piece_scene.instantiate()
piece.piece_placed.connect(_on_piece_placed)
Напишите обработчик, который выводит позицию:
func _on_piece_placed(pos: Vector2) -> void:
print("Объект размещён в: ", pos)