シンプルだけど動く背景のつくりかた(OpenSiv3D)


シンプルだけど動く背景のつくりかた(OpenSiv3D)

こんばんは、ミツゴロウです。
今年10月に新作ゲーム「くらげみゅーじかる」を公開しました。
ダウンロードはこちら https://www.freem.ne.jp/win/game/24153

そのゲームで使われた背景の作り方を紹介します。

どんな背景?

丸い泡玉がたくさん表示されて、それが下から上方向に直線移動していくものです。

使用するテクスチャは泡玉1個だけです。この画像は、Photoshopで

円形に塗りつぶし→中身を範囲をぼかしてDelete

とすればすぐ作れます。

↑ここに画像があるが、白一色なのでみえないね。クリックすれば見える。

プログラム実装

※今回はQiita記事用に1ファイル内で収めていますが、実際の実装ではクラスごとにファイル分けすることをおススメします。

「泡玉」というオブジェクトを作るため、泡玉はクラスで書くといいでしょう。
泡玉はたくさんあるので、クラスをArrayに入れて使います。(数は固定)
コンストラクタでランダムな点に座標をセットします。大きさも1/16~1でランダム。
毎フレームUpdate関数を呼び出して、泡玉の座標を上に移動させていきます。画面外に出たら、画面の下にワープする処理も追加します。これにより、泡玉は画面内をずっと動き続けます。
画像描画はTextureAssetを使うことで、クラスを別ファイルに分けても描画関数を使うことができます。

ソースコード

Main.cpp

# include <Siv3D.hpp> // OpenSiv3D v0.4.2

const int32 TEX_SIZE = 200; // テクスチャの画像サイズ
class Bubble
{
private:
    Vec2 pos;   // ポジション
    double size;    // 泡のサイズ

public:
    // コンストラクタ 初期配置をきめる
    Bubble() 
    {
        size = Random(0.25, 1.0) * Random(0.25, 1.0); // Random2個かいた方がサイズのバランスが良くなる
        pos = Vec2(Random(0 - size * TEX_SIZE / 2, 1280 + size * TEX_SIZE / 2), Random(0 - size * TEX_SIZE / 2, 720 + size * TEX_SIZE / 2));
    }

    // デストラクタ 今回は特に何もなし
    ~Bubble()
    {
    }

    // 1フレームに1回呼び出す処理。ここでは移動処理
    void update()
    {
        pos.y -= 100.0 * size * Scene::DeltaTime();

        // 画面の一番上に完全に出たら、画面の一番下にワープ
        if (pos.y <= 0 - size * TEX_SIZE / 2)
        {
            // サイズとX座標も変えるとランダム性が高く見える
            size = Random(0.25, 1.0) * Random(0.25, 1.0);
            pos.x = Random(0 - size * TEX_SIZE / 2, 1280 + size * TEX_SIZE / 2);

            pos.y = 720 + size * TEX_SIZE / 2;
        }
    }

    // 画像描画
    void draw()
    {
        TextureAsset(U"tex1").scaled(size).drawAt(pos, HSV(240.0 - size * 80.0, 1.0, 1.0));
    }
};

void Main()
{
    // 画面サイズを1280*720にする ただ単に自作ゲームのサイズに合わせているだけ
    Window::Resize(1280, 720);

    // 背景を暗いアオイロにする
    Scene::SetBackground(ColorF(0.125, 0.125, 0.25));

    // TextureAsset
    TextureAsset::Register(U"tex1", U"Bubble.png");

    // 泡玉はたくさん表示するのでArrayに入れる(120個がちょうどよい)
    Array<Bubble> bubble;
    bubble.resize(120);

    while (System::Update())
    {
        // すべてのbubbleに更新処理をする
        for (auto &i : bubble)
        {
            i.update();
        }

        // すべてのbubbleに描画処理をする
        for (auto &i : bubble)
        {
            i.draw();
        }
    }
}


出力画像(実際には動いている)

発展形

テクスチャを変えたり、移動のさせ方を変えるとバリエーションが増えます。いろいろ考えてみましょう。

例、テクスチャを星にした(回転もする)

例2、テクスチャ画像を横並びにした

まとめ

テクスチャ画像1つでも、たくさん表示させて動かせば簡単に動く背景が作れます。
メニュー画面などに使う際はぜひご活用ください。