ゲームエンジン「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 のチュートリアル https://github.com/lriki/LuminoTutorial
開発環境の準備 https://github.com/lriki/LuminoTutorial/blob/master/Common/1.md
以下、いくつかの例を紹介します。 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()) {} }
スプライトを表示する
#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()) { } }
ユーザー入力を受け取る
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++; } }
活用事例
開発中であったり、身内公開のままプロジェクトが終わったものが多いので、いくつかスクリーンショットでのご紹介です。
今後のロードマップ
一応、2D/3Dゲームを作る力はあります。が、それは私自身が開発に携わっていてヘルプが出せるからであって、第三者に Lumino だけ渡しても多分無理です。
なので、まずはなによりもドキュメントの整備と、開発中のゲームで必要な機能を優先的に実装したため生まれてしまった 滅茶苦茶汚いコード 負債の返済です。
そんなことと、開発中のゲームの完成を経て ver1.0 でしょうか。 そのあとはマルチプラットフォームとか、IDE とか、物理ベースレンダリングとかやりたいですね。
もし何かご意見などありましたら、GitHub の Issues に投げていただけると幸いです。