Porting SDL C++ Game to HTML5 (Emscripten)

[Translation may be some day]

За последний год я написал простейший движок Flame Steel Engine и набор классов для игровой разработки Flame Steel Engine Game Toolkit. В данной статье я опишу как производил портирование движка и SDL игры Bad Robots на HTML 5, с использованием компилятора Emscripten.

Установка Hello World – Emscripten

Для начала нужно установить Emscripten. Простейшим вариантом оказалось использование скрипта emsdk для Linux. На официальном сайте данный тип установки называется как “Portable Emscripten SDK for Linux and OS X“. Внутри архива есть инструкция по установке с использованием скрипта. Я производил установку в директорию ~/emsdk/emsdk_portable.

После установки emscripten нужно проверить корректность работы компилятора, для этого создаем простейший hello_world.cpp и собираем его в hello_world.html с помощью команд:

source ~/emsdk/emsdk_portable/emsdk_env.sh
emcc hello_world.cpp -o hello_world.html

После компиляции в папке появится hello_world.html и вспомогательные файлы, откройте его в лучшем браузере Firefox, проверьте что все работает корректно.

Портирование кода игры

В javascript нежелательно вызывать бесконечный цикл – это приводит к зависанию браузера. На данный момент корректная стратегия – запрашивать один шаг цикла у браузера с помощью вызова window.requestAnimationFrame(callback)

В Emscripten данное обстоятельство решено с помощью вызова:

emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop);

Таким образом, нужно изменить код игры для корректного вызова метода emscripten. Для этого я сделал глобальный метод GLOBAL_fsegt_emscripten_gameLoop, в котором вызываю шаг цикла игрового контроллера. Главный игровой контроллер также вынесен в глобальную видимость:

#ifdef __EMSCRIPTEN__

void GLOBAL_fsegt_emscripten_gameLoop() {

GLOBAL_fsegt_emscripten_gameController->gameLoop();

}
#endif

Также для обработки специфических для Emscripten моментов, нужно использовать макрос __EMSCRIPTEN__.

Ресурсы и оптимизация

Emscripten поддерживает ресурсы и сборку с оптимизацией.

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

emcc <файлы для сборки> –use-preload-plugins –preload-file data

Флаг –use-preload-plugins включает красивый прелоадер в углу экрана, –preload-file добавляет указанный ресурс в файл <имя проекта>.data
Код постоянно останавливался с ошибками доступа к ресурсам, пока я не включил оба этих флага. Также стоит заметить что для корректного доступа к ресурсам, желательно запускать игру на https (возможно и http) сервере, или отключить защиту локального доступа к файлам в вашем браузере.

Для включения оптимизации добавьте флаги:

-s TOTAL_MEMORY=67108864 -O3 -ffast-math

TOTAL_MEMORY – оперативная память в байтах(?) необходимая для корректной работы игры. Вы можете использовать флаг для динамического выделения памяти, но тогда часть оптимизаций работать не будет.

Производительность

Код javascript из C++ работает гораздо медленнее, даже со включенными оптимизациями. Поэтому если ваша цель это разработка для HTML5, то приготовьтесь к ручной оптимизации алгоритмов игры, паралелльному тестированию, также к написанию javascript кода вручную в особо узких местах. Для написания javascript кода используется макрос EM_ASM. Во время реализации рейкастера на emscripten, мне удалось добиться повышения fps с 2-4 до 30 с помощью прямого использования методов canvas.drawImage, в обход обертки SDL->Canvas, что почти приравнялось к написанию всего на javascript.

Поддержка SDL

На данный момент почти не работает SDL_TTF, поэтому отрисовка шрифта для Game Score в BadRobots очень проста. SDL_Image, SDL_Mixer работают корректно, в mixer я проверил только проигрывание музыки.

Исходный код Flame Steel Engine, Flame Steel Engine Game Toolkit, игры Bad Robots:

https://github.com/demensdeum/BadRobots
https://github.com/demensdeum/FlameSteelEngine
https://github.com/demensdeum/FlameSteelEngineGameToolkit

Статья на эту тему:

