Створення ворога¶
Тепер настав час зробити ворогів, від яких гравцеві доведеться ухилятися. Їх поведінка буде не дуже складною: вони будуть час від часу виникати по краях екрана і рухатися у випадковому напрямку по прямій лінії.
Ми створимо сцену Mob
, яку ми зможемо потім використати, для створення будь-якої кількості незалежних мобів в грі.
Налаштування вузлів¶
Клацніть Сцена -> Нова сцена та додайте наступні вузли:
RigidBody2D (тверде тіло 2D) (названий
Mob
):ref:`AnimatedSprite <class_AnimatedSprite>`(Анімація спрайту)
:ref:`CollisionShape2D <class_CollisionShape2D>`(Форма зіткнення 2D)
VisibilityNotifier2D (Видимість)
Не забудьте налаштувати нащадків, щоб вони не могли бути обрані, як ви робили це зі сценою гравця.
У властивостях RigidBody2D встановіть значення Gravity Scale
(сила гравітації) на 0
, щоб моб не падав вниз. Крім того, в розділі CollisionObject2D натисніть властивість Mask
і зніміть галочку у першому полі. Завдяки цьому моби не будуть стикатися один з одним.

Налаштуйте AnimatedSprite так, як ви налаштовували його для гравця. На цей раз, у нас є 3 анімації: fly
(літати), swim
(плавати), і walk
(ходити). В папці art є по два зображення для кожної анімації.
Встановіть "Speed (FPS)" на 3
для всіх анімацій.

Встановіть властивість Playing
в Інспекторі на "On".
Ми вибиратимемо одну з цих анімації випадковим чином, тому моби будуть мати певну різноманітність.
Як і зображення гравця, ці зображення мобів потрібно зменшити. Встановіть в AnimatedSprite
властивість Scale
на (0.75, 0.75)
.
Як і в сцені Player
, додайте CapsuleShape2D
для зіткнення. Щоб вирівняти фігуру із зображенням, потрібно встановити властивість Rotation Degrees
(градус поворота) на 90
(під "Transform" в Інспекторі).
Збережіть сцену.
Скрипт ворога¶
Додайте такий скрипт до Mob
:
extends RigidBody2D
public class Mob : RigidBody2D
{
// Don't forget to rebuild the project.
}
// Copy `player.gdns` to `mob.gdns` and replace `Player` with `Mob`.
// Attach the `mob.gdns` file to the Mob node.
// Create two files `mob.cpp` and `mob.hpp` next to `entry.cpp` in `src`.
// This code goes in `mob.hpp`. We also define the methods we'll be using here.
#ifndef MOB_H
#define MOB_H
#include <AnimatedSprite.hpp>
#include <Godot.hpp>
#include <RigidBody2D.hpp>
class Mob : public godot::RigidBody2D {
GODOT_CLASS(Mob, godot::RigidBody2D)
godot::AnimatedSprite *_animated_sprite;
public:
void _init() {}
void _ready();
void _on_VisibilityNotifier2D_screen_exited();
static void _register_methods();
};
#endif // MOB_H
Тепер давайте розглянемо решту скрипту. В _ready()
ми відтворюємо анімацію і випадковим чином вибираємо один з трьох її варіантів:
func _ready():
$AnimatedSprite.playing = true
var mob_types = $AnimatedSprite.frames.get_animation_names()
$AnimatedSprite.animation = mob_types[randi() % mob_types.size()]
public override void _Ready()
{
var animSprite = GetNode<AnimatedSprite>("AnimatedSprite");
animSprite.Playing = true;
string[] mobTypes = animSprite.Frames.GetAnimationNames();
animSprite.Animation = mobTypes[GD.Randi() % mobTypes.Length];
}
// This code goes in `mob.cpp`.
#include "mob.hpp"
#include <RandomNumberGenerator.hpp>
#include <SpriteFrames.hpp>
void Mob::_ready() {
godot::Ref<godot::RandomNumberGenerator> random = godot::RandomNumberGenerator::_new();
random->randomize();
_animated_sprite = get_node<godot::AnimatedSprite>("AnimatedSprite");
_animated_sprite->_set_playing(true);
godot::PoolStringArray mob_types = _animated_sprite->get_sprite_frames()->get_animation_names();
_animated_sprite->set_animation(mob_types[random->randi() % mob_types.size()]);
}
Спочатку ми отримуємо список назв анімацій з властивості AnimatedSprite frames
. Вона повертає масив, який містить всі три назви анімацій: ["walk", "swim", "fly"]
.
Далі нам потрібно вибрати випадкове число між 0
та 2
, щоб вибрати назву однієї з цих анімацій (массив індексується з 0
). randi() % n
вибирає випадкове ціле число між 0
та n-1
.
Примітка
Ви повинні використовувати, randomize()
якщо хочете, щоб ваша послідовність "випадкових" чисел була щоразу різною, коли ви запускаєте сцену. Ми будемо використовувати randomize()
в нашій Main
сцені, тому тут це не потрібно.
Останній фрагмент - це змусити мобів видаляти себе, коли вони залишають екран. Підключіть сигнал screen_exited()
вузла VisibilityNotifier2D
і додайте цей код:
func _on_VisibilityNotifier2D_screen_exited():
queue_free()
public void OnVisibilityNotifier2DScreenExited()
{
QueueFree();
}
// This code goes in `mob.cpp`.
void Mob::_on_VisibilityNotifier2D_screen_exited() {
queue_free();
}
На цьому завершуємо сцену Mob
.
З гравцем і ворогами закінчено, в наступній частині ми об'єднаємо їх у новій сцені. Ми змусимо ворогів випадковим чином виникати навколо ігрової дошки і рухатися вперед, перетворюючи наш проект в гру.