]> git.tdb.fi Git - libs/game.git/blobdiff - examples/bassteroids/source/physics.cpp
Convert components to buffered where appropriate
[libs/game.git] / examples / bassteroids / source / physics.cpp
index 67cdf6fe596bbf29199b7af96174c92eecaefc92..158b745ca83f6e0af19597e7fc7e4df9876e8365 100644 (file)
@@ -1,5 +1,5 @@
 #include "physics.h"
-#include <algorithm>
+#include <msp/core/algorithm.h>
 #include <msp/game/transform.h>
 #include "physicalentity.h"
 
@@ -8,9 +8,15 @@ using namespace Msp;
 
 Physics::Physics(Game::Stage &s):
        System(s),
+       event_source(stage.get_event_bus()),
        observer(stage.get_event_bus())
 {
+       declare_dependency<Game::Transform>(UPDATE);
+       declare_dependency<RigidBody>(UPDATE);
+       declare_dependency<Collider>(READ_OLD);
+
        observer.observe<Game::Events::EntityCreated>([this](auto &e){ entity_added(e); });
+       observer.observe<Game::Events::EntityDestroyed>([this](auto &e){ entity_removed(e); });
 
        stage.synthesize_initial_events(observer);
 }
@@ -35,6 +41,27 @@ void Physics::entity_added(const Game::Events::EntityCreated &e)
        }
 }
 
+void Physics::entity_removed(const Game::Events::EntityDestroyed &e)
+{
+       if(Game::Handle<PhysicalEntity> physical = dynamic_handle_cast<PhysicalEntity>(e.entity))
+       {
+               auto i = find_member(entities, physical, &SimulatedEntity::entity);
+               if(i!=entities.end())
+               {
+                       size_t index = distance(entities.begin(), i);
+                       if(index<fixture_count)
+                       {
+                               if(index+1!=fixture_count)
+                                       *i = std::move(entities[fixture_count-1]);
+                               entities[fixture_count-1] = std::move(entities.back());
+                       }
+                       else
+                               *i = std::move(entities.back());
+                       entities.pop_back();
+               }
+       }
+}
+
 void Physics::tick(Time::TimeDelta dt)
 {
        float dt_secs = dt/Time::sec;
@@ -59,6 +86,9 @@ void Physics::tick(Time::TimeDelta dt)
                copy_out<true>(entities[i]);
        for(unsigned i=fixture_count; i<entities.size(); ++i)
                copy_out<false>(entities[i]);
+
+       for(const Collision &c: collisions)
+               event_source.emit<Events::Collision>(entities[c.body1].entity->get_collider(), entities[c.body2].entity->get_collider());
 }
 
 template<bool is_fixture>