entity system
TRANSCRIPT
Scott Bilas, GDC 2002
Unity Cocos2d-x ...Cocos2d-x 3.0 alpha
Warrior,Goblin,Player... Scene
MVCEntity Component System
Game ObjectGameObject
AItree bullet monster player hero
GameObject
GameObjectGameObject
GameObject ID, GameObject.Find()GameObject
( )getChildByTag(), GameObject.Find()
Game Object System
?
( )
boss
helper
root-heavy blob pattern
hard coding database
Collision
AnimationAI
Render
Path finding
Input
ID
IDRender
Collision
AI
Path finding
Animation
Input
Entity Component System
EntityEntity ID
UI
class Entity:public Object { public: typedef std::string entity_id_type; static Entity* createWithId(const entity_id_type& id); const entity_id_type& getId(){return _id;} bool operator==(const Entity& entity){return _id==entity._id;} private: Entity(); Entity* initWithId(const entity_id_type& id); private: entity_id_type _id; };
ComponentComponent Entity
health, heromove
, render, collision, AI, move, gun, input...
class ECSComponent:public Object { protected: ECSComponent(const std::string& type); public: inline const std::string& getType() const{return _type;} private: std::string _type; };
ship
monster
bullet
helper
hero
level
healthcollisiongunscriptrendermovement ....
Entity Component Grid
EntityManager/** Manage all entity ids, and it's components */ class EntityManager:public Object { public: EntityManager(); ~EntityManager(); entity_id_type generateNewEid(); Entity* createEntity(); void removeEntity(Entity* entity); void addComponentToEntity(ECSComponent* component,Entity* entity);
/** an entity only can own one instane of some kind of component */ ECSComponent* getComponentForEntity(const std::string & eId,Entity* entity); /** get all entities which contain some kind of component. */ const std::vector<Entity*>* getAllEntitiesPosessingComponent(const std::string& cId); private: std::vector<Entity*> _entities; std::map<std::string, std::map<Entity*, ECSComponent*>*> _componentsByType; //for quick find entities every frame. std::map<std::string, std::vector<Entity*>*> _componentEntities; int _lowestUnassignedEid; };
SystemSystemSystemSystem Entity EntityCollisionSystem, AISystem, MoveSystem, InputSystem, BattleSystem,
CameraSystem... Code...
class ECSSystem:public Object { protected: ECSSystem(); void initWithManager(EntityManager*); public: virtual void configure(){}; virtual void update(float dt){}; protected: EntityManager* _entityManager; };
ECS(Byte56 stackoverflow)
System ( )
Calculations collision detection
Collision
Render
CollisionSystemPosition
Entity ( )
Entity ID: 88 Entity
Collision
Render
CollisionSystem Id 88 Entity
Position
void CollisionSystem::update(float dt) { Array* entities=_entityManager->getAllEntitiesPosessingComponent(CollisionComponent::COLLISION_TYPE); if(!entities) return; int count=entities->count(); //记录两个Entity之间是否已执⾏碰撞检测 int haveCollision[count][count]; for (int i=0; i<count; i++){ //碰撞主体 Entity* entity=(Entity*)entities->getObjectAtIndex(i); RenderComponent* render=(RenderComponent*)_entityManager->getComponentForEntity(RenderComponent::RENDER_TYPE, entity); if(!render) continue; //可能与之发⽣碰撞的主体 for (int j=0; j<count; j++) { if (haveCollision[j][i]==1||i==j) { continue; } Entity* collisionEntity=(Entity*)entities->getObjectAtIndex(j); RenderComponent* collisionRender=(RenderComponent*)_entityManager->getComponentForEntity(RenderComponent::RENDER_TYPE, collisionEntity); if(!collisionRender) continue; //发⽣碰撞 if (collide(render->getNode(), collisionRender->getNode())) { //标记已处理两个特定Entity haveCollision[i][j]=1; CollisionEvent* event=new CollisionEvent(entity,collisionEntity); EventDispatcher::getInstance()->dispatchEvent(event); } } } }
Collision
Render
Position
System
Renderentity1entity2entity3
Collisionentity1entity2entity3
Moveentity1entity2entity3
Move
Health
Render
Move
Health
EntityManager ComponentSystem
GameEngineLoop
Entity SpriteEntity SystemgetChildByTag GameObject.FindSystem Component Sprite tag name
ID NameEntity UI UI
UI Sprite UI
System
EventDispatcherGunEvent, DeadEvent,CollisionEvent…
Systemconfigure EventDispatcher
thisECS
Cocos2d-x 3.0 alpha
SystemSystem
thisEntity
CCCalFuncNC++11 lambda
DemoEntity( Render ship ghost)
ghost MoveComponentghost GunComponent
girlCocosd-x 3.0 alpha
http://github.com/elvisqin/entitysystem
ECSSystemUI
mouse touch
ECS EventDispatcher
Unity GameObject name
( )
prefabUI
Unity
<?xml version="1.0"?><entity> <Render> <Sprite>Ghost/ghost.png</Sprite> </Render> <Health> <curHP>20</curHP> <maxHP>20</maxHP> </Health> <Move></Move> <Collision/> <Ghost/> <Gun> <distance>100</distance> <targetType>ship</targetType> </Gun></entity>
Entity* unit = _entityManager->createEntity(); _entityManager->addComponentToEntity(RenderComponent::create(unitSprite), unit); //UI _entityManager->addComponentToEntity(HealthComponent::create(20,20),unit); //⽣命值 _entityManager->addComponentToEntity(MoveComponent::cretae(ship->getPosition(),1), unit); //可移动 _entityManager->addComponentToEntity(CollisionComponent::create(), unit); //可碰撞 _entityManager->addComponentToEntity(HitComponent::create(ShipComponent::SHIP_TYPE, 10), unit); //碰撞攻击伤害及⺫标 _entityManager->addComponentToEntity(GhostComponent::create(), unit); //单位类型 _entityManager->addComponentToEntity(GunComponent::create(ShipComponent::SHIP_TYPE, 1000, 0.2), unit);
System Entitystd::map size
EntityManagerSystem Entity(Unity )Cocos2d-x 2.1.2 CCNode
EventDispatcher
Entity SystemSprite Kit , …
2.5D
C++ Style STL lamdaGUI
LabelCocoStudiomore…
Cocos2d-x 3.0
thanks&enjoy