DxLibから引っ越したSiv3D使いの感想


Siv3D Advent Calendar 2015 12 日目の記事です。
本日はミツゴロウが担当します。

自分はSiv3Dと出会ってもうすぐ2年。Siv3D作者のRyoSuzukiさんと直接会って、自分の制作スタイルがSiv3Dに変わった。いままではDxLibというものを使っていたが、それを手放すくらいSiv3Dの機能には驚きました。

Siv3Dは現代的、かつ高機能、そしてわかりやすいです!
そこでSiv3Dがすごい!というところをいくつかまとめました。

Siv3Dは、標準描画の見た目がいい

まず、Siv3Dは見た目がきれいなゲームが作りやすいことに感動した。とくに、フォントが扱いやすく描画がきれいでした。

画像:Siv3Dはじめたての時に作った数字ゲーム。テクスチャなし縛りで標準的な描画機能だけで作った。フォントの変更が容易で、文字の表現がしやすいのがいい。デフォルトでアンチエイリアスがかかってくれるので、仕上がりがきれい。

ちなみに、Siv3Dにアンチエイリアスのかからないビットマップフォントを設定可能にしたのは自分です。(どうでもいい)

それと、Siv3DにはHSV表色系が標準装備されている。このように虹色を表現するのがとても簡単なのだ。DxLibを使っていた時代はHSV関数(もどき?)を自前で実装しようとして四苦八苦してました。

画像引用: http://play-siv3d.hateblo.jp/entry/reference/KineticTypography

ベクトルを制するものはゲーム制作を制す

Siv3Dにはベクトルクラスがある。ベクトルはゲーム制作の知識には必要不可欠。数学が弱い人は頭抱えるけど・・・
Siv3Dのベクトルは、各クラスの引数に組み込めるように設計されている。また、算術演算子や便利な関数群が用意されており、扱いやすい。
ベクトルに慣れない人は、まずはプレイヤーなどのポジションを表す変数x, yを1つの2次元ベクトルで管理するところから始めてみよう。

VectorTest.cpp
# include <Siv3D.hpp>

void Main() {
    Vec2 v0(0.0, 0.0);
    Vec2 v1(50.0, 300.0);
    Vec2 v2(200.0, 100.0);
    while (System::Update()) {
        Line(v0, v1).drawArrow(3.0, Vec2(5.0, 10.0), HSV(300));
        Line(v0, v2).drawArrow(3.0, Vec2(5.0, 10.0), HSV(180));
        Line(v1, v1 + v2).drawArrow(1.0, Vec2(5.0, 10.0), HSV(240));
        Line(v2, v1 + v2).drawArrow(1.0, Vec2(5.0, 10.0), HSV(0));
    }
}

当たり判定は神

Siv3Dには、当たり判定を処理する関数がある。自分が一番ショックだったのはこの機能です。なぜならば、比較的複雑な図形同士の判定も正確に判定してしまうからだ。そして違う図形同士の判定まで取れてしまう。
計算速度的には自前実装でやったほうが高速かもしれないが、面倒な当たり判定を取ってくれるのはうれしい。
この当たり判定の機能は、マウスクリックのボタンを作るのに最適で、図形に乗っかっているときにクリックすればそれだけでクリックボタンができてしまう。お手軽!

ButtonTest.cpp
# include <Siv3D.hpp>

void Main() {
    int buttonColor = 0;
    int buttonClick = 0;
    Font font(25);
    Rect button1(100, 100, 200, 200);
    while (System::Update()) {
        if (buttonClick > 0) --buttonClick; // 時間差演出のために使う

        if (button1.intersects(Mouse::Pos())) {
            buttonColor += 2;   // マウスと重なってたら色が変わる
            if (Mouse::LeftClicked()) buttonClick = 15; // 重なった状態でクリック
        }

        // 描画
        button1.draw(HSV(buttonColor));
        button1.drawFrame(buttonClick / 2, buttonClick, HSV(buttonColor, 0.5, 1.0));
        font(L"ぼたん").drawCenter(button1.center, Color(255));
    }

}
// ちょっとだけ演出にこだわっているため、最低限必要なコード以外の処理も入っています。

ボタンにテクスチャを使いたい場合は、当たり判定だけを四角形などの図形でとり、その上にほぼ同じ大きさのテクスチャをのせればよい。図形オブジェクトは描画しなくても当たり判定に使えるから、意外と用途は広い。

クラスはプログラミング習得を難しくするか?

Siv3Dはあらゆる機能がクラス化されている。よくプログラミング初心者は「クラスあるから難しい」とかよく聞く。だからSiv3Dは難しいのではないか・・・?

自分の回答は「No」だ。

クラスは膨大な量のプログラムを分割するはたらきがある。クラスの中に関数を内包した方がスッキリする。Siv3Dは、四角形も円もテクスチャも、すべてクラス(C++の構造体も含む)の形となっている。

クラスの基本は
- 変数と同じ感覚でオブジェクトを作る
- 「~~.○○」で中身を呼び出す。
これだけできればSiv3Dはある程度使えます。その他「Window」「Mouse」などシステムまわりのものを呼び出すときは「.」ではなく「::」を使うくらい。

Siv3Dのテクスチャクラスやサウンドクラスは、クラスによって管理されているため、そのオブジェクトが消滅すると自動的にメモリが解放される。「メモリリーク」の事を考えなくていいのが強みだ。メモリリークはなかなか気づかないバグなのがやっかい。

で、何が言いたいか

Siv3D最高!
Ryoさんが作ってくれたSiv3D、使ってあげてください。

Siv3Dの改善点

でもSiv3Dに満足できない点もいくつかあります。

リファレンスの不足

DxLibでは関数1つ1つを丁寧に説明する完璧なリファレンスがあるが、Siv3Dのリファレンスは現状穴あき状態だ。リファレンスの充実は新規ユーザーを獲得するのに重要な要素だから、早いうちに完成させなければならない。Ryoさん1人でこれを作るのは大変そうだから、誰かほかの人がリファレンス作れるようなシステムにならないだろうか・・・?

実際、「Siv2D」

3Dの機能がまだ少ないのが弱点。3D作品は第2回10時間GameJamのしょうぐんさんの作品くらいしかまだ見たことがないです。名前がSiv「3D」だから、3D機能を推していかないといけないと思いました。もちろん、2D機能のように使いやすさ重視で実装されてほしいものですね。

最後に

ゲーム制作の環境は多様化してきている。UnityやUE、Altseed、JavaScriptの何か… など。数多くあるが、それらを尊重しつつ自分はその選択肢にSiv3Dをおすすめしていきたい。

明日の記事は @Reputeless さんです。
よろしくお願いします。