Сейчас я восстановлю структуру программы Годот Bullet Shower.

Сегодня мы немного поэкспериментируем с кодом. Никакой скучной теории — только блоки кода, примеры и практика.

Наша главная задача — создать небольшие независимые проекты, в которых мы поработаем с текстурами и загруженными объектами.

Создаём текстуру с независимыми объектами в Годот

Всё начинается просто: запускаем Godot и нажимаем кнопку 2D-сцена.

Давайте сразу дадим узлу понятное имя. Переименуйте её в Displayable.

Теперь выделяем наш узел Displayable, нажимаем на значок + и добавляем внутрь неё ещё одну узел Node2D

Переименуйте узел Node2D в textured.Нажмите Ctrl + S и сохраните сцену как displayable.tscn.

Добавьте новый скрипт к узлу Textured и назовите его textured.gd.

Добавляем в папку проекта картинку пули (bullet.png) и вставляем в код следующую строку.

const bullet_image := preload("res://bullet.png")

Добавим код, который загружает случайные координаты в список bullets.

Выберите корневой узел Node2D текущей сцены.

Добавим код, который кладёт новую пулю в список bullets.

На экране отображается только один экземпляр пули.

Добавим цикл, чтобы на экране появлялось больше пуль.

Добавление игрока

Чтобы игрок мог сталкиваться с пулями, выделите узел Displayable и нажмите +.

Переименуйте Area2D в player.

Рядом с узлом Area2D загорелся жёлтый символ. Так Godot подсказывает, что блоку чего-то не хватает.

Нажмём на кнопку + и добавим к нашему Player новый узел — CollisionShape2D. Именно он будет отвечать за столкновения.

Мы добавили CollisionShape2D, но он пока не работает — ему нужна форма. В инспекторе создаём для него CircleShape2D.Как только добавим форму, жёлтое предупреждение исчезнет. Теперь добавим к Player анимированный спрайт — так у игрока появится визуальный образ.

AnimatedSprite2D требует набор кадров для анимации.

Теперь создадим ресурс SpriteFrames — именно в нём будут храниться все кадры анимации. Кликаем по нему, и перед нами откроется редактор анимаций.

Перетаскиваем спрайты в кадры анимации.

Выделите player и добавьте к нему скрипт player.gd

Теперь выделяем нужный узел, создаём сигналы body_shape_entered и body_shape_exited, и привязываем их к player.

Теперь добавим логику: если игрок наткнулся на блок, его спрайт должен меняться.

Мы добавили спрайт, но он пока стоит на месте. Давайте научим его двигаться за мышкой.

Теперь добавим функцию _input() — именно она будет отвечать за обработку действий игрока.

Управление с мыши добавили, а спрайт всё равно не меняется при столкновении с пулей.

Теперь нужно добавить позицию в физический движок. Для этого в файле displayable пропишем следующий код.

Теперь смайлик меняет спрайт при касании блоков.

Примеры кода

Player.gd

extends Area2D
@onready var sprite:AnimatedSprite2D = $AnimatedSprite2D
func _ready() -> void:
pass

func _input(event: InputEvent) -> void:
    if event is InputEventMouseMotion:
          position =event.position

func _process(delta: float) -> void:
    pass

func _on_body_shape_entered(body_rid: RID, body: Node2D, body_shape_index: int, local_shape_index: int) -> void:
   sprite.frame=1

func _on_body_shape_exited(body_rid: RID, body: Node2D, body_shape_index: int, local_shape_index: int) -> void:
   sprite.frame=0;

 

Textured.gd

extends Node2D
const bullet_image := preload("res://bullet.png")
var bullets=[]
var MAX_COUNT=100
func _ready() -> void:
    var shape = PhysicsServer2D.circle_shape_create()
    PhysicsServer2D.shape_set_data(shape, 8)
    for i in range(MAX_COUNT):
          bullets.push_back([Vector2(randf_range(0,get_viewport_rect().size.x),
                randf_range(0,get_viewport_rect().size.y)),PhysicsServer2D.body_create()])
          PhysicsServer2D.body_set_space(bullets[i][1],get_world_2d().get_space())
          PhysicsServer2D.body_add_shape(bullets[i][1],shape)
          var transform2d := Transform2D()
          transform2d.origin=bullets[i][0]
          PhysicsServer2D.body_set_state(bullets[i][1],PhysicsServer2D.BODY_STATE_TRANSFORM,
               transform2d)

func _physics_process(delta: float) -> void:
    for bullet:Array in bullets:
          var transform2d := Transform2D()
          transform2d.origin=bullet[0]
          PhysicsServer2D.body_set_state(bullet[1],PhysicsServer2D.BODY_STATE_TRANSFORM,
                               transform2d)

func _process(delta: float) -> void:
   queue_redraw()

func _draw() -> void:
  for bullet: Array in bullets:
         draw_texture(bullet_image, bullet[0])

На этом эксперимент с программой Bullet Shower завершён. Мы разобрались, как работает физика в Godot, и выделили из этого упражнения главные блоки для понимания. Спасибо, что были со мной!

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх