SHARE
TWEET

Untitled

a guest Apr 23rd, 2019 78 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # include <Siv3D.hpp> // OpenSiv3D v0.3.2
  2.  
  3.  
  4. class Bullet : public Circle
  5. {
  6. private:
  7.     Vec2 m_vel;
  8.     bool m_is_friend;
  9.  
  10. public:
  11.     Bullet(Vec2 pos, Vec2 vel, bool is_friend = false)
  12.         : Circle(pos, 5)
  13.         , m_vel(vel)
  14.         , m_is_friend(is_friend)
  15.     {}
  16.  
  17.     bool isFriend() const { return m_is_friend; }
  18.     bool isOut() const { return !intersects(Window::ClientRect().stretched(100)); }
  19.     void update() { moveBy(m_vel); }
  20.     void draw() const { Circle::draw(ColorF(m_is_friend ? 0.8 : 0.6)); }
  21. };
  22.  
  23.  
  24. class Item : public RectF
  25. {
  26. private:
  27.     static Array<String> m_Label;
  28.     int m_category;
  29.  
  30. public:
  31.     Item(Vec2 pos, int category)
  32.         : RectF(pos, 40.0)
  33.         , m_category(Min(category, getCategoryNum()))
  34.     {}
  35.  
  36.     String getLabel() const { return m_Label.at(m_category); }
  37.     static int getCategoryNum() { return m_Label.count() - 1; }
  38.     bool isOut() const { return !RectF::intersects(Window::ClientRect().stretched(100)); }
  39.     void update() { RectF::moveBy(Vec2::Down(100.0 * System::DeltaTime())); }
  40.  
  41.     void draw() const
  42.     {
  43.         rotated(Periodic::Sine0_1(3.0s) * Math::TwoPi)
  44.             .draw(HSV(220).lerp(HSV(330), (double)m_category / getCategoryNum()))
  45.             .drawFrame(1.0, ColorF(0.0));
  46.         FontAsset(U"item")(m_Label.at(m_category)).drawAt(center());
  47.     }
  48. };
  49. Array<String> Item::m_Label({ U"HP", U"S", U"R", U"W" });
  50.  
  51.  
  52. class Shooter
  53. {
  54. protected:
  55.     double m_Max_health;
  56.     double m_health;
  57.     Stopwatch m_cooldown;
  58.  
  59. public:
  60.     Shooter(double Max_health = 100.0)
  61.         : m_Max_health(Max_health)
  62.         , m_health(Max_health)
  63.         , m_cooldown(true)
  64.     {}
  65.  
  66.     bool isDead() const { return m_health <= 0.0; }
  67.     void damage(double amount) { m_health = Max(0.0, m_health - amount); }
  68.     void heal(double amout) { m_health = Min(m_Max_health, m_health + amout); }
  69. };
  70.  
  71.  
  72. class Player : public Triangle, public Shooter
  73. {
  74. private:
  75.     double m_speed_factor;
  76.     double m_reload_factor;
  77.     int m_way;
  78.     Font m_font;
  79.  
  80. public:
  81.     Player(double health = 1000.0)
  82.         : Triangle(Window::Width() / 2, Window::Height() * 4 / 5, 30.0)
  83.         , Shooter(health)
  84.         , m_speed_factor(1.0)
  85.         , m_reload_factor(1.0)
  86.         , m_way(1)
  87.         , m_font(100)
  88.     {}
  89.  
  90.     void addSpeed(double amount = 0.3) { m_speed_factor += amount; }
  91.     void addReload(double amount = 0.3) { m_reload_factor += amount; }
  92.     void addWay(int amount = 1) { m_way += amount; }
  93.  
  94.     Array<Bullet> GenerateBullets() const
  95.     {
  96.         Array<Bullet> generate;
  97.         if (m_way == 1)
  98.         {
  99.             generate << Bullet(centroid(), Vec2::Up(5.0), true);
  100.             return generate;
  101.         }
  102.         const double theta_base = 30_deg / Math::Pow((double)(m_way - 1), 0.8);
  103.         for (int i : step(m_way))
  104.         {
  105.             const double theta = (i - (double)(m_way - 1) / 2) * theta_base;
  106.             generate << Bullet(centroid(), Circular(5.0, theta), true);
  107.         }
  108.         return generate;
  109.     }
  110.  
  111.     bool update()
  112.     {
  113.         Vec2 Key_input(KeyD.pressed() - KeyA.pressed(), KeyS.pressed() - KeyW.pressed());
  114.         if (Key_input.length() > 1.0) Key_input.normalize();
  115.         const double speed = (KeyShift.pressed() ? 0.5 : 1.0) * m_speed_factor * 100.0 * System::DeltaTime();
  116.         const Vec2 pos = centroid().movedBy(Key_input * speed);
  117.         setCentroid(pos.clamped(Window::ClientRect()));
  118.  
  119.         if (KeySpace.pressed() && m_cooldown.msF() > 200.0 / m_reload_factor)
  120.         {
  121.             m_cooldown.restart();
  122.             return true;
  123.         }
  124.         return false;
  125.     }
  126.  
  127.     void drawStatus(int score) const
  128.     {
  129.         const int baseX = Window::Width() / 6, baseY = Window::Height() / 6;
  130.         Transformer2D t0(Mat3x2::Translate(baseX, baseY));
  131.         m_font(U"Score {:d}"_fmt(score)).draw(0, 0, ColorF(1.0, 0.2));
  132.         Transformer2D t1(Mat3x2::Translate(0, baseY));
  133.         m_font(U"Speed {:.1f}"_fmt(m_speed_factor)).draw(0, 0, ColorF(1.0, 0.2));
  134.         Transformer2D t2(Mat3x2::Translate(0, baseY));
  135.         m_font(U"Reload {:.1f}"_fmt(m_reload_factor)).draw(0, 0, ColorF(1.0, 0.2));
  136.         Transformer2D t3(Mat3x2::Translate(0, baseY));
  137.         m_font(U"Way {:d}"_fmt(m_way)).draw(0, 0, ColorF(1.0, 0.2));
  138.         Transformer2D t4(Mat3x2::Translate(0, baseY));
  139.         const double e = Max(0.0, m_health) / m_Max_health;
  140.         const HSV color = HSV(0, 0.2).lerp(HSV(120, 0.2), e);
  141.         m_font(U"HP {:.1f}%"_fmt(100.0 * e)).draw(0, 0, color);
  142.     }
  143.  
  144.     void draw() const
  145.     {
  146.         Triangle::draw(ColorF(0.5, 0.5, 1.0));
  147.     }
  148. };
  149.  
  150.  
  151. class Enemy : public Circle, public Shooter
  152. {
  153. private:
  154.     Vec2 m_start;
  155.     Vec2 m_dest;
  156.     Transition m_transition;
  157.  
  158. public:
  159.     Enemy(double health = 100.0)
  160.         : Circle(20)
  161.         , Shooter(health)
  162.         , m_transition(3.0s)
  163.     {
  164.         m_dest = RandomVec2(Window::Width(), Window::Height() * 0.3);
  165.         m_start = m_dest + Vec2(m_dest - Window::Center());
  166.         setPos(m_start);
  167.     }
  168.  
  169.     bool update()
  170.     {
  171.         m_transition.update(true);
  172.         setPos(m_start.lerp(m_dest, m_transition.easeOut()));
  173.        
  174.         if (m_cooldown > 2.0s)
  175.         {
  176.             m_cooldown.restart();
  177.             return true;
  178.         }
  179.         return false;
  180.     }
  181.  
  182.     void draw() const
  183.     {
  184.         const double e = Max(0.0, m_health) / m_Max_health;
  185.         Circle::draw(ColorF(1.0, 0.5, 0.5))
  186.             .drawFrame(1.0, ColorF(0.0))
  187.             .drawPie(-Math::Pi * e, Math::TwoPi * e, HSV(0).lerp(HSV(120), e));
  188.         Line({ 0, 0 }, Circular(r,  Math::Pi * e)).movedBy(center).draw(ColorF(0.0, EaseOutExpo(1.0 - e)));
  189.         Line({ 0, 0 }, Circular(r, -Math::Pi * e)).movedBy(center).draw(ColorF(0.0, EaseOutExpo(1.0 - e)));
  190.         Circle::scaled(0.7).draw(ColorF(1.0, 0.5, 0.5))
  191.             .drawArc(-Math::Pi * e, Math::TwoPi * e, 1.0, 0.0, ColorF(0.0));
  192.     }
  193. };
  194.  
  195.  
  196. void Main()
  197. {
  198.     Window::Resize(800, 800);
  199.  
  200.     Player player;
  201.     int score = 0;
  202.     Array<Enemy> enemies(10);
  203.     Array<Bullet> bullets;
  204.     Array<Item> items;
  205.     FontAsset::Register(U"item", 24);
  206.  
  207.     System::Sleep(5.0s);
  208.  
  209.     while (System::Update())
  210.     {
  211.         if (player.update())
  212.             bullets.append(player.GenerateBullets());
  213.         if (RandomBool(2.0 * System::DeltaTime()))
  214.             enemies << Enemy();
  215.         for (auto it = enemies.begin(); it != enemies.end();)
  216.         {
  217.             if (it->isDead())
  218.             {
  219.                 score++;
  220.                 if (RandomBool()) items << Item(it->center, Random(Item::getCategoryNum()));
  221.                 it = enemies.erase(it);
  222.                 continue;
  223.             }
  224.             if (it->update())
  225.                 bullets << Bullet(it->center, Circular(3.0, Random(160_deg, 200_deg)));
  226.             it++;
  227.         }
  228.         for (auto it = bullets.begin(); it != bullets.end();)
  229.         {
  230.             it->update();
  231.             bool is_hit = false;
  232.             if (it->isFriend())
  233.             {
  234.                 Optional<int> enemy_index;
  235.                 enemies.each_index([&](int i, auto & e) { if (it->intersects(e)) enemy_index = i; });
  236.                 if (enemy_index)
  237.                 {
  238.                     enemies.at(enemy_index.value()).damage(Random(20.0, 60.0));
  239.                     is_hit = true;
  240.                 }
  241.             }
  242.             else {
  243.                 if (it->intersects(player))
  244.                 {
  245.                     player.damage(Random(8.0, 12.0));
  246.                     is_hit = true;
  247.                 }
  248.             }
  249.             if (it->isOut() || is_hit)
  250.                 it = bullets.erase(it);
  251.             else
  252.                 it++;
  253.         }
  254.         for (auto it = items.begin(); it != items.end();)
  255.         {
  256.             it->update();
  257.             if (it->intersects(player))
  258.             {
  259.                 if (it->getLabel() == U"HP") player.heal(50.0);
  260.                 if (it->getLabel() == U"S") player.addSpeed();
  261.                 if (it->getLabel() == U"R") player.addReload();
  262.                 if (it->getLabel() == U"W") player.addWay();
  263.                 it = items.erase(it);
  264.             }
  265.             else if (it->isOut())
  266.                 it = items.erase(it);
  267.             else
  268.                 it++;
  269.         }
  270.  
  271.         player.drawStatus(score);
  272.         bullets.each([](const auto & b) { b.draw(); });
  273.         items.each([](const auto & i) { i.draw(); });
  274.         enemies.each([](const auto & e) { e.draw(); });
  275.         player.draw();
  276.     }
  277. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top