SFMLでImGuiを使用してゲーム開発ツールを作成する

こんにちは、Habr!







この記事は、私の記事をロシア語に無料で翻訳したもので、若干の変更と改良が加えられています。 SFMLでImGuiを使用することがいかにシンプルで便利かを示したいと思います。 始めましょう。













はじめに



ゲームを開発する場合、コンテンツの作成(レベルのエディター、リソースなど)とデバッグのための優れたツールを持つことが非常に重要です。 これらのものがあると、生産性と創造性が向上します。 バグをキャッチし、すでに見つかっているものを修正するのははるかに簡単です。さまざまな変数の値を表示し、それらを変更するウィジェットを作成して、特定の値でゲームがどうなるかを確認するのは簡単です。 変数を変更するためのウィジェットは、ゲームプレイを洗練するためにも非常に便利です。 たとえば、キャラクターの速度、武器のリロードの速度などを簡単に変更できます。







ゲーム ImGuiを使用し作成したツールは次のとおりです。









レベルエディター









Luaコンソール









アニメーションエディター







ご覧のとおり、ImGuiには便利で便利なインターフェイスを作成するのに十分な数のウィジェットがあります。







ImGuiと即時GUIコンセプト



即時モードGUIは保持モードGUIと呼ばれる従来のインターフェイスプログラミング手法と少し異なります 。 ImGuiウィジェットは、ゲームループのすべてのフレームで作成および描画されます。 ウィジェット自体は、自身の状態を内部に保存しません。または、通常はプログラマから隠されている、絶対に必要な最小値を保存します。







ボタンを作成するQtとは異なり、 QPushButton



オブジェクトを作成し、押されたときに呼び出されるコールバック関数に関連付ける必要がありますが、 QPushButton



