Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

281 Neutral

About Krankles

  • Rank
  1. Hi, I'm reading up on ECS on t-machine and other places, but now I'm trying to implement my own simple ECS. I'm stuck on trying to convert https://github.com/adamgit/Entity-System-RDBMS-Inspired-Java from Java to C++. In the EntityManager, he has a variable called componentStores which is defined as  HashMap<Class, HashMap<Integer, ? extends Component>> componentStores; However, I don't know the equivalent of this in C++.   So far, I've been able to create and generate entity ids, but I don't know how to actually add the component to the entity in a map. In the hashmap above, what types of data is it containing? Also, the second hashmap inside the hashmap, is the "? extends Component" supposed to be a pointer to a given Component? For example, I made a PositionComponent, would the hashmap contain a pointer to the PositionComponent? And, what is the point of the first data type "Class?" Sorry if this doesn't make sense, I don't fully understand what's happening, but the big question is how can you convert the hashmap into C++?   My entity header file looks like this: #ifndef ENTITY_MANAGER_H #define ENTITY_MANAGER_H #include <map> #include <vector> #include <cstdint> #include <iostream> #include <algorithm> class EntityManager { public: EntityManager(); ~EntityManager(); uint32_t create_entity(); void kill_entity(uint32_t id); private: std::vector<uint32_t> entity_list; uint32_t assignable_entity_id; uint32_t generate_entity_id(); }; #endif and this is my EntityManager source file #include "EntityManager.h" EntityManager::EntityManager() : assignable_entity_id(1) { }; EntityManager::~EntityManager() { }; uint32_t EntityManager::create_entity() { uint32_t id = generate_entity_id(); if (id < 1) { // throw error return 0; } else { entity_list.push_back(id); return id; } } uint32_t EntityManager::generate_entity_id() { if (assignable_entity_id < UINT32_MAX) { std::cout << "Generated ID: " << assignable_entity_id << std::endl; return assignable_entity_id++; } else { for (unsigned int i = 1; i < UINT32_MAX; i++) { std::vector<uint32_t>::iterator it = std::find(entity_list.begin(), entity_list.end(), i); if (*it != i) { std::cout << "Generated ID: " << i << std::endl; return i; } } // throw error return 0; } } void EntityManager::kill_entity(uint32_t id) { std::vector<uint32_t>::iterator it = entity_list.begin(); for (; it != entity_list.end(); it++) { if (*it == id) { std::cout << "Killing Entity: " << *it << std::endl; entity_list.erase(it); return; } } }  Any help would be greatly appreciated, thanks.
  2. Thanks for the descriptive answers guys! I think I got it now.
  3.   I see! This makes a lot of sense, thanks. And yeah, I should probably learn more of C++ before I start doing this. However, I have a quick question. What if you wanted separate functionality for a specific entity that operates within the same system? Should you just create a new system entirely? Or possibly check if it's a specific entity and run that code inside the system? For example, I have a JumpSystem and the player could double jump but the enemy can't, should you create a new DoubleJumpSystem? Or should you just check within the JumpSystem for the player entity? Or another example to possibly clear the question up, what if I have an AnimationSystem and the 2 different entities animate differently, should it just check for a specific entity or create a new system?   Thank you.
  4. Sorry for the triple post! But, ignore what I said earlier, I was being stupid. I think I got a good system going. I need to know if this is how a decent ECS should work though, or even if this is a good basis. I took out the Render component and replaced it with Velocity and Position instead, as I find it much easier to start out with. #include "Entity.h" #include "PositionComponent.h" #include "VelocityComponent.h" #include "MovementSystem.h"   int main(int argc, char const* argv[]) {     MovementSystem movementSystem;       Entity player;     player.AddComponent(new PositionComponent(2, 2));     player.AddComponent(new VelocityComponent(5, 5));       for (int i = 0; i < 10; i++) {         movementSystem.ProcessEntity(&player);     }       return 0; } That's basically how everything works, I create a movement system, entity, add components to the entity and then use the system to process my entity. I don't know whether or not this is how ECS works or not, but it seems right to me.   MovementSystem.h #ifndef MOVEMENT_SYSTEM_H #define MOVEMENT_SYSTEM_H   #include "EntitySystem.h" #include <vector>   class VelocityComponent; class PositionComponent;   class MovementSystem : public EntitySystem {     public:         MovementSystem();         ~MovementSystem();           void ProcessEntity(Entity* entity);       private:         VelocityComponent* velocityComponent;         PositionComponent* positionComponent; };   #endif MovementSystem.cpp #include <iostream> #include "Entity.h" #include "MovementSystem.h" #include "PositionComponent.h" #include "VelocityComponent.h"   MovementSystem::MovementSystem() {   }   MovementSystem::~MovementSystem() {   }   void MovementSystem::ProcessEntity(Entity* entity) {     positionComponent = dynamic_cast<PositionComponent *>(entity->GetComponent("position"));     velocityComponent = dynamic_cast<VelocityComponent *>(entity->GetComponent("velocity"));       positionComponent->SetX(positionComponent->GetX() + velocityComponent->GetVelocityX());     positionComponent->SetY(positionComponent->GetY() + velocityComponent->GetVelocityY());     std::cout << "Player X: " <<  positionComponent->GetX() << std::endl; } That's how my movement system works, but I was wondering if there's anything I could improve my system on?
  5. So I've been researching even more, and I am confused a bit now. Should the System know how to do a function? Or should the Component know how to do a function? For example, JumpComponent and JumpSystem, should the System know how to Jump? Or should the Component know how to jump? I'm confused because I've read that the component should just contain the data, etc, and the system should handle the components. However, in some people's implementations, I've seen them having the component having the data and knowing how to do something, and the system should just have a list of components, and make them interact with each other.   Also, I've been thinking, for my RenderComponent and RenderSystem -- to make it work -- should I have the Render function inside my RenderComponent, and then have the RenderSystem loop through all of the RenderComponents and call the respective Render function?   Not only that, but I was also thinking that for my problem earlier, I could possibly fix the problem by using my newly created RenderSystem by passing in the component pointer to the RenderSystem component list and then be able to access the member named "image".   Lastly, I was wondering, why do people in their Entity class don't include the component header? I see them just doing "Class Component;" and that's it. (Sorry for the noob questions, I didn't fully learn C++, I learned the basics, learned some SDL and went on creating basic games. I also can't test this ideas right now because I'm busy with other things currently.)   Thanks.
  6.   My bad, I guess I got too used to it!   Anyways, thanks guys, I started my own attempt at ECS, but I'm having troubles connecting things together. This is what I have so far.   Entity.h #ifndef ENTITY_H #define ENTITY_H   #include <vector> #include <string> #include "Component.h"   class Entity {     public:         Entity();         ~Entity();           void AddComponent(Component *component);         Component* GetComponent(std::string name);         void Update();       private:         std::vector<Component*> components; };   #endif   Entity.cpp #include "Entity.h"   Entity::Entity() {   }   Entity::~Entity() {   }   void Entity::AddComponent(Component *component) {     components.push_back(component); }   Component* Entity::GetComponent(std::string name) {     for (unsigned int i = 0; i < components.size(); i++) {         if (name.compare(components[i]->name) == 0)             return components[i];     } }   void Entity::Update() {     for (unsigned int i = 0; i < components.size(); i++) {         components[i]->Update();     } }   BaseSystem.h #ifndef BASE_SYSTEM_H #define BASE_SYSTEM_H   class BaseSystem {     public:         BaseSystem();         virtual ~BaseSystem(); };   #endif   Component.h #ifndef COMPONENT_H #define COMPONENT_H   #include <string>   class Component {     public:         Component();         virtual ~Component();           std::string name;         virtual void Update(); };   #endif   RenderSystem.h #ifndef RENDER_SYSTEM_H #define RENDER_SYSTEM_H   #include <SDL2/SDL.h>   class RenderSystem : public BaseSystem {     public:         void Render(SDL_Renderer* renderer, SDL_Texture* image); };   #endif   RenderSystem.cpp #include "RenderSystem.h"   void RenderSystem::Render(SDL_Renderer* renderer, SDL_Texture* image) {     SDL_RenderCopy(renderer, image, NULL, NULL); }   RenderComponent.h #ifndef RENDER_COMPONENT_H #define RENDER_COMPONENT_H #include "Component.h" #include <SDL2/SDL.h> class RenderComponent : public Component { public:         RenderComponent();         ~RenderComponent();         SDL_Texture* image; }; #endif   RenderComponent.cpp #include "RenderComponent.h" RenderComponent::RenderComponent(){ name = "render"; }   So that's all I have right now, but I don't know if I'm even doing this right or not. Right now, I don't want to complicate anything, and just want a simple entity (background, player, what-have-you) to draw. Once I have that down, I believe I can implement the rest.   I need some help being guided in the right direction, I know my code might look like utter crap right now, but I'm just learning, so please bear with me. When I try creating an entity in my test program, I tried doing this: Entity background; background.AddComponent(new RenderComponent()); SDL_Surface *tmp_image = NULL; tmp_image = IMG_Load("gfx/background.png"); background.GetComponent("render")->image = SDL_CreateTextureFromSurface(renderer, tmp_image); But it says that "class Component" has no member named "image". Which is obvious, since it's not declared in the class Component, but in RenderComponent. How do I solve this? Or should I NOT be doing this?   Thanks.   EDIT: Basically what I'm asking is, is that how you correctly add a component? If so, then when I get my component, I want to be able to manipulate it, but it doesn't let me due to the class Component having no member named image. The list of components is an array of Components, which means I can't access the image variable. Also, how are systems supposed to work. I've been googling around and it's somewhat confusing. I feel like I'm doing this completely wrong.
  7. Hello, so I've made a couple of basic games in C++ and AS3, through the traditional object oriented way, and then I came across an article about Entity Component Systems on GameDev. Everything made a lot more sense than having a big hierarchy of classes, but as I try to research more about this on google and gamedev, I only find explanations on how it works (and very partial implementations). I can't wrap my head around getting the design to work.   I've seen previous threads that have some code in them, but I still don't quite understand it. Is there any existing tutorials, books, resources, etc, that I could read to further understand how it works? It'd also help immensely if there's code to go along with it, as I don't understand much without some code. Also, if anyone has made a simple game or basic system showing how it works, I'd be very interested in seeing your code, most preferably in C++ as well. Thanks.
  8.   Yeah I've started a little bit on OpenGL and used GLFW to create the window, context and listen for events. Also, what edition would you recommend me for Beginning OpenGL Game Programming?
  9.   I see. I'm curious, how did you learn modern opengl? How did you approach the arcsynthesis tutorials (if you did learn it from arcsynthesis)? Did you read it and then tested the source code? Or did you read and try to make your own demo?
  10.   I see, so start a bit of OpenGL from a web tutorial or something and learn the basics, then go for example, read OpenGL Programming Guide 8th Edition Version 4.3? I also read that this book also basically teaches 3.3 with little code having to be changed.
  11. Thanks, but just a quick question (probably a stupid one), how do you learn from these tutorials/books (for example, arcsynthesis) if they don't give you a small snippet of code and explain it? I'm looking at arcsynthesis and basically he just wants you to read the whole source code, which also has a framework in place, which I then need to scavenge for and read about how his framework works.   I'm sort of used to tutorials teaching things step by step and explaining snippets of code (coming from Flash). Also, I looked at the superbible and it teaches you their opengl wrapper instead of opengl until later into the chapters.
  12. Hi, I have a fairly good understanding of C++ and I made a couple of small little games in SFML. I decided to move onto OpenGL now and I was wondering whether I should pickup and get the OpenGL Programming Guide 8th Edition Version 4.3? I want your feedback on the book whether it's suitable for someone who's trying to learn OpenGL because I don't want to buy it, then find out that it's horrible and that I wasted my cash on it.   If this book is bad, then what are your suggestions to learning modern opengl? I dislike NeHe tutorials since they're old and deprecated. Also, if there's any other books that you suggest I should get then please leave a comment below or even a website to check out.   Thanks.
  13. Krankles

    To learn SDL 1.2 or 2.0?

    Unless someone is actually planning on targeting AmigaOS, then what does it matter? A feature you aren't actually going to use isn't a feature you should care about.   Here's the breakdown: SDL 1.2 claims: Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX SDL 2.0 claims: Windows XP, Windows Vista, Windows 7, Mac OS X 10.4+, Linux 2.6+, iOS 3.1.3+, Android 2.3.3+ SFML claims: Windows, Linux, Mac OS X and soon Android & iOS.   Basically, SFML claims the exact same platform support that SDL 2.0 claims (Windows, Linux, Mac). SDL 1.2 claims more than either (Only IRIX, QNX, and BeOS). Whether they actually function smoothly on those platforms are another matter... but that's what their websites claim, anyways.   Most of those groups probably chose SDL over SFML because SFML didn't exist at the time, not because they weighed the pros and cons between the two. SFML is very recent (2007), SDL is very old (1998), and alot of the well-known open source games that use SDL were created before SFML existed (or before SFML sufficiently matured). I'm not saying that newer is better, I'm just saying that older doesn't (in itself) mean better. If you prefer older libraries, Allegro (<1995) predates SDL by at least three years, and maybe more.   I'm not suggesting SFML over SDL. I'm suggesting you figure out what it is your current project needs, and then deciding which solution (SDL 1.2, SDL 2.0, SFML 1.x, SFML 2.0, Allegro, HGE, etc...) best fits those needs.   Your needs, as far as I understand, are: C++ Stepping stone towards OpenGL Cross platform for the following platforms: ??? Good documentation Decent tutorials Active community Stable code   Which APIs do and don't meet those requirements?     I see now, I forgot to mention that I wanted to target Windows, Mac, Linux and sometime later, Android and iOS. I didn't know that SFML will soon be able to target those last 2 platforms, and I see your point about projects not using SFML instead of SDL.   I think I'll stick with SFML, thanks.
  14. Hi, I'm deciding whether or not to learn SDL 1.2 or SDL 2.0 because I want to learn the API and create some games before moving onto OpenGL. I know SDL 2.0 is newer and is hardware accelerated, but there's not a lot of tutorials (at least updated ones) to learn from. Lazyfoo's tutorials are for version 1.2 and are generally the only recommended good tutorials to learn SDL.   I'm deciding to learn SDL, create a few games, come back, and render things in opengl instead of using SDL. I was deciding between SFML 2.0 and SDL 1.2 or 2.0 but the platforms supported in SDL is much bigger, and I felt it outweighed the difference between the two. Also, since a lot of indie and commercial game companies are using SDL, it seemed to be a better API to learn.   I'm learning SDL to start out with because I need more games created under my belt before I dive into OpenGL. Once I get better game concepts and stuff, I'll be then able to switch over to OpenGL for my rendering which will ease the process if I were to just start out with OpenGL and SDL and start to create games from there.   Thanks.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!