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

Author Topic: S2DEC: A entity component game engine in C++  (Read 13441 times)

0 Members and 1 Guest are viewing this topic.

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
S2DEC: A entity component game engine in C++
« on: August 14, 2015, 07:56:32 am »
https://github.com/S2DGames/S2DEC

I have been working on this engine on and off for a while now. I mainly use it for game jams but I haven't really made any noteworthy games with it yet. I always seem to end up working on the engine more than the game whenever ludum dare comes around. Anyways back on topic.

I finally feel like the engine is at a point where someone else might be interested in using it if they knew about. So I'm not going to put off posting here any longer.

S2DEC is a 2d game engine that uses an entity component system for game objects and also utilizes box2d for physics.

I will edit this post tomorrow with a small tutorial because it is nearly 2am and I have to get up for work tomorrow. For now you can look in the game folder for am idea of how it works.  https://github.com/S2DGames/S2DEC/tree/master/S2DEC/Games pong is the best example in there. Snake runs like crap once you get a lot of segments and space invaders is not done or really even started.

Edit:
Here is a short overview of my engine. To use it, first create a game object passing the resolution and the window title like this
Game game(1920, 1080, "Game title");
Next you can either initialize  the game which will open the window,
game.init();
or change other settings such as tell the game to open full screen
game.setFullScreen();
Once we have the window set up the way we want, before or after initializing the window, we need to add our game objects to the game.

We do this by creating an entity
Entity& entity = game.createEntity("entity name");
and add a component with
entity.addComponent<SampleComponent>(/*paramaters to pass to the component constructor*/);
Here is the code for sample component which is just a box that moves around the screen depending on what arrow key you press.
#pragma once

#include "Game.h"

using namespace S2D;

class SampleComponent : public Component{
private:
        //stuff for box2d.
        b2Body* body{nullptr};
        b2BodyDef bodyDef;
        b2PolygonShape shape;
        b2Fixture* fixture{nullptr};
        b2Vec2 velocity{0.0f, 0.0f};

        sf::RectangleShape image;

        sf::Vector2f size;
public:
        SampleComponent(sf::Vector2f size) : size(size){
               
        }

        /**
        * Called when this component is added to an Entity.
        */

        void init() override{
                //////////////////////////set up physics stuff////////////////////////////
                bodyDef.type = b2_dynamicBody;
                //start off in the center. note that we need to use this function to convert the window coordinates to physics world coordinates
                bodyDef.position = sfTob2(game->getView().getCenter());
                //Here we are using the same function on a single number as apposed to a vector
                shape.SetAsBox(sfTob2(size.x / 2.0f), sfTob2(size.y / 2.0f));
                //create the body
                body = game->CreateBody(&bodyDef);
                //we dont need this now but if this body were to collide with something, you need to set the user data so it is notified viea a callback function
                body->SetUserData(this);
                body->SetFixedRotation(true);
                //create the fixture.
                //a body does not have a shape unless it has a fixture
                fixture = body->CreateFixture(&shape, 1.0f);
                fixture->SetFriction(0.0f);
                fixture->SetRestitution(1.0f);

                //////////////////////////set up image stuff///////////////////////////////
                image.setSize(size);
                movesfTob2(image, body);
        }

        /**
        * Called once every frame.
        */

        void update(float frameTime) override{
                //check keyboard keys. There are 4 states,
                //KEY_PRESSED   - The key was just pressed
                //KEY_HELD              - The key was pressed and is still being pressed
                //KEY_RELEASED  - The key was just released
                //NOT_PRESSED   - The key is not pressed and has not just been released
                if(game->getKeyState(sf::Keyboard::Up) != NOT_PRESSED){
                        velocity.y -= 1.0f;
                }
                if(game->getKeyState(sf::Keyboard::Down) != NOT_PRESSED){
                        velocity.y += 1.0f;
                }
                if(game->getKeyState(sf::Keyboard::Left) != NOT_PRESSED){
                        velocity.x -= 1.0f;
                }
                if(game->getKeyState(sf::Keyboard::Right) != NOT_PRESSED){
                        velocity.x += 1.0f;
                }

                //set the velocity of the physics body
                body->SetLinearVelocity(velocity);

                //update the image position
                movesfTob2(image, body);
                //reser the velocity back to 0 so it only moves when a button is being pressed
                velocity = {0.0f, 0.0f};
        }

