]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
attacks?
authorClyne Sullivan <tullivan99@gmail.com>
Tue, 7 Mar 2017 23:17:51 +0000 (18:17 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Tue, 7 Mar 2017 23:17:51 +0000 (18:17 -0500)
.gitignore
include/attack.hpp [new file with mode: 0644]
include/components.hpp
include/vector2.hpp
src/attack.cpp [new file with mode: 0644]
src/components.cpp
src/engine.cpp
src/player.cpp
xml/entities.xml

index d913368eda2d376a74a2d6f66f94e5a1275d41ad..a554d64b6ad0e0618e73af65fada9296f803f1f3 100644 (file)
@@ -6,3 +6,5 @@ brice.dat
 config/settings.xml\r
 setup.mk\r
 TODOS\r
+out/*\r
+screenshots/*\r
diff --git a/include/attack.hpp b/include/attack.hpp
new file mode 100644 (file)
index 0000000..412694e
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef FIGHT_HPP_
+#define FIGHT_HPP_
+
+#include <entityx/entityx.h>
+
+#include <forward_list>
+
+#include <vector2.hpp>
+
+enum class AttackType : char {
+       ShortSlash,
+       LongSlash
+};
+
+struct AttackEvent {
+       AttackEvent(vec2 p, AttackType at, int pow = 10)
+               : pos(p), type(at), power(pow) {}
+
+       vec2 pos;
+       AttackType type;
+       int power;
+};
+
+class AttackSystem : public entityx::System<AttackSystem>, public entityx::Receiver<AttackSystem> {
+private:
+       std::forward_list<AttackEvent> attacks;
+
+public:
+       explicit AttackSystem() = default;
+
+       void configure(entityx::EventManager& ev) {
+               ev.subscribe<AttackEvent>(*this);
+       }
+
+       void receive(const AttackEvent& ae);
+       void update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt) override;
+};
+
+#endif // FIGHT_HPP_
index 541f0f861a6e40e7faac323c59675aab845e4258..0fb8ec679a0fe2a0745a4e5c2900e8657dc63f86 100644 (file)
@@ -172,7 +172,9 @@ struct Health : public Component {
                (void)imp;
                (void)def;
                // TODO
-               health = maxHealth = 1;
+               if (def->QueryIntAttribute("value", &health) != XML_NO_ERROR)
+                       health = 1;
+               maxHealth = health;
        }
 };
 
@@ -208,6 +210,8 @@ struct Name : public Component {
        }
 };
 
+struct Player {};
+
 struct ItemDrop {
        ItemDrop(InventoryEntry& ie)
                : item(ie) {}
index c1148da53f872338404d3b7d6e31f7c971d24304..828654c352a7376e3207709f8afa99e55f89796f 100644 (file)
@@ -84,6 +84,10 @@ struct vector2 {
                return (x < v.x) && (y < v.y);
        }
 
+       bool operator<=(const T& n) const {
+               return (x <= n) && (y <= n);
+       }
+
        // other functions
        std::string toString(void) const {
                return "(" + std::to_string(x) + ", " + std::to_string(y) + ")";
diff --git a/src/attack.cpp b/src/attack.cpp
new file mode 100644 (file)
index 0000000..226fe2f
--- /dev/null
@@ -0,0 +1,54 @@
+#include <attack.hpp>
+#include <components.hpp>
+#include <engine.hpp>
+#include <particle.hpp>
+
+constexpr int shortSlashLength = 100;
+constexpr int longSlashLength = 200;
+
+// math helpers because we don't trust stdlib
+template<typename T>
+inline T abs(const T& n) {
+       static_assert(std::is_arithmetic<T>::value, "abs expects numbers");
+       return n >= 0 ? n : -n;
+}
+
+
+void AttackSystem::receive(const AttackEvent& ae)
+{
+       attacks.emplace_front(ae);
+}
+
+void AttackSystem::update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt)
+{
+       (void)en;
+       (void)ev;
+       (void)dt;
+
+       for (const auto& a : attacks) {
+               switch (a.type) {
+               case AttackType::ShortSlash:
+                       en.each<Position, Solid, Health>(
+                               [&a](entityx::Entity e, Position& pos, Solid& dim, Health& h) {
+                                       (void)e;
+                                       if (e.has_component<Player>())
+                                               return;
+                                       vec2 eloc (pos.x + dim.width / 2, pos.y + dim.height / 2);
+                                       if (abs(eloc.x - a.pos.x) <= shortSlashLength) {
+                                               h.health -= a.power;
+                                               game::engine.getSystem<ParticleSystem>()->addMultiple(10, ParticleType::SmallBlast,
+                                                       [&](){ return eloc; }, 500, 7);
+                                       }
+                               }
+                       );
+                       break;
+               case AttackType::LongSlash:
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       attacks.clear();
+}
+
index 644d504af20d99fd046d629f976b77e6fc913844..f4ac01e3c015ea86b83934efdf26f3389074f2b8 100644 (file)
@@ -182,7 +182,7 @@ void RenderSystem::render(void)
                if (entity.has_component<Health>()) {
                        float width = entity.component<Solid>()->width;
                        auto& health = *entity.component<Health>();
-                       width /= health.health / health.maxHealth;
+                       width *= health.health / static_cast<float>(health.maxHealth);
 
                        GLfloat health_coord[] = {
                                pos.x, pos.y, -9, 0, 0,
index ee35d0610cfba6c8119e73bd9641f40499aa384d..640356e3f3fde0f1dd860818799f47eac93651d2 100644 (file)
@@ -11,6 +11,7 @@
 #include <quest.hpp>
 #include <particle.hpp>
 #include <weather.hpp>
+#include <attack.hpp>
 
 Engine::Engine(void)
     : shouldRun(true), systems(game::entities, game::events)
@@ -35,6 +36,7 @@ void Engine::init(void) {
 
        systems.add<ParticleSystem>();
        systems.add<WeatherSystem>();
+       systems.add<AttackSystem>();
 
     systems.configure();
 
@@ -54,6 +56,7 @@ void Engine::update(entityx::TimeDelta dt)
        //systems.update<QuestSystem>(dt); // doesn't do anything
        systems.update<WeatherSystem>(dt);
        systems.update<ParticleSystem>(dt);
+       systems.update<AttackSystem>(dt);
 }
 
 
index bcde3886d8a8319f265656aca808d16c697f307f..0a854595483a5ec751e6921e1a859bbe3a86397e 100644 (file)
@@ -5,6 +5,7 @@
 #include <gametime.hpp>
 #include <world.hpp>
 #include <particle.hpp>
+#include <attack.hpp>
 
 static const char *spriteXML =
        "<Sprite> \
@@ -70,6 +71,7 @@ static const char *animationXML =
 void PlayerSystem::create(void)
 {
        player = game::entities.create();
+       player.assign<Player>();
        player.assign<Position>(0.0f, 100.0f);
        player.assign<Direction>(0.0f, 0.0f);
        //player.assign<Physics>(-0.001f);
@@ -198,6 +200,8 @@ void PlayerSystem::receive(const KeyDownEvent &kde)
        } else if (kc == SDLK_t) {
                game::time::tick(50);
        }
+       if (kc == SDLK_j)
+               game::events.emit<AttackEvent>(vec2(loc.x, loc.y), AttackType::ShortSlash);
 }
 
 vec2 PlayerSystem::getPosition(void) const
index 5e33b92a194fced698674de9671f3bf851be97ff..fb690860c50ce04bb6d4e621ce68ebd0a372f6d2 100644 (file)
@@ -62,7 +62,7 @@
                </frame>
        </Sprite>
        <Direction />
-       <Health />
+       <Health value="200" />
        <Solid />
        <Physics />
        <Name value="SKIRL" />