DevGang
Авторизоваться

Rust против C ++ для разработки игр 

Rust здесь не для замены C ++, хотя они синтаксически похожи. В качестве основной функции Rust обеспечивает безопасность памяти, поэтому он действительно нравится тем, кто любит Rust. Rust также универсален: его можно использовать для веб-разработки, разработки игр, файловых систем, операционных систем и многого другого.

C ++ - это объектно-ориентированный язык программирования, который можно использовать для разработки игр, операционных систем, веб-браузеров, облачных / распределенных систем и т. д. Он особенно популярен для разработки игр из-за его высокой производительности, сильной абстракции и доступности библиотек и инструментов.

В этом руководстве мы сравним Rust и C ++ в контексте разработки игр. Мы рассмотрим сходства и различия между Rust и C, а также плюсы и минусы использования каждого языка программирования для разработки игр. Мы также познакомим вас с некоторыми инструментами для разработки игр на Rust и C ++.

Почему C ++ популярен для разработки игр

C ++ уже довольно давно используется в индустрии разработки игр. Многие разработчики игр предпочитают дополнять его другими языками семейства C или даже языками ассемблера.

C ++ делает ставку на высокую производительность и сильную абстракцию. Разработчики также выбирают C ++ из-за его функции наследования и других функций, предоставляемых его объектно-ориентированной моделью. Любой, кто какое-то время работает в игровой индустрии, может подтвердить широкую доступность инструментов для создания игр на C ++. Для разработчиков, которым нужно уложиться в срок или которые являются новичками в игровой индустрии, C ++ всегда подходит из-за широкой доступности инструментов и ресурсов.

Игровые движки для разработчиков на C ++

Поскольку C ++ долгое время был основным продуктом сообщества разработчиков игр, существует множество игровых движков, созданных на C ++. Давайте сравним некоторые из самых популярных инструментов для разработчиков игр на C ++.

Blender

Blender - это бесплатное программное обеспечение с открытым исходным кодом (FOSS) для 3D-производства. Он полностью построен на C ++ и предлагает поддержку OpenAL 3D-звука и сценариев Python. Учитывая, что это кроссплатформенный блендер, он поддерживает большинство основных операционных систем. Разработка игр - это не все, для чего подходит Blender; вы также можете создавать короткометражные фильмы и другие кинематографические элементы.

Unity

Unity - это кроссплатформенный игровой движок, который позволяет создавать игры в 2D, 3D и виртуальной реальности. Хотя Unity в основном создавался как эксклюзивный игровой движок для MAC OS X, с тех пор Unity был принят во многих кинематографических, инженерных и строительных приложениях.

Panda3D

Некоторые игровые движки требуют использовать внешние библиотеки для обнаружения столкновений, I / O, аудио, и т.д. Panda3D предлагает все это и многое другое в одном пакете. Этот игровой движок, написанный на C ++, позволяет писать игры на Python, хотя есть обходной путь для написания игр на C ++.

Godot

Godot - это кроссплатформенный игровой движок с открытым исходным кодом, наполненный инструментами, которые позволяют вам сосредоточиться на разработке игры. Этот игровой движок построен на C ++ и довольно популярен для разработки игр на C ++ из-за поддерживаемой гибкости.

Инструменты C ++ для разработки игр

В отличие от Rust, большинство игровых движков на C ++ содержат все инструменты, необходимые для разработки игр.

При создании игр на C ++ важно тщательно продумать, какой движок лучше всего подходит для вашего проекта. Также важно понимать общую концепцию объектно-ориентированного программирования, поскольку вы будете иметь дело с объектно-ориентированной моделью.

Rust в разработке игр: мы уже играем?

Чтобы оценить, что предлагает Rust и почему это полезный язык для разработки игр, давайте немного прокатимся на поезде истории, чтобы понять, почему он вообще был создан.

Rust начинался как побочный проект одного из сотрудников Mozilla, Грейдона Хоара, который устранил большинство уязвимостей в C ++. Со временем пользователи Mozilla разочаровались в утечках памяти и других уязвимостях C ++, который является основным языком его веб-браузера Firefox.

Вот почему Грейдон Хоар предлагает Rust, язык, над которым он работал с 2006 года. Только в 2010 году Mozilla начала поддерживать Rust после того, как он продемонстрировал большие успехи в обеспечении безопасности памяти.

Зачем использовать Rust для разработки игр?

Зачем кому-то нужно использовать новый язык для разработки игр вместо семейства C, которое существует уже много лет? Это потому, что безопасные для памяти языки, такие как Rust, устраняют многие ошибки, с которыми ваши пользователи могут столкнуться при использовании вашего продукта. Безопасные для памяти языки не позволяют запускать код с утечками памяти. Для обеспечения безопасности памяти Rust использует модель, ориентированную на данные. Он обрабатывает игровые элементы как данные, а не как объекты, как в объектно-ориентированном программировании.