https://hacks.mozilla.org/2012/04/porting-me-my-shadow-to-the-web-c-to-javascriptcanvas-via-emscripten/

ECSの希釈


Commission: Mad Scientist by Culpeo-Fox on DeviantArt

この記事では、ECS パターンと Flame Steel Engine ゲーム ツールキットでの実装について大まかに説明します。 Entity Component System パターンは、ゲームなどで使用されます。 Unityエンジン上で。ゲーム内の各オブジェクトはコンポーネントで満たされたエッセンスです。  OOP があるのになぜこれが必要なのでしょうか?
次に、ゲームの実行中にオブジェクトのプロパティ、動作、表示を直接変更します。このようなことは現実世界のアプリケーションでは見られません。パラメータ、オブジェクトのプロパティ、表示、サウンドの変化のダイナミクスは、会計ソフトウェアよりもゲームの特徴です。


バナナを渡さなかった

ゲームにバナナ クラスがあるとします。そしてゲームデザイナーはバナナを武器として使用したいと考えていました。現在のアーキテクチャでは、バナナは武器とは何の関係もないとしましょう。バナナを武器にする?全てのアイテムを武器に
しますか?ECS は、この差し迫った問題に対する解決策を提供します。ゲーム内のすべてのオブジェクトはコンポーネントで構成されている必要があります。以前はバナナは Banana クラスでしたが、今後はこれを作成し、他のすべてのオブジェクトを Entity クラスにして、それらにコンポーネントを追加します。バナナが次のコンポーネントで構成されているとします。

