Siv3D

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

More than 5 years have passed since last update.

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

}