STGを200行以内で@280行【改善策募集】

  • 1
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Siv3DでSTGを作ります。
目標は

1.200行以内に収めること(Mainのみ)
2.http://play-siv3d.hateblo.jp/ と似た書き方
3.華やかであること
4.STGとして遊べること

です。
現状

280行→長い
画面→地味
STG→死なない

改善策求む

Main.cpp

# include <Siv3D.hpp>
//March2014

class Mover
{
public:

    Mover(
        const Vec2& pos, 
        const Vec2& velocity, 
        double radius
        ) :
        m_pos(pos),
        m_velocity(velocity),
        m_radius(radius)
    {

    }

    virtual void update()
    {
        m_pos += m_velocity;

        if (!RectF(Window::Size()).intersects(Circle(m_pos, m_radius)))
        {
            m_isActive = false;
        }

        ++m_count;
    }

    virtual void draw()
    {
        RectF(2.0 * Vec2(m_radius, m_radius)).setCenter(m_pos).draw();
    }

    void setPos(const Vec2& pos)
    {
        m_pos = pos;
    }

    const Vec2& getPos() const
    {
        return m_pos;
    }

    void setRadius(double radius)
    {
        m_radius = radius;
    }

    double getRadius() const
    {
        return m_radius;
    }

    void setActive(bool isActive)
    {
        m_isActive = isActive;
    }

    bool isActive() const
    {
        return m_isActive;
    }

protected:

    Vec2 m_pos;

    Vec2 m_velocity;

    double m_radius;

    bool m_isActive = true;

    unsigned m_count = 0;

};

class Object : public Mover
{
public:

    Object(
        const Vec2& pos,
        vector<std::shared_ptr<Mover>>& bullets,
        const Vec2& velocity,
        double radius       
        ) :
        Mover(pos, velocity, radius),
        m_bullets(bullets)
    {

    }

    void update() override
    {
        Mover::update();

        if (m_count % 30 == 0)
        {
            m_bullets.emplace_back(std::make_shared<Mover>(m_pos, Vec2::Down * 5.0, 2.5));
        }
    }

    void setHp(int hp)
    {
        m_hp = hp;

        if (m_hp <= 0)
        {
            m_isActive = false;
        }
    }

    int getHp() const
    {
        return m_hp;
    }

protected:

    int m_hp = 3;

    vector<std::shared_ptr<Mover>>& m_bullets;
};

class Player : public Object
{
public:

    Player(
        const Vec2& pos, 
        vector<std::shared_ptr<Mover>>& bullets,
        const Vec2& velocity = Vec2(0.0, 0.0), 
        double radius = 10.0
        ) :
        Object(pos, bullets, velocity, radius)
    {
        m_hp = 10;
    }

    void update() override
    {
        m_velocity = Vec2(0.0, 0.0);

        const double speed = 5.0;

        if (Input::KeyLeft.pressed)
        {
            m_velocity += Vec2::Left * speed;
        }
        if (Input::KeyRight.pressed)
        {
            m_velocity += Vec2::Right * speed;
        }
        if (Input::KeyUp.pressed)
        {
            m_velocity += Vec2::Up * speed;
        }
        if (Input::KeyDown.pressed)
        {
            m_velocity += Vec2::Down * speed;
        }
        if (Input::KeyZ.pressed)
        {
            m_bullets.emplace_back(std::make_shared<Mover>(m_pos, Vec2::Up * 20.0, 10.0));
        }

        if (RectF(Window::Size()).contains(Circle(m_pos + m_velocity, m_radius)))
        {
            Mover::update();
        }
    }
};

bool CheckBullet(const std::shared_ptr<Object>& Object, const std::shared_ptr<Mover>& bullet)
{
    const Circle circleBullet(bullet->getPos(), bullet->getRadius());

    const Circle circleObject(Object->getPos(), Object->getRadius());

    if (circleBullet.intersects(circleObject))
    {
        Object->setHp(Object->getHp() - 1);

        bullet->setActive(false);

        return true;
    }
    else
    {
        return false;
    }
}

void Main()
{
    Window::SetTitle(L"Z:打つ 十字キー:移動");

    int score = 0;

    const Vec2 startPos = Vec2(Window::Width() / 2.0, Window::Height() * 4.0 / 5.0);

    vector<std::shared_ptr<Object>> enemies;
    vector<std::shared_ptr<Mover>> bulletsEnemy;
    vector<std::shared_ptr<Mover>> bulletsPlayer;
    std::shared_ptr<Player> player = std::make_shared<Player>(startPos, bulletsPlayer);

    while (System::Update())
    {
        if (System::FrameCount() % Random(30, 60) == 0)
        {
            enemies.emplace_back(std::make_shared<Object>(RandomVec2(Window::Width(), 0.0), bulletsEnemy, Vec2(0.0, 1.0), 20.0));
        }

        for (auto& enemy : enemies)
        {
            enemy->update();
        }

        for (auto& bullet : bulletsEnemy)
        {
            bullet->update();

            if (CheckBullet(player, bullet))
            {
                Rect(Window::Size()).draw(Palette::Red);
            }
        }

        for (auto& bullet : bulletsPlayer)
        {
            bullet->update();

            for (auto& enemy : enemies)
            {
                if (CheckBullet(enemy, bullet))
                {
                    score += 1;
                }
            }
        }

        player->update();

        Erase_if(bulletsEnemy, [](const std::shared_ptr<Mover>& bullet){return !bullet->isActive(); });
        Erase_if(bulletsPlayer, [](const std::shared_ptr<Mover>& bullet){return !bullet->isActive(); });
        Erase_if(enemies, [](const std::shared_ptr<Object>& enemy){return !enemy->isActive(); });

        //描画
        for (auto& enemy : enemies)
        {
            enemy->draw();
        }

        for (auto& bullet : bulletsEnemy)
        {
            bullet->draw();
        }

        for (auto& bullet : bulletsPlayer)
        {
            bullet->draw();
        }

        player->draw();

        ClearPrint();
        Println(score);
        Println(player->getHp());
        Println(bulletsEnemy.size());
        Println(bulletsPlayer.size());
        Println(enemies.size());
    }


}