Объектно-ориентированное и ориентированное на данные программирование

При разработке игр есть некоторые проблемы с объектно-ориентированным программированием, особенно с одной из основных функций объектно-ориентированного программирования - инкапсуляцией. Инкапсуляция помогает разработчикам скрывать данные для поддержания безопасной среды. Однако в разработке игр эта функция - это ножное ружье, потому что она противоречит той самой цели, для которой была создана.

Например, вам нужно следовать наследованию, чтобы иметь доступ к данным, потому что вы не можете сделать их общедоступными из-за инкапсуляции. Следовательно, для каждой новой функции, добавленной в игру, вам может потребоваться доступ к данным из другого поля, которое может быть инкапсулировано, чтобы они могли унаследовать эту функцию.

Чтобы понять обратную сторону инкапсуляции / наследования, связанной с ООП при разработке игр, давайте посмотрим на этот быстрый пример из заключительного выступления Кэтрин Уэст на RustConf 2018:

typedef uint32_t EntityId;

// Declare World to pass it to Entity
struct World;

struct InputState { ... };
struct RenderState { ... };

// Pure virtual interface!
class Entity {
public:
    virtual Vec2F position() const = 0;
    void update(World* world) = 0;
    void input(InputState const& input_state) = 0;
    void render(RenderState& render_state) = 0;

private:
};

class Player : Entity {
public:
    Vec2F position() const override;

    void input(InputState const& input_state) override;
    void update(World* world) override;
    void render(RenderState& render_state) override;

private:
    Physics m_physics;
    HumanoidState m_humanoid;

    ...
};

class Monster : Entity {
public:
    Vec2F position() const override;

    void input(InputState const& input_state) override;
    void update(World* world) override;
    void render(RenderState& render_state) override;

private:
    Physics m_physics;

    ...
};

class NPC : Entity {
public:
    Vec2F position() const override;

    void input(InputState const& input_state) override;
    void update(World* world) override;
    void render(RenderState& render_state) override;

private:
    Physics m_physics;
    HumanoidState m_humanoid;

    ...
};

struct WorldTile { ... };

struct World {
    List<EntityId> player_ids;
    HashMap<EntityId, shared_ptr<Entity>> entities;

    MultiArray2D<WorldTile> tiles;

    ...
};

По мере роста вашего проекта многие отношения дочерних, родительских и предков в вашем приложении станут слишком сложными для обработки и могут создать лазейку в вашем проекте. Например, если наша игра получит новую функцию в будущем выпуске, нам нужно будет применить наследование.

Скажем, например, нам нужен монстр, чтобы отслеживать игроков с плохим здоровьем. Для этого мы должны создать публичный аксессор для здоровья игрока, потому что он приватный:

class Monster : Entity {
public:
    Vec2F position() const override;

    void input(InputState const& input_state) override;
    void update(World* world) override;
    void render(RenderState& render_state) override;

    DamageRegion const& damage_region() const;

private:
    ...
};

Если мы хотим добавить больше функций для частных состояний, нам нужно создать больше аксессуаров. Поступая таким образом, мы продолжим проделывать дыры в нашем приложении, пока оно не станет небезопасным и им нельзя будет управлять.

Поскольку в Rust используется подход, ориентированный на данные, игровые элементы обрабатываются как данные. Rust использует паттерн Entity Component System (ECS) при разработке игр, где объект состоит из различных компонентов, прикрепленных к нему, компонент состоит из блоков данных (данные для разработки игры), а система управляет логикой приложения. Например, если мы хотим воспроизвести тот же пример из C ++ в Rust, мы будем использовать подход ECS с сущностями и компонентами как структурами.

type EntityIndex = usize;

struct Physics {
    position: Vector2<f32>,
    velocity: Vector2<f32>,
    mass: f32,
}

struct HumanoidAnimationState { ... }
struct HumanoidItem { ... }

struct HumanoidState {
    animation_state: HumanoidAnimationState,
    left_hand_item: HumanoidItem,
    right_hand_item: HumanoidItem,
    aim_position: Vector2<f32>,
}

struct Player {
    physics: Physics,
    humanoid: HumanoidState,

    health: f32,
    focused_entity: EntityIndex,
    food_level: f32,
    admin: bool,

    ...
}

enum MonsterAnimationState { ... }
struct DamageRegion { ... }

struct Monster {
    physics: Physics,
    animation_state: MonsterAnimationState,

    health: f32,
    current_target: EntityIndex,
    damage_region: DamageRegion,

    ...
}

struct NpcBehavior { ... }

struct Npc {
    physics: Physics,
    humanoid: HumanoidState,

