LoginSignup
1
1

More than 5 years have passed since last update.

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

Posted at

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());
    }


}

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1