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