entity system

33
A Data-Driven Game Object System CDC 2013 ᑇช Soul Game http://elvisqin.me

Upload: elvisqin

Post on 15-Apr-2017

191 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Entity System

A Data-DrivenGame Object System

CDC 2013Soul Game

http://elvisqin.me

Page 2: Entity System

Scott Bilas, GDC 2002

Unity Cocos2d-x ...Cocos2d-x 3.0 alpha

Page 3: Entity System

Warrior,Goblin,Player... Scene

MVCEntity Component System

Page 4: Entity System

Game ObjectGameObject

AItree bullet monster player hero

GameObject

Page 5: Entity System

GameObjectGameObject

GameObject ID, GameObject.Find()GameObject

( )getChildByTag(), GameObject.Find()

Game Object System

Page 6: Entity System

?

Page 7: Entity System

( )

boss

helper

Page 8: Entity System

root-heavy blob pattern

hard coding database

Collision

AnimationAI

Render

Path finding

Input

Page 9: Entity System

ID

IDRender

Collision

AI

Path finding

Animation

Input

Page 10: Entity System

Entity Component System

Page 11: Entity 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; };

Page 12: Entity System

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; };

Page 13: Entity System

ship

monster

bullet

helper

hero

level

healthcollisiongunscriptrendermovement ....

Entity Component Grid

Page 14: Entity System

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; };

Page 15: Entity System
Page 16: Entity System

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; };

Page 17: Entity System

ECS(Byte56 stackoverflow)

Page 18: Entity System

System ( )

Calculations collision detection

Collision

Render

CollisionSystemPosition

Page 19: Entity System

Entity ( )

Entity ID: 88 Entity

Collision

Render

CollisionSystem Id 88 Entity

Position

Page 20: Entity System

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

Page 21: Entity System

System

Renderentity1entity2entity3

Collisionentity1entity2entity3

Moveentity1entity2entity3

Move

Health

Render

Move

Health

EntityManager ComponentSystem

GameEngineLoop

Page 22: Entity System

Entity SpriteEntity SystemgetChildByTag GameObject.FindSystem Component Sprite tag name

ID NameEntity UI UI

UI Sprite UI

Page 23: Entity System

System

Page 24: Entity System

EventDispatcherGunEvent, DeadEvent,CollisionEvent…

Systemconfigure EventDispatcher

thisECS

Cocos2d-x 3.0 alpha

Page 25: Entity System

SystemSystem

thisEntity

CCCalFuncNC++11 lambda

Page 26: Entity System

DemoEntity( Render ship ghost)

ghost MoveComponentghost GunComponent

girlCocosd-x 3.0 alpha

http://github.com/elvisqin/entitysystem

Page 27: Entity System

ECSSystemUI

mouse touch

ECS EventDispatcher

Page 28: Entity System

Unity GameObject name

( )

prefabUI

Unity

Page 29: Entity System

<?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);

Page 30: Entity System
Page 31: Entity System

System Entitystd::map size

EntityManagerSystem Entity(Unity )Cocos2d-x 2.1.2 CCNode

Page 32: Entity System

EventDispatcher

Entity SystemSprite Kit , …

2.5D

C++ Style STL lamdaGUI

LabelCocoStudiomore…

Cocos2d-x 3.0

Page 33: Entity System

thanks&enjoy