    health: f32,
    behavior: NpcBehavior,

    ...
}

enum Entity {
    Player(Player),
    Monster(Monster),
    Npc(Npc),
}

struct Assets { ... }

struct GameState {
    assets: Assets,

    entities: Vec<Option<Entity>>,
    players: Vec<EntityIndex>,

    ...
}

fn main() {
    let mut game_state = initial_game_state();

    loop {
        let input_state = capture_input_state();

        player_control_system(&mut game_state, &input_state);
        npc_behavior_system(&mut game_state);
        monster_behavior_system(&mut game_state);

        physics_system(&mut game_state);

        // ... lots more systems

        render_system(&mut game);
        audio_system(&mut game);

        wait_vsync();
    }
}

В структуры можно легко добавить новые функции. Чтобы избежать повторения, вы можете использовать ключевое слово impl. При таком подходе легко извлекать или передавать данные функции безопасно без наследования, потому что компоненты могут вызываться всякий раз, когда они требуются.

Игровые движки для разработчиков на Rust

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

Amethyst

Amethyst ориентирован на данные, быстр и прост в настройке. Он имеет массивно-параллельную архитектуру, использует модель ECS и позволяет быстро создавать прототипы с помощью файлов RON.

Amethyst позволяет разработчикам, которые плохо знакомы с разработкой игр, сразу же взяться за дело. Движок игры предлагает примеры, которые помогут вам легко познакомиться. Чтобы запустить любой из примеров, выполните команду ниже в интерфейсе командной строки по вашему выбору:

cargo run --example name_of_example

Caper

Caper поддерживает другие системы, включая аудио, рендеринг, ввод и обнаружение столкновений. Это не кроссплатформенный игровой движок и поддерживает только ОС Linux. Как и Amethyst, Caper предоставляет несколько примеров, которые помогут вам сориентироваться в игровом движке. Вы можете протестировать эти примеры, выполнив приведенную ниже команду в интерфейсе командной строки.

cargo run --example transforms

Chariot

Chariot - это повторная реализация игры Age of Empires, выпущенной Microsoft, в которой используется движок Genie Engine. Chariot - это игровой движок с открытым исходным кодом, который можно портировать на любую желаемую платформу. Цель этого игрового движка - создавать игры, подобные вышеупомянутому.

Console

Если вам нужен движок, который предоставляет инструменты для обработки пользовательского ввода, Console - ваш лучший выбор. С помощью механизма консоли вы даже можете легко создавать автономные экраны, если вам не нужны терминал, мышь или клавиатура.

Oxygengine

Oxygengine - это движок веб-игр, написанный на Rust с помощью web-sys. Это игровой движок HTML5 и WebAssembly, основанный на крейте Specs, используемом для его среды ECS.

Другие примечательные игровые движки, написанные в Русте включают bevycoffeecorangedoryendotrixmuoxirusty_engineturbine, и многое другое.

Инструменты Rust для разработки игр

Как мы упоминали ранее, инструменты играют важную роль в разработке игр. В этом разделе, как и в случае с C ++, мы подробно рассмотрим некоторые инструменты Rust для разработки игр.

2D рендеринг

Рендеринг - важная часть создания игры, потому что дает пользователям вашего продукта увлекательный пользовательский интерфейс с двухмерными фотореалистичными изображениями. Некоторые из лучших инструментов 2D-рендеринга для разработки игр на Rust включают:

  1. beryllium
  2. blit
  3. crow
  4. fermium
  5. image

3D рендеринг

Хотя 2D-рендеринг предлагает двухмерные фотореалистичные изображения, как вы, наверное, догадались, 3D-рендеринг делает вашу игровую среду еще более реалистичной с трехмерными изображениями. Ниже приведены некоторые из наиболее полезных инструментов 3D-рендеринга для разработчиков игр на Rust:

  1. ash
  2. gfx
  3. gl
  4. glow
  5. glutin

Искусственный интеллект (ИИ)

Библиотеки AI позволяют использовать алгоритмы для реализации прогнозируемого поведения в вашей игре. Например, есть библиотеки AI с готовыми шахматными алгоритмами, которые вы можете использовать для создания такой игры в Rust. Яркие примеры библиотек Rust AI для разработки игр:

  1. chess_ai
  2. pathfinding
  3. navmesh
  4. steering
  5. big_brain

Библиотеки анимации

Большинство игр требуют движения. Библиотеки анимации в Rust позволяют управлять изображениями так, как будто они движутся. Поскольку большинство библиотек Rust создается членами сообщества, а Rust - относительно новый язык на сцене, Pareen - единственный широко используемый ящик для анимации для разработки игр на Rust на момент написания.