        /**
        * Called once every frame.
        */

        void draw(sf::RenderTarget& target) override{
                //lastly draw the image
                target.draw(image);
        }
};

Calling
game.play();
will begin running the main loop of the game and will update and draw all objects that were added to the game. In this case, there is only one. You can also set the z of an entity which will determine the order it is drawn.
« Last Edit: August 15, 2015, 02:15:11 am by mashedtatoes »

Satus

  • Guest
Re: S2DEC: A entity component game engine in C++
« Reply #1 on: August 14, 2015, 11:16:27 am »
Hey, nice code. I also finished implementing something similar to this a few days ago, so it was very interesting to compare my code with yours. Though I have a 'System' class in my version, but didn't implement any Events yet (I'm still thinking if I need them at all).
I will borrow some pieces of your code, if you don't mind.
Some minor suggestions: make ResourceManager a template, remove using std::X and collision detection from Component (not all entities may need it).
Also, do you use Box2D only for collision detection?
And why do you have 'draw' method inside Component? Isn't it for Entity?
« Last Edit: August 14, 2015, 11:20:26 am by Satus »

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: S2DEC: A entity component game engine in C++
« Reply #2 on: August 14, 2015, 11:17:13 am »
Hm. Not 100% sure, but seems like your "components" are more like the actual entities (or a combination of components and systems)? Or did I misunderstand something?

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: S2DEC: A entity component game engine in C++
« Reply #3 on: August 14, 2015, 02:37:27 pm »
Also, do you use Box2D only for collision detection?
And why do you have 'draw' method inside Component? Isn't it for Entity?

For the first part, no? Kind of? I don't know. The collision detection is the result of using box2d but you also get all the physics stuff like linear velocity, angular velocity, acceleration, momentum, you can create joints to make things stick together or to make more complex moving parts. But right now, I am really only utilizing the collision detection. There is no real wrapper around the other stuff so you have to do it manually.

For the second part, the components are created by the person who uses the engine. So how else would you draw your sprites if you didn't have an overridable draw function in the component. The entity is a container of components so drawing an entity should just iterate through and draw all the components.

Hm. Not 100% sure, but seems like your "components" are more like the actual entities (or a combination of components and systems)? Or did I misunderstand something?

From what I understand the entity is just a container of stuff and the component/s are the stuff that do things. Maybe there is something more to it but that's the way I have been thinking about it for a while.

Satus

  • Guest
Re: S2DEC: A entity component game engine in C++
« Reply #4 on: August 14, 2015, 02:55:43 pm »
Quote
So how else would you draw your sprites if you didn't have an overridable draw function in the component.

I think user can create DrawableComponent inherited from Component, that will draw itself in update method or something like that.

Elias Daler

  • Hero Member
  • *****
  • Posts: 599
    • View Profile
    • Blog
    • Email
Re: S2DEC: A entity component game engine in C++
« Reply #5 on: August 14, 2015, 02:58:50 pm »
Making a DrawingSystem which iterates over all DrawableComponents is one way to go.
It's has one of the main advantages of using ECS: being able to use components independently from entities which they belong to.

(Note that this is just the way I like to do it, there is no "ideal" way)
Tomb Painter, Re:creation dev (abandoned, doing other things) | edw.is | @EliasDaler

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: S2DEC: A entity component game engine in C++
« Reply #6 on: August 14, 2015, 03:14:25 pm »
Hmm, so how would the actual thing that is going to be drawn be put into the DrawableComponent? And how would you update the position and things of that sprite.

being able to use components independently from entities