<オル>

  • 位置コンポーネント (ゲーム世界の座標 – x、y、z)
  • 回転コンポーネント (x、y、z 座標)
  • バナナのカロリー成分 (主人公は太りすぎないように注意してください)
  • バナナ画像コンポーネント
  • 現在、すべてのバナナに新しいコンポーネントを追加しています。これは、バナナが武器として使用できることを示すフラグです –武器のコンポーネント。ここで、ゲーム システムは、プレイヤーがバナナに近づいたことを認識すると、バナナに武器コンポーネントの存在を確認し、存在する場合は、プレイヤーにバナナを武装させます。
    私のゲーム「Flame Steel Call Of The Death Mask」では、ECS パターンが全体的に使用されています。オブジェクトはコンポーネントで構成されており、コンポーネント自体にコンポーネントを含めることができます。一般に、オブジェクトの分割 < – >私の実装ではコンポーネントが欠落していますが、これはさらにプラスです。

    screenshot_2016-09-24_14-33-43

    このスクリーンショットのショットガンはプレーヤーのコンポーネントであると同時に、2 番目のショットガンは通常のオブジェクトとしてゲーム マップ上にぶら下がっているだけです。
    このスクリーンショットでは、2 つのシステムが実行されています –シーンレンダラーとインターフェイスレンダラー。シーン レンダラーはマップ上でショットガン画像コンポーネントを操作し、インターフェイス レンダラーはプレイヤーの手の中でショットガン画像コンポーネントを操作します。

    関連リンク:
    https://habrahabr.ru/post/197920/
    https://www.youtube.com/watch?v=NTWSeQtHZ9M

    Flame Steel Engine ゲーム ツールキットのアーキテクチャ

    今日は、ゲーム開発用のツールキットであるFlame Steel Engine ゲーム ツールキットのアーキテクチャについて説明します。
    Flame Steel Engine ゲーム ツールキットを使用すると、Flame Steel Engine に基づいたゲームを作成できます。
    flamesteelgametoolkitschematics

    Flame Steel Engine のすべてのクラスは、接頭辞 FSE (Flame Steel ) で始まります。 >Engine)、FSEGTFlameSteelEngineG)強いアメTookit) ツールキット用。
    ゲーム シーン、オブジェクト、ボタンはすべて FSEObject のサブクラスであり、FSEGTGameData クラス内に置く必要があります。各FSEObject はFSESerialize インターフェイスを実装する必要があります。これにより、ゲーム データの保存/ロードが可能になり、保存メカニズムが提供されます。
    FSEController クラスは、FSEObject クラスのオブジェクトを操作します。ツールキットには、基本ゲーム シーン コントローラー クラスがあります。 FSEGTGameSceneController では、このクラスを継承してゲーム ロジックを実装できます。
    IOSystemFSEGTIOSystem インターフェイスのオブジェクトであり、このインターフェイスには FSEGTRendererFSEGTInputControllerFSEGTUIRendererFSEGTIOSystem はレンダラーを実装し、キーボード、ジョイスティック (入力デバイス) からデータを受信し、アクセス可能な インターフェイス要素のレンダリングを提供する必要があります。 href=”https://ru.wikipedia.org/wiki/%D0%92%D0%B2%D0%BE%D0%B4-%D0%B2%D1%8B%D0%B2%D0%BE%D0このプラットフォームの %B4″>入出力システム
    現時点では、SDL ライブラリに基づいたキーボード コントローラであるレンダラーが実装されており、 >FSEGTIOSDL システムクラス。

    Flame Steel Engine Raycaster Demo
    Flame Steel Engine Raycaster Demo

    将来的には、OpenGL に基づいて IOSystem を作成する予定です。クラスは FSEGTIOGLSystem と呼ばれます。 。任意のプラットフォームに基づいて IOSystem を作成する場合は、FSEGTIOSystem インターフェイスを使用し、そのための FSEGTRenderer レンダラ、FSEGTInputController を実装する必要があります。プラットフォーム 。

    Flame Steel Engine、ツールキット、ゲームのソース コード:
    https://github.com/demensdeum/FlameSteelCallOfTheDeathMask

    Unity、Wasteland 2 が私の Ubuntu で動作しないのはなぜですか?

    私は、Wasteland 2 ゲームの支援者であることを誇りに思います。今日、Ubuntu で起動しようと思ったのですが、できませんでした。しかし、1時間グーグルで調べた後、すべてがうまくいきました。 Unity には Linux に関していくつかの深刻な問題があることが判明しましたが、特定の松葉杖を使用することでゲームを起動できるようになります。

    ulimit -Sn 65536~/.local/share/Steam/steamapps/common/Wasteland\ 2\ Director\'s\ Cut/Linux/WL2

    レシピはこちらから:
    https://forums.inxile-entertainment.com/viewtopic.php?t=15505

    16 ビットのサンタのヘルパー

    電子メールでメッセージを受け取りました。
    “こんにちは、ここでレトロ ゲーム ジャムを開催します– bibitjam3!!! 8 ~ 16 ビットのレトロなプラットフォームでゲームを作成する必要があります!!!”
    ああ!これは私の子供の頃の夢です–セガ メガドライブ 2 用のゲームを作成してください。
    さて、おもちゃを作ってみましたが、成功することもありました。
    rqr
    私はそのゲームを「Red Queen’s Knead」と名付けました。ストーリーは–です。 “赤の女王は危険な迷宮に投げ込まれ、今度は自由へ向かう途中で全員を殺すつもりです。”
    歩き回ったり、赤い目の緑色のものを攻撃したり、宝箱を開けたり、シーンからシーンに移動したりできます。
    もちろんこれは「トライレベル」です。せめて将棋と競技のために何かをして
    ください。SGDK ツールキットを使用しています – GCC ベースの Motorola 68k 用コンパイラ、Sega Mega ハードウェアで動作するためのライブラリ。
    今では本当に大変だったことが分かります– 20~30年前にゲームを作っていた。たとえば、各タイル – 8×8 ピクセルの部分に分割し、一度に 1 つずつ描画する必要があります。また、各タイルのパレットは 16 色を超えてはなりません。もちろん今ではずっと簡単になりました
    が。もちろん現状と同様にゲームエンジン、サウンドエンジン、グラフィックエンジンを
    作成する必要があります。Sega Genesis エミュレータとゲームの ROM を使用して Red Queen をプレイできます。
    http://demensdeum.com/games/redQueenRampageSegaGenesis/RedQueenRampage.zip
    ソースを確認したい場合は、
    http://demensdeum.com/games/redQueenRampageSegaGenesis/RedQueenRampageSource.zip