読者です 読者をやめる 読者になる 読者になる

lumino trail

ゲームエンジン作ってます。https://github.com/lriki/Lumino

ゲームエンジン「Lumino」の紹介

この記事は「ゲームエンジン・ライブラリ・ツールの開発 Advent Calendar 2016(http://qiita.com/advent-calendar/2016/gameengine)」の21日目です。 それなりのゲームエンジンを目指しつつも未だぴよぴよですが、せっかくなので公開したい。ということで、こんなことやっています、という紹介です。

Lumino とは

Lumino はゲームやグラフィックスソフトウェア を簡単に開発できるよう支援するための C++ ライブラリです。 ゲーム開発をメインのユースケースとしていますが、グラフィックスを中心とした様々な機能を、既存のアプリケーションに組み込んで使用することもできます。

特徴

さて、紹介、という体で改めて特徴に向き合うのもなかなか難しいです。

というのも、今の Lumino は単なるリアルタイムレンダリングエンジンにちょっとゲーム寄りの機能が付いた、という感じです。 それがどんなに効率よく綺麗な絵を描くことができるとしても、今できることはレガシーなマテリアルシステムで簡単な絵を描くだけです。 これまで作りこんできたシステムでどこまで行けるかは、今後の課題です。

そんな感じでまだまだ開発中ですが、今は以下のような方向を向いて進んでいます。

広く使われている API デザイン

Lumino はできるだけ Lumino らしさを求めないようにしています。 もしかしたら「ライブラリの色が薄い」と言うとピンと来る人もいるかもしれません。 Lumino で得た知識は他の開発ツールで利用できますし、逆に他の開発ツールで得た知識も Lumino で利用しやすい、ということを常に意識しています。

高パフォーマンス

Lumino はマルチコア環境に最適化されています。 昨今はPCに限らずモバイルでもマルチコアは当たり前になってきました。 そういったデバイスの性能を活かしきれるような設計にしています。

組み込みやすさ

Lumino に研究開発やプロトタイピングでも使いやすいように、という要求を持たせたのは、 私がエンジニアの仕事に就いてしばらく経ってからでした。 以来、既にある別のツールキットに組み込んで使うようなケースも考えています。

使い方

チュートリアルを書き始めています。よろしければ参考にしてみてください。

以下、いくつかの例を紹介します。 Lumino の雰囲気を見ていただければと思います。

Lumino で Hello world

#include <Lumino.h>
using namespace ln;

void Main()
{
    // Lumino の初期化処理
    Engine::Initialize();
    
    // 2D テキストを作成する
    auto text = TextBlock2D::Create("Hello, world!");
    
    // Lumino の更新処理 (ウィンドウへの描画などを行い、ウィンドウが閉じられていれば false を返す)
    while (Engine::Update()) {}
}

f:id:lriki:20161220233352p:plain

スプライトを表示する

#include <Lumino.h>
using namespace ln;

void Main()
{
    Engine::Initialize();

    // 画像を読み込み、2Dスプライトを作成する
    auto sprite = Sprite2D::Create("Assets/icon256.png");

    // 2Dスプライトの位置を設定する
    sprite->SetPosition(200, 100);

    while (Engine::Update())
    {
    }
}

f:id:lriki:20161220233436p:plain

ユーザー入力を受け取る

void Main()
{
    Engine::Initialize();
    
    // アクションマッピング (キーコンフィグ)
    // "left" と "right" に キーボードの左右キーと、ゲームパッドの1軸を割り当てる
    Input::AddButtonBinding("left", KeyboardBinding::Create(Keys::Left));
    Input::AddButtonBinding("left", GamepadBinding::Create(GamepadElement::Axis1Minus));
    Input::AddButtonBinding("right", KeyboardBinding::Create(Keys::Right));
    Input::AddButtonBinding("right", GamepadBinding::Create(GamepadElement::Axis1Plus));
    
    auto text = TextBlock2D::Create("A");
    
    while (Engine::Update())
    {
        Vector3 pos = text->GetPosition();
        
        if (Input.IsPressed("left"))   // "left" が押されているか?
            pos.x -= 5;
        if (Input.IsPressed("right"))  // "right" が押されているか?
            pos.x += 5;
        
        text->SetPosition(pos);
    }
}

音を鳴らす

void Main()
{
    Engine::Initialize();
    
    // BGM を再生する
    GameAudio::PlayBGM("bgm.ogg");
    
    int count = 0;
    while (Engine::Update())
    {
        // およそ2秒ごとに効果音を鳴らす
        if (count % 120 == 0)
        {
            GameAudio::PlaySE("se.wav");
        }
        count++;
    }
}

活用事例

開発中であったり、身内公開のままプロジェクトが終わったものが多いので、いくつかスクリーンショットでのご紹介です。 f:id:lriki:20161220234550p:plain

今後のロードマップ

一応、2D/3Dゲームを作る力はあります。が、それは私自身が開発に携わっていてヘルプが出せるからであって、第三者に Lumino だけ渡しても多分無理です。 なので、まずはなによりもドキュメントの整備と、開発中のゲームで必要な機能を優先的に実装したため生まれてしまった 滅茶苦茶汚いコード 負債の返済です。

そんなことと、開発中のゲームの完成を経て ver1.0 でしょうか。 そのあとはマルチプラットフォームとか、IDE とか、物理ベースレンダリングとかやりたいですね。

もし何かご意見などありましたら、GitHub の Issues に投げていただけると幸いです。