Can you explain this a little bit? I am not understanding it. You don't really use entities other than to update all the components right?

Satus

  • Guest
Re: S2DEC: A entity component game engine in C++
« Reply #7 on: August 14, 2015, 04:10:08 pm »
Quote
Hmm, so how would the actual thing that is going to be drawn be put into the DrawableComponent?

That is up to the programmer who implements the DrawableComponent to decide.

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: S2DEC: A entity component game engine in C++
« Reply #8 on: August 14, 2015, 04:21:35 pm »
So you are basically adding another layer but also removing a little bit from Component. I'm not sure I like that.

The thing I have been trying to do while making this engine is minimize the code required to use any part as much as possible. Actually my first iteration of the engine was a non entity component engine that attempted to split up everything into pieces like have a PhysicsObject, DrawableObject, ManagerObject.... and it was a nightmare. Creating objects was really cool because you could do something like
Object object<PhysicsObject, DrawableObject>();
and it would inherit those pieces. Then you would set the image and set up your physics stuff. But it was a pain to manage everything and I ran into a bunch of shortcomings that I couldn't get around. So i am trying to avoid splitting up things too much based off of that experience.

Satus

  • Guest
Re: S2DEC: A entity component game engine in C++
« Reply #9 on: August 14, 2015, 06:04:22 pm »
But it was a pain to manage everything and I ran into a bunch of shortcomings that I couldn't get around. So i am trying to avoid splitting up things too much based off of that experience.

Can you please provide more details about the problems you got? I am afraid I can face the same in near future.

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: S2DEC: A entity component game engine in C++
« Reply #10 on: August 14, 2015, 07:19:22 pm »
I think they were more of a result of the way I wanted to build game objects (like in my example). I used variadic templates to inherit different base classes. The biggest problem was with inter "component" communication. So essentialy my example would expand to something like this

public Object : public PhysicsObject, public DrawableObject...

Now, how do you go about moving the image to be in the same location as the physics body. You aren't writing the code in this class, it is being instantiated with the template parameters. Well you can put the position in a BaseObject class that all Objects will need to inherit then the physics object would modify this position and the image would pull from it. Because of that, you would not be able to have multiple images in an object or multiple physics objects either. It just got really restrictive and frustrating (to actually use to make a game with) not to mention it was not taking advantage of cpu caching nearly as much as data driven designs such as an entity component system does.

If you are using an entity component system and you are splitting up components successfully, then I say keep on working on it. You probably wont run into the same problems I was because I was trying to use variadic templates and template pack expansions and crazy c++11 features that I barely understood at the time.
« Last Edit: August 14, 2015, 07:22:40 pm by mashedtatoes »

Satus

  • Guest
Re: S2DEC: A entity component game engine in C++
« Reply #11 on: August 14, 2015, 07:44:31 pm »
If you are using an entity component system and you are splitting up components successfully, then I say keep on working on it. You probably wont run into the same problems I was because I was trying to use variadic templates and template pack expansions and crazy c++11 features that I barely understood at the time.

Thanks! That is reassuring.
By the way, why don't you use systems in you engine?

mashedtatoes

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: S2DEC: A entity component game engine in C++
« Reply #12 on: August 14, 2015, 08:31:57 pm »
Don't give me any ideas. I don't want a broken engine by the time Ludum Dare starts because I decided to add new features.

In all seriousness, what do you mean by systems?

JuDelCo

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
    • JuDelCo's Twitter
Re: S2DEC: A entity component game engine in C++
« Reply #13 on: August 14, 2015, 08:53:02 pm »
Probably he refers to make entities and components behaviour-free, holding on them only data and "systems" will have all (seriously, ALL) the game logic.

Like in Artemis framework (for example): https://github.com/vinova/Artemis-Cpp

Satus

  • Guest
Re: S2DEC: A entity component game engine in C++
« Reply #14 on: August 14, 2015, 09:29:41 pm »
Yes, that is exactly what I mean. ;)

 

anything