Pareen позволяет создавать анимацию, параметризованную по времени, без необходимости передавать временные переменные. Это полезно для создания плавных переходов между несколькими игровыми состояниями.

Аудио оболочки

В разработке игр звук так же важен, как и движение. Например, экшн-игра выглядела бы незавершенной и скучной без реалистичных грохотов, сбоев и других шумов, связанных с обломками и разрушением.

Следующий список звуковых оберток Rust - отличное место для начала, если вы хотите реализовать звук в вашей игре на Rust:

  1. hound
  2. kira
  3. oddio
  4. rodio
  5. portmidi

Входные библиотеки

Для игр, в которых используются планшеты и другие устройства ввода, вам понадобится ящик для работы с контроллерами в устройствах ввода. В Rust есть две библиотеки ввода:

  1. gilrs
  2. sdl2

Сетевые инструменты

Игры становятся намного веселее, когда вы играете в них с друзьями. Экосистема Rust включает ряд сетевых инструментов, которые помогают наладить сотрудничество между разработчиками и упростить многопользовательские функции в играх на Rust, в том числе:

  1. naia
  2. laminar
  3. message-io
  4. enet
  5. quinn

Библиотеки обнаружения столкновений

В определенных типах игр пользователь терпит неудачу или зарабатывает очки, когда сталкивается с чем-либо. Библиотеки обнаружения столкновений делают именно то, что следует из названия: обнаруживают столкновения в вашей игре.

Полезные библиотеки обнаружения столкновений для разработчиков игр на Rust:

  1. physme
  2. physx
  3. rapier
  4. salva
  5. mgf

Библиотеки пользовательского интерфейса

Пользовательский интерфейс - это первое, что игрок видит и судит о вашей игре еще до того, как вступит в нее и испытает ее. Первые впечатления - это все в разработке игры, и плохой пользовательский интерфейс часто отключает игроков еще до того, как они начнут взаимодействовать с вашей игрой.

Вот некоторые библиотеки пользовательского интерфейса для разработки игр на Rust:

  1. egui
  2. fungui
  3. imgui
  4. iced
  5. vitral

Движки VR

В 2021 году некоторые сегменты сообщества разработчиков игр будут стремиться к виртуальной реальности, создавая потрясающе реалистичные визуальные ландшафты, которые окружают и погружают игроков, как никогда раньше.

Ниже приведены некоторые из лучших движков виртуальной реальности, которые Rust может предложить:

  1. openvr
  2. openxr
  3. rovr
  4. libovr

Где Rust терпит неудачу

При создании игр на Rust важно понимать, что большинство инструментов и движков Rust все еще находятся в стадии разработки. И, повторюсь, подход Rust к разработке игр ориентирован на данные. Поэтому, если вы пришли из объектно-ориентированного фона, такого как C ++, вам следует потратить некоторое время на ознакомление с моделью, ориентированной на данные, прежде чем начинать разработку игр на Rust.

Чтобы узнать больше о проблемах, которые ставит объектно-ориентированное программирование при разработке игр, ознакомьтесь с заключительным докладом Кэтрин Уэст с RustConf 2018.

C ++ против Rust: что лучше всего подходит для вашего проекта по разработке игр?

По моему скромному мнению, идеального языка программирования или даже языка программирования по сути не существует. Выбор лучшего языка, фреймворка, библиотеки или инструмента для любой работы зависит от вашего уровня комфорта при их использовании, а также от уникальных требований и целей вашего проекта.

Доступность инструментов и поддержка также являются главными соображениями для разработчиков игр. Поэтому, если вы создаете игру, в которой безопасность памяти является приоритетом, Rust, вероятно, будет вашим лучшим выбором. На Discord и в других местах есть поддержка сообщества и каналы связи. Вы можете быть в курсе последних событий и отслеживать готовность Rust к разработке игр, посетив Are We Game Again?

С другой стороны, C ++ - отличный выбор для проектов разработки игр, не требующих защиты памяти. Экосистема C ++ включает в себя более широкий спектр проверенных временем инструментов, которые существуют уже много лет и пользуются доверием сообщества разработчиков игр. C ++ - особенно хороший выбор для вашего проекта, если вам удобнее использовать объектно-ориентированное программирование, чем использование языков, ориентированных на данные, таких как Rust.

Заключение

В этом руководстве мы изучили основы разработки игр на C ++ и языке программирования Rust. Мы сравнили опыт разработчиков с использованием Rust и C ++ для создания игр; перечислены наиболее полезные и широко используемые инструменты для реализации анимации, звуков, обнаружения столкновений, многопользовательских функций и многого другого; и определили несколько простых параметров для определения того, какой язык лучше всего подходит для вашего проекта разработки игр

Источник:

Комментарии
Чтобы оставить комментарий, необходимо авторизоваться