Help us understand the problem. What is going on with this article?

Siv3D実装会で作ったサンプルプログラム

この記事は Siv3D Advect Calendar 2018 の20日目の記事です。

こんにちは。去年 Siv3D/OpenSiv3Dの便利な機能 を書いたleafです。
今回は、OpenSiv3D実装会でできたサンプル的なプログラムが2つほどあるので、紹介したいと思います。

注意

OpenSiv3D v0.3.0からデフォルトの解像度が 640*480 → 800*600 になったので、支障が出ないようにWindowの大きさを 640*480 に設定しています。時間があったらWindowの大きさが変わっても支障がでないようにしたいと思います

シューティングゲーム

スクリーンショット.png

code.cpp
 # include <Siv3D.hpp>

 void Main()
 {
    Window::Resize(640, 480);

    int32 level = 0;

    Graphics::SetBackground(ColorF(0.8, 1.0, 0.8));

    const Texture textureA(Emoji(U"🛩"), TextureDesc::Mipped);

    const Texture textureB(Emoji(U"👾"), TextureDesc::Mipped);

    Stopwatch time1(true);

    Stopwatch time2(true);

    Array<Vec2> bullets, enemies;

    Vec2 playerPos = Window::Center();

    while (System::Update())
    {
        const double speed = System::DeltaTime() * 100;

        playerPos.moveBy(Vec2(KeyRight.pressed() - KeyLeft.pressed(), KeyDown.pressed() - KeyUp.pressed())
            .setLength(6 * speed))
            .clamp(Window::ClientRect());

        if (time1 >= 250ms - 1ms * Min(level, 180)) {
            enemies.emplace_back(680, Random(40, 440));
            ++level;
            time1.restart();
        }
        if (KeyZ.pressed() && time2 >= 40ms) {
            bullets.push_back(playerPos);
            time2.restart();
        }

        bullets.each([=](Vec2& bullet) { bullet.x += 9.0 * speed; });
        enemies.each([=](Vec2& enemy) { enemy.x -= 3.0 * speed; });

        bullets.remove_if([](const Vec2& b) { return b.x > 664.5; });
        enemies.remove_if([&](const Vec2& e)
        {
            for (auto it = bullets.begin(); it != bullets.end(); ++it)
            {
                if (it->distanceFrom(e) < 35.0)
                {
                    bullets.erase(it);
                    return true;
                }
            }
            return e.x < -35.0;
        });

        bullets.each([](const Vec2& b) { Circle(b, 4).draw(Palette::Orange);  });

        textureA.resized(150).drawAt(playerPos);

        enemies.each([&](const Vec2& e) { textureB.resized(70).drawAt(e); });

    }
 }

OpenSiv3Dのサンプルに新しいシューティングゲームがなかったので作った、横に動くタイプのシューティングゲームです。
フレームレートが変化してもできるだけ動作の速さはできるだけ変わらないようになってます。
是非スコアを表示するなり背景をつけたりするなりなんなりしてください。

High & low

b1edad25861383da4c413cc983d124b1.png

code.cpp
# include <Siv3D.hpp>
 # include <HamFramework.hpp>

 std::pair<PlayingCard::Card, PlayingCard::Card> ChoiceTwoCards(const Array<PlayingCard::Card>& cards)
 {
    const Array<PlayingCard::Card> cardPair = cards.shuffled().take(2);

    return{ cardPair[0], cardPair[1] };
 }

 int32 Reorder(int32 var)
 {
    return (var + 12) % 14;
 }

 void Main()
 {
    Window::Resize(640, 480);
    Graphics::SetBackground(Palette::Darkgreen);
    const Font font(65, Typeface::Bold);
    const RectF lowButton(Arg::center(Window::Center().movedBy(-130, 100)), 200, 90);
    const RectF highButton(Arg::center(Window::Center().movedBy(130, 100)), 200, 90);

    const PlayingCard::Pack pack(100, Palette::Red);
    const Array<PlayingCard::Card> cards = PlayingCard::CreateDeck(0);

    int32 combo = 0;
    bool selected = false, correct = false;

    auto cardPair = ChoiceTwoCards(cards);
    cardPair.first.flip();

    while (System::Update())
    {
        if (MouseL.down())
        {
            if (!selected)
            {
                if (lowButton.mouseOver())
                {
                    cardPair.first.flip();
                    correct = (Reorder(cardPair.first.rank) <= Reorder(cardPair.second.rank));
                    selected = true;
                }
                else if (highButton.mouseOver())
                {
                    cardPair.first.flip();
                    correct = (Reorder(cardPair.first.rank) >= Reorder(cardPair.second.rank));
                    selected = true;
                }
            }
            else
            {
                cardPair = ChoiceTwoCards(cards);
                cardPair.first.flip();
                selected = false;
                combo = correct ? (combo + 1) : 0;
            }
        }

        if (lowButton.mouseOver() || highButton.mouseOver())
        {
            Cursor::RequestStyle(CursorStyle::Hand);
        }

        RectF(Arg::center(Window::Center().movedBy(-130, -60)), pack.size()).drawShadow(Vec2(6, 6), 12, 0);
        pack(cardPair.first).drawAt(Window::Center().movedBy(-130, -60));

        RectF(Arg::center(Window::Center().movedBy(130, -60)), pack.size()).drawShadow(Vec2(6, 6), 12, 0);
        pack(cardPair.second).drawAt(Window::Center().movedBy(130, -60));

        lowButton.rounded(25).draw(HSV(Palette::Lightblue) - HSV(0, lowButton.mouseOver()*0.15, 0)).drawFrame(2, 2, ColorF(0.6));
        highButton.rounded(25).draw(HSV(Palette::Orange) - HSV(0, highButton.mouseOver()*0.4, 0)).drawFrame(2, 2, ColorF(0.6));

        if (selected)
        {
            font(correct ? U"Win" : U"Lose")
                .drawAt(Window::Center().movedBy(0, -110),
                    correct ? Palette::Red : Palette::Blue);
        }

        font(U"Low").drawAt(lowButton.center());
        font(U"High").drawAt(highButton.center());

        if (combo)
        {
            font(combo).drawAt(Window::Center().movedBy(0, -180), Palette::Gold);
        }
    }
 }

せっかくSiv3Dにはトランプ描画機能があるのに、公式サンプルがないということで、トランプを使った簡単なゲームです。
ハイアンドロー(ハイロー)と呼ばれる、カジノとかにありそうなゲームです。(というか多分あります)
2つ裏のカードがあるので、片方を表にして数字を見て、裏になっているもう片方のカードにかかれている数字が表になったカードの数字より高い(High)か低い(Low)か当てるゲームです。
何連続正解かが黄色い字ででるのでわかるようになっています。
ハイスコア機能をつけたりするといいかもしれません。

さいごに

上にある二つのプログラムは (https://scrapbox.io/Siv3Dbyleaf/ )にあります
新しくサンプルを作ったらここにあげられるかもしれません。
試験や文化祭のゲームづくりなんかで忙しかったので最近は実装会に行けてませんでしたが、そろそろ行きたいですね。

pcleaf2326
プログラミングをしています
https://twitter.com/pcleaf2326
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした