Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

BACKGROUND:

My World class that is responsible for updating the physics for each object in the game contains a std::vector of Rigidbody classes.

As Rigidbodies are added to the world, they are also added to a gravityforcegenerator (gravity) and a dragforcegenerator (drag).

Every Update call on the world (every frame), both the gravity class and drag class call Update which calls ApplyImpulse on each Rigidbody they know about, then the world calls Update on each Rigidbody which calculates acceleration, velocity, position, etc.

World Update:

void World::Update(double deltaTime) {

    class UpdateObjects {
    public:
        UpdateObjects(double deltaTime) : _deltaTime(deltaTime) { }
        void operator()(RigidBody* elem) {
            elem->Update(_deltaTime);
        }
    private:
        double _deltaTime;
    };

    _gh->Update(deltaTime);
    _dh->Update(deltaTime);

    if(_objects.empty()) return;
    std::for_each(_objects.begin(), _objects.end(), UpdateObjects(deltaTime));

}

Gravity Update:

void GravityForceGenerator::Update(double /*deltaTime*/) {
    class UpdateObject {
    public:
        UpdateObject(const Vector2D& gravity) : _gravity(gravity) { }
        void operator()(RigidBody* elem) {
            elem->ApplyImpulse((_gravity * elem->GetGravityModifier() * elem->GetMass()));
        }
    private:
        Vector2D _gravity;
    };

    if(_subscribers.empty()) return;
    std::for_each(_subscribers.begin(), _subscribers.end(), UpdateObject(_gravity));

}

Drag Update:

void DragForceGenerator::Update(double /*deltaTime*/) {
    class UpdateObject {
    public:
        UpdateObject(const std::pair<double, double>& drag_coefficients) : _dc(drag_coefficients) { }
        void operator()(RigidBody* elem) {
            Vector2D force = elem->GetVelocity();

            double dragCoeff = force.GetLength();
            if(a2de::Math::IsEqual(dragCoeff, 0.0)) return;
            dragCoeff = _dc.first * dragCoeff + _dc.second * dragCoeff * dragCoeff;

            a2de::Vector2D::Normalize(force);
            //NEWTONS!!
            force *= (-dragCoeff / 1000.0);
            //KILONEWTONS!!
            elem->ApplyImpulse(force);
        }
    private:
        std::pair<double, double> _dc;
    };

    if(_subscribers.empty()) return;
    std::for_each(_subscribers.begin(), _subscribers.end(), UpdateObject(_coefficients));

}

THE PROBLEM:

As a simple example (it can get way more complicated than this; area-based triggers, for example), if a custom class is composed of a Sprite and a Rigidbody:

class TestClass {
    public:
        /*...*/
        Sprite* GetSprite() { return _image; }
        Rigidbody* GetBody() { return _body; }
        void Update(double deltaTime) {
            _body->Update(deltaTime);
            _image->SetPosition(_body->GetPosition());
        }
        /*...*/
    private:
        /*...*/
        RigidBody* _body;
        Sprite* _image;
};

The update method of the game must do the following:

TestClass* t;
World* _world;

void Initialize() {
    /*...*/
    t = new TestClass();
    _world->Add(t->GetBody());
    /*...*/
}

void Processing(gameTime, deltaTime) {
    /*...*/
    _world->Update(deltaTime);
    t->Update(deltaTime);
    /*...*/
}

void Render(gameTime, deltaTime) {
    /*...*/
    Draw(t->GetSprite());
    /*...*/
}

I tried to get around this problem by declaring an IUpdatable interface but then the gravity and drag classes fail because they must call the ApplyImpulse method which would make no sense in a Update interface.

Would re-designing the world class to accept a base abstract Object class that all objects must derive from be a valid solution or is that just pushing the problem one level further down?

THE QUESTION:

What refactor or re-design would you recommend to allow the world class to accept ANY object?

share|improve this question
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.