ではすべてがはるかに簡単です。 コードを記述するだけで十分です。







 if (ImGui::Button("Some Button")) { ... // ,     }
      
      





このコードは、ユーザーがこのボタンを使用できるようにするゲームサイクルの各反復で呼び出す必要があります。







最初は、この概念は奇妙で非常に効率が悪いように見えるかもしれませんが、他のコードと比較して非常に高速に動作するため、複雑なインターフェースでもゲームのパフォーマンスに大きな変更を加えません。







このテクニックについてもう少し知りたい場合は、ImGuiについてのこのケーシームラトリビデオをご覧ください。







ImGuiの利点は何ですか?









カスタマイズ



それでは始めましょう







  1. 空のウィンドウを表示する簡単なSFMLプログラムを作成します。 これをまだ行っていない場合は、 チュートリアルを使用できます。
  2. ImGuiをダウンロードします
  3. ImGui SFMLバインディングをダウンロードし、ImGuiをダウンロードしたフォルダーに入れます。

    重要imconfig-SFML.hの内容をimconfig.hに追加ます
  4. ImGuiフォルダーをプロジェクトのincludeディレクトリーに追加します
  5. 次のファイルをプロジェクトビルドに追加します。







    • imgui.cpp
    • imgui_draw.cpp
    • imgui-sfml.cpp
    • imgui_demo.cpp


  6. リンクエラーが発生した場合は、OpenGLをプロジェクトにリンクしてください。


ImGuiウィンドウを作成し、背景色とウィンドウタイトルを変更できるコードの小さな例を次に示します。 何が起こっているかの説明が続きます。







 #include "imgui.h" #include "imgui-sfml.h" #include <SFML/Graphics/RenderWindow.hpp> #include <SFML/System/Clock.hpp> #include <SFML/Window/Event.hpp> int main() { sf::RenderWindow window(sf::VideoMode(640, 480), ""); window.setVerticalSyncEnabled(true); ImGui::SFML::Init(window); sf::Color bgColor; float color[3] = { 0.f, 0.f, 0.f }; //      char.   // std::string   ,     char windowTitle[255] = "ImGui + SFML = <3"; window.setTitle(windowTitle); sf::Clock deltaClock; while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { ImGui::SFML::ProcessEvent(event); if (event.type == sf::Event::Closed) { window.close(); } } ImGui::SFML::Update(window, deltaClock.restart()); ImGui::Begin("Sample window"); //   //    if (ImGui::ColorEdit3("Background color", color)) { //     ,   //   bgColor.r = static_cast<sf::Uint8>(color[0] * 255.f); bgColor.g = static_cast<sf::Uint8>(color[1] * 255.f); bgColor.b = static_cast<sf::Uint8>(color[2] * 255.f); } ImGui::InputText("Window title", windowTitle, 255); if (ImGui::Button("Update window title")) { //   ,      //      // if(ImGui::InputText(...)) window.setTitle(windowTitle); } ImGui::End(); // end window window.clear(bgColor); //     ImGui::SFML::Render(window); window.display(); } ImGui::SFML::Shutdown(); }
      
      





次のようなものが表示されるはずです。













何かを変えてみてください。 RGBフィールドの1つをダブルクリックすると、対応する値を入力できます。 フィールドの1つをプルすると、現在の入力値をスムーズに変更できます。 入力フィールドでは、ボタンをクリックした後、ウィンドウのタイトルを変更できます。













では、どのように機能するかを見てみましょう。







ImGui ImGui::SFML::Init



呼び出すと、ImGuiが初期化されます。呼び出されると、 sf::RenderWindow



ウィンドウへのリンクが関数に渡されます。 現在、標準フォントも作成されており、今後使用されます。 (他のフォントの使用方法については、imgui-sfmlの説明の「フォントの使用方法」セクションを参照してください)。







プログラムを終了するとき、ImGuiが使用するリソースを解放するImGui::SFML::Shutdown



関数を呼び出すことが重要です。







ImGuiのゲームサイクルには、更新とレンダリングの2つのフェーズがあります。







更新は、イベント処理、ImGuiのステータスの更新、およびウィジェットの更新/作成で構成されます。 イベント処理は、 ImGui::SFML::ProcessEvent



呼び出しを通じて発生します。 ImGuiは、キーボード、マウス、フォーカス、ウィンドウサイズのイベントを処理します。 ImGuiの状態はImGui::SFML::Update



、デルタ時間(2つの更新間の時間)を送信します。これはImGuiがウィジェットの状態(アニメーションなど)を更新するために使用します。 また、この関数では、 ImGui::NewFrame



、その呼び出しの後、新しいウィジェットを作成することがすでに可能です。







ImGui レンダリングはImGui::SFML::Render



呼び出すことで実行されます。 ImGui::SFML::Update



ImGui::SFML::Render



呼び出しの間にウィジェットを作成/更新することが非常に重要です。そうしないと、ImGuiは状態の違反を誓います。







入力とゲームを更新するよりも頻繁にレンダリングしない場合は、更新の各反復の終わりに、 ImGui::EndFrame



も呼び出す必要があります。







 while (gameIsRunning) { while (updateIsNeeded()) { updateGame(dt); ImGui::SFML::Update(window, dt); ImGui::EndFrame(); } renderGame(); }
      
      





ウィジェットは、適切な関数( ImGui::InputInt



またはImGui::Button



)を呼び出すことで作成されます。 ImGui::ShowTestWindow



を呼び出すと、 ImGui::ShowTestWindow



の使用例が多数表示されます 。すべてのコードはimgui_demo.cppにあります。







SFMLの便利な関数オーバーロード



いくつかの関数オーバーロードがバインダーのSFML用に作成されました。たとえば、 ImGui::Image



およびImGui::ImageButton



sf::Sprite



およびsf::Texture



スローできます。







おわりに



以下にそのようなライブラリを示します。使いやすく構成しやすく、ツールの作成やデバッグに非常に便利です。 素敵な使い方をしてください!







PS興味があれば、チュートリアルの2番目の部分を翻訳できます。これは、ImGuiを最新のC ++および標準ライブラリとともに使用することについて説明しています。 ImGuiを使用する(または既に使用している)ことに注意することをお勧めします。ImGuiの主な問題を解決し、C ++ 03で行うよりも簡単で安全なものにすることがどれほど簡単かを示しています。








All Articles