Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Veritas

Pages: [1]
1
SFML projects / Veritas Framework
« on: June 19, 2014, 04:41:37 pm »
Hello everyone! Although this project is not directly related to sfml, I thought that it may be useful to the community.

Veritas is a C++ framework that I have been working on for some time and it's design is
based on the entity-component-system software architecture pattern.

It's goal is to provide a flexible core that allows for fast implementation of features while keeping maintenance to the minimum.

Although the framework is by no means completed yet (the messaging system is not yet completed and the code needs some polishing), for those interested the source can be found at GitHub.
Also, since this is my first serious project (and the first time I'm using GitHub), any feedback is largely appreciated!

Documentation and examples should be finished within a few weeks due to the exams not having finished yet.

2
Python / sf.Keyboard.is_key_pressed() expensive?
« on: June 08, 2014, 10:15:15 pm »
I was wondering, is sf.Keyboard.is_key_pressed() expensive?
My tests lag considerably when there are 70+ controllable objects at a time (about 300 calls).
The profiler showed that 90% of the time was spent in the is_key_pressed() function so either I am doing something wrong or the function is expensive (after many calls that is).

3
General / Framework Design Advice
« on: June 05, 2014, 08:51:25 am »
Hello everyone,

As some of you may already know, I spent some time designing a small game framework
in order to help me with my future projects. Unfortunately, because of the
university entry exams, I didn't really have a lot of time to spend on it.

Now that the exams are almost finished I thought I should start working seriously on
the actual design of the framework. I did make a prototype but C++ didn't prove that great for prototyping.
I am now making a prototype in Python and I will port it to C++ if the performance proves inadequate.

My goal is not to make a framework with incredible performance. What I want to achieve is a core which will allow me to easily implement features, without worrying about dependencies and coupling while also keeping the maintainable code to the minimum.

I have settled on a self-registration entity-component system where the entities register to the systems according to the components that they hold. All the registration functionality should remain hidden and the user should only have to provide a registration condition for each system.

Here is a small example in Python:

import veritas_framework as vf

class TestComponent:
    pass

class TestSystem(vf.System):
    def registration_condition(self, entity):
        return entity.has_component(TestComponent) # Take note that we use the type here
    def update(self, delta=0):
        for entity in self.entities:
            print "updated"

engine = vf.Engine()
test_system = TestSystem()
engine.add_to_systems(test_system) # Here we use the object
engine.add_to_pipeline(test_system)

entity = vf.Entity(engine) # The entity will signal the engine when it updates it's components

engine.update() # Nothing happens

test_comp = TestComponent()
entity.add_component(test_comp) # Passing an object again

engine.update() # Prints "updated"

entity.remove_component(TestComponent) # Here we use the type

engine.update() # Nothing happens

What I am having troubles with is small inconsistencies in the design.
We actually pass the objects when we add a system or a component but we use the types
to remove them or test if they exist.

This is because both the engine and the entity classes should only
keep 1 object per system or component type accordingly. I think this is not obvious with the current design.

One way to solve this is to actually use the type when we add a system/component and the function would return
the created object for further manipulation, however I am not sure whether this is acceptable .

Any help is much appreciated!

~Veritas

4
General / error: no type named value_type in class sf::Rect<int>
« on: May 07, 2014, 02:12:58 pm »
When I try to make a vector of sf::IntRects I get the error :

no type named value_type in class sf::Rect<int>

Here is the code:

class Animation
{
public:
        explicit Animation(float);
        void addFrame(sf::IntRect);
        void play();
        void pause();
        void reset();
        void stop();
        void update(float);
        const sf::IntRect& getFrame() const;
private:
        std::vector<sf::IntRect> m_frames;
        float m_duration;
        bool m_playing;
        float m_index;
};

Animation::Animation(float duration) :
        m_frames(),
        m_duration(duration),
        m_playing(true),
        m_index(0)
{
}

void Animation::addFrame(sf::IntRect frame)
{
        m_frames.push_back(frame);
}

void Animation::play()
{
        m_playing = true;
}

void Animation::pause()
{
        m_playing = false;
}

void Animation::reset()
{
        m_index = 0;
}

void Animation::stop()
{
        reset();
        pause();
}

void Animation::update(float dt)
{
        if (m_playing)
        {
                m_index += dt/m_duration;
                if (m_index >= m_frames.size())
                {
                        m_index = 0;
                }
        }
}

const sf::IntRect& Animation::getFrame() const
{
        return m_frames[m_index];
}

Can someone point out what's wrong?

5
General / Laggy rendering.
« on: May 03, 2014, 10:45:21 pm »
Hello everyone. I finished my game engine's prototype today and I decided to test it by making a rectangle and moving it by the arrow keys. Unfortunately the rendering lags noticeably. I believe this is a result of my engine's pipeline so I may have to explain how it works:

-GameObjects are containers of Components and hold a pointer to the Engine.
-Components are containers for data. Each component holds different types of data.
-The Engine is a container of Systems.
-Systems are containers of GameObjects.

Now every time we add a Component to the GameObject, it checks the requirements for the different systems and registers to them.
Each System has an update() function where the logic is kept. The pipeline goes through all the Systems consequently and calls their update() function.

For my example I do:

void World::run()
{
        sf::RenderWindow window(sf::VideoMode(1024, 768), "Testing");

        Engine engine;
        auto PIS = engine.addSystem<PlayerInputSystem>();
        PIS->window = &window;
        engine.addSystem<MovementSystem>();
        auto RS = engine.addSystem<RenderingSystem>();
        RS->window = &window;

        GameObject player(engine);
        player.addComponent<PlayerInputComponent>();
        player.addComponent<MovementComponent>();
        player.addComponent<VelocityComponent>();
        auto GC = player.addComponent<GraphicsComponent>();
        GC->sprite.setSize(sf::Vector2f(100,10));
        GC->sprite.setPosition(sf::Vector2f(0,0));

        sf::Clock clock;
        float elapsed;
        while (window.isOpen())
        {
                elapsed += clock.restart().asSeconds();
                while (elapsed > 1/60.f)
                {
                        engine.update(1/60.f);
                        elapsed -= 1/60.f;
                }
                RS->update();
        }
}

Here are the Components:

class VelocityComponent : public Component
{
public:
        sf::Vector2f velocity;
};

class MovementComponent : public Component
{
public:
        sf::Vector2f movement;
};

class PlayerInputComponent : public Component
{
        /* No need to add anything here */
};

class GraphicsComponent : public Component
{

public:
        sf::RectangleShape sprite;
};
 

And here are the Systems:

class PlayerInputSystem : public System
{
public:
        bool registration_condition(GameObject*);
        void update(float);
        sf::RenderWindow* window;
};

bool PlayerInputSystem::registration_condition(GameObject* object)
{
        return (object->hasComponent<PlayerInputComponent>().first &&
                object->hasComponent<VelocityComponent>().first );
}

void PlayerInputSystem::update(float dt = 0)
{
        for (auto &object : registered_objects)
        {
                auto velocity = object->getComponent<VelocityComponent>();
                velocity->velocity.x = 0;
                velocity->velocity.y = 0;
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                {
                        velocity->velocity.x = -500;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                {
                        velocity->velocity.x = 500;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                {
                        velocity->velocity.y = -500;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                {
                        velocity->velocity.y = 500;
                }
        }
}

//*****************************************************************************************************

class MovementSystem : public System
{
public:
        bool registration_condition(GameObject*);
        void update(float);
};

bool MovementSystem::registration_condition(GameObject* object)
{
        return (object->hasComponent<MovementComponent>().first &&
                object->hasComponent<VelocityComponent>().first );
}

void MovementSystem::update(float dt = 0)
{
        for (auto &object : registered_objects)
        {
                auto velocity = object->getComponent<VelocityComponent>();
                auto delta = object->getComponent<MovementComponent>();
                delta->movement.x = velocity->velocity.x * dt;
                delta->movement.y = velocity->velocity.y * dt;
        }
}

//******************************************************************************************************

class RenderingSystem : public System
{
public:
        bool registration_condition(GameObject*);
        void update(float);
        sf::RenderWindow* window;
};

bool RenderingSystem::registration_condition(GameObject* object)
{
        return (object->hasComponent<MovementComponent>().first &&
                object->hasComponent<GraphicsComponent>().first );
}

void RenderingSystem::update(float dt = 0)
{
        window->clear();
        for (auto &object : registered_objects)
        {
                auto delta = object->getComponent<MovementComponent>();
                auto graphics = object->getComponent<GraphicsComponent>();
                graphics->sprite.move(delta->movement);
                window->draw(graphics->sprite);
        }
        window->display();
}

The engine is by no means finished. It pretty much works with pointers everywhere and I would like to add Systems that don't take part in the pipeline. I hope I am doing something wrong with the game loop or else I may have to do way more work than I can handle atm.

EDIT: Wrong forum section again. Can this be moved to the help section?

6
General / Logic in components vs logic in systems?
« on: May 01, 2014, 09:56:39 pm »
Hello everyone, I did some research on the different practices and patterns used in game development and I settled on a composition system where the different components communicate using messages that the container-GameObject distributes.

For instance say that I press the attack key. The playerInput component sends an AttackMessage to all the other components using the notify function of the GameObject. The Weapon component picks the message, sets some local variables and sends a RigidBodyStateMessage to the RigidBody component which in turn sends another message containing the rotation and position of the GameObject. The Weapon component catches the message and instantiates a bullet using the information passed in the message.

Communication between different objects is achieved via messages sent in message buses on which the GameObjects have registered. For example, the PhysicsComponent continuously sends messages to the CollisionBus which are then delivered to the registered GameObjects for collisionDetection in the appropriate component.

This approach allows for complete decoupling between the components but I am not sure if it may create any long-term problems. Some people also told me that components shouldn't have any logic in them and that they should only keep data which will be processed in the appropriate systems. I was wondering what advantages the latter method would have compared to the one that I am currently using. Sorry for the wall of text, I am writing from my phone. Any help is much appreciated!

7
General / State Machine to handle player actions?
« on: April 25, 2014, 12:55:45 pm »
So far I've been making some small example games using a command system to handle input. Depending on the input a command simply gets sent to the target and changes it's attributes. Now I was wondering how I could handle cases where the input behaves differently in different contexts. For example the arrow keys could make the character run after a certain time of being pressed, different action buttons could be chained to make combos etc. You can't handle that directly using commands. So I thought that a hierarchical state machine would work pretty well in this case. I am not sure what the responsibility of commands would be though. Should they be used simply to create a layer of indirection and give all the responsibility of handling the input to the state manager or should they still retain some elements of control on the player's actions?

8
General / Graphical Representation and Animations.
« on: April 23, 2014, 03:13:11 pm »
Lately I've been trying to separate graphics from logic on my game and so far things are looking good. One thing I am not sure how I should deal with is storing animation states and accessing them using a command system. How I am going about animations is that I have an Animation class that stores sf::IntRects which I use on the renderer to choose the correct part of the needed texture. In the beginning I thought that having an animation object as an attribute of the entity class would be ok since it's just a state and it doesn't contain actual graphical information. Something like this:

class Entity
{
public:
        Entity(sf::Vector2f, float);
        virtual ~Entity() = 0;

        void setPosition(sf::Vector2f);
        void setPosition(int, int);
        void move(sf::Vector2f);
        void move(int, int);
        sf::Vector2f getPosition() const;

        void setVelocity(sf::Vector2f);
        void setVelocity(int, int);
        void accelerate(sf::Vector2f);
        void accelerate(int, int);
        sf::Vector2f getVelocity() const;

        void setRotation(float);
        void rotate(sf::Vector2f);
        void rotate(float);
        float getRotation() const;
       
        Animation& getAnimationState() const;
        void update(float);
private:
        Animation mAnimation;
        sf::Vector2f mPosition;
        sf::Vector2f mVelocity;
        float mRotation;
};

This is how the basic drawEntity function works (it's the base for more specific drawing functions providing the texture files) :

void Renderer::DrawEntity(const Entity& entity, const char* file)
{
        sf::Texture& texture = mResourceManager.getTexture(file);
        texture.isSmooth();
        sf::Sprite sprite;
        sprite.setTexture(texture);
        sprite.setTextureRect(entity.getAnimationState().getCurrentFrame());
        sprite.setPosition(entity.Position);
        sprite.setRotation(entity.Rotation);
        mRenderWindow.draw(sprite);
}

Technically, storing an animation object to the entity class makes sense since it simply holds a state, however after exchanging some messages with Nexus I am having doubts whether I should store the actual animation object or use the pimpl idiom and store a pointer to it. Another option is to store the animation objects in a separate map but that probably complicate things.

Is the above an acceptable design and if not, how should I proceed ?
Any feedback is much appreciated!

9
General / Problem building SFML after updating to ubuntu 14.04
« on: April 20, 2014, 07:27:12 pm »
Hello everyone, I decided to change to the new LTS version of Ubuntu and thought I may as well do a complete cleanup .That included completely removing SFML. Ok so I say it's no big deal, I will just get the source and compile it again. I don't seem to be able to even configure cmake-gui though. I put the source folder to my home folder, I specify the build folder but I get :

Error in configuration process, project files may be invalid

Any help is much appreciated!

10
So I started reading the sfml development book to look at the possible structure of a game and to gain some more knowledge of the sfml library. There are some points in the book that I don't understand WHY they chose to implement something in a particular way. An example is the resource class in the beginning of the book. When I looked at it something struck me as weird but I didn't realize what it was until a fellow stack overflow member reminded me that the [] operator of the std::map container creates an object if the key doesn't exist.

The book's implementation:

template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename)
{
        std::unique_ptr<Resource> resource(new Resource());
        if (!resource->loadFromFile(filename))
        {
                 throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);
        }
        auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
        assert(inserted.second);
}
 

Another possible implementation:

template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename)
{
        assert(mResourceMap.find(id) == mResourceMap.end());
        if (!mResourceMap[id].loadFromFile(file))
        {
                mResourceMap.erase(id);
                throw std::runtime_error("ResourceHolder::load - Failed to load " + file);
        }
}
 

Are there any advantages in the book's implementation?

EDIT: Just noticed that this is the help section's general category.

11
General / Will sfml be updated using c++11 features?
« on: April 18, 2014, 02:50:13 pm »
It feels that some classes (like most resources) could make great use of the move semantics introduced with the c++11 standard. Are there any plans to update the classes so they include move constructors?

12
General / Am I implementing acceleration and movement correctly?
« on: April 10, 2014, 03:02:08 pm »
Hello everyone, this is the first time I'm writing to this forum and the first time I'm trying to make a game using c++ so I apologize in case I am oblivious to some known game development concepts. Anyway the first thing I tried to address was movement handling. Instead of having to litter the main procedure with variables, I thought I should make a wrapper class possibly deriving from the sprite class in order to handle movement and general functions better.
Below is a small example-class showing what I came up. Is this a good approach for general movement? The real class will of course address other things like collision and camera view but I would like some feedback first to see if this is a good approach. Take note that I'm using the 1.6 library because of some technical reasons and since this is an educational project I thought it shouldn't matter much. In the example I'm also deriving from the Shape class since I don't really need any of the Drawable class functionalities.

Here is the main file:

#include <SFML/Graphics.hpp>
#include "Object.h"

int main(int argc, char** argv) {
   
    double frt;
    sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML Graphics");
    sf::Event Event;
    Object Rect = sf::Shape::Rectangle(0, 0, 10, 10, sf::Color::Red);
    Rect.bottomBoundary(590);
    Rect.rightBoundary(790);
    Rect.gravity(500);
    Rect.SetPosition(0,590);
    Rect.onGround(true);
    while (App.IsOpened()) {
       
        frt = App.GetFrameTime();

        if (App.GetInput().IsKeyDown(sf::Key::Left)) {
            if (Rect.horizontalSpeed() == 0) {
                Rect.horizontalSpeed(-5);
            }
            Rect.acceleration(-500);
        }
        else if (App.GetInput().IsKeyDown(sf::Key::Right)) {
            if (Rect.horizontalSpeed() == 0) {
                Rect.horizontalSpeed(5);
            }
            Rect.acceleration(500);
        }
        else {
            if (Rect.horizontalSpeed() > 0) {
                Rect.acceleration(-500);
            }
            else if (Rect.horizontalSpeed() < 0) {
                Rect.acceleration(500);
            }
        }
           
        if (Rect.horizontalSpeed() < 0.10 && Rect.horizontalSpeed() > -0.10) {
            Rect.acceleration(0);
            Rect.horizontalSpeed(0);
        }

        if (App.GetInput().IsKeyDown(sf::Key::Up) && Rect.onGround()) {
            Rect.jump(590);
            Rect.onGround(false);
        }
     
        while (App.GetEvent(Event)) {

            if (Event.Type == sf::Event::Closed || Event.Key.Code == sf::Key::Escape) {
                App.Close();
            }
           
         }  

        Rect.updateMovement(frt);
        App.Clear();
        App.Draw(Rect);    
        App.Display();
    }

    return EXIT_SUCCESS;
}
 

And here is the wrapper class:

#include <SFML/Graphics.hpp>
#include "Object.h"
#include <math.h>

    Object::Object(const sf::Shape& other) :
        sf::Shape(other) , _gravity(0), _accel(0), _uBound(0), _bBound(0),
        _lBound(0), _rBound(0), _vSpeed(0), _hSpeed(0), _onGround(false) {}

    void Object::gravity(double gravity) {
        _gravity = gravity;
    }
    double Object::acceleration() {
        return _accel;
    }
    void Object::acceleration(double accel) {
        _accel = accel;
    }
    void Object::upperBoundary(double bound) {
        _uBound = bound;
    }
    void Object::bottomBoundary(double bound) {
        _bBound = bound;
    }
    void Object::leftBoundary(double bound) {
        _lBound = bound;
    }
    void Object::rightBoundary(double bound) {
        _rBound = bound;
    }
    void Object::verticalSpeed(double speed) {
        _vSpeed = speed;
    }
    void Object::horizontalSpeed(double speed) {
        _hSpeed = speed;
    }
    void Object::jump(double meters) {
        _vSpeed = -std::sqrt(2*_gravity*meters);
    }
    double Object::horizontalSpeed() {
        return _hSpeed;
    }
    double Object::verticalSpeed() {
        return _vSpeed;
    }
    bool Object::onGround() {
        return _onGround;
    }
    void Object::onGround(bool onGround) {
        _onGround = onGround;
    }
    void Object::updateMovement(double frt) {
        if (!_onGround) {
            _vSpeed += _gravity * frt;
        }
        if (GetPosition().y + _vSpeed * frt >= _bBound) {
            SetY(_bBound);
            _vSpeed = 0;
            _onGround = true;
        }
        if (GetPosition().y +_vSpeed * frt <= _uBound) {
            SetY(_uBound);
            _vSpeed = 0;
        }        
        if (GetPosition().x + _hSpeed * frt >= _rBound) {
            SetX(_rBound);
            _hSpeed = 0;
        }
        if (GetPosition().x + _hSpeed * frt <= _lBound) {
            SetX(_lBound);
            _hSpeed = 0;
        }
        _hSpeed += _accel * frt;
        Move(_hSpeed * frt, _vSpeed * frt);
       
    }
 

Pages: [1]