Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualppodsiadly

Posted 07 May 2013 - 07:31 AM

Recently I've been experimenting with component-based game objects. I came to conclusion that the best (for me) approach is to have a GameObject class which is just a container for class derived from IGOComponent. Creation and usage of a game object looks like this:

GameObject* go=world->createObject("Object's unique name");
go->addComponent(world->createComponent("Transform")); // position+rotation, written by the physics component, read, by the graphics component
go->addComponent(world->createComponent("Graphics"));
go->addComponent(world->createComponent("Physics"));
go->addComponent(world->createComponent("NPC AI"));
go->addComponent(world->createComponent("Health"));
go->initialise();

//...

IGOComponent* GameWorld::createComponent(const std::string& type)
{
	IGOComponentMgr* manager=m_managers[type];
	return manager->createComponent(type);	// one manager could handle several types, e.g. "NPC AI" and "Alien AI" would belong the the same manager
}

//...

void GameObject::initialise()
{
	for(IGOComponent* goc : m_components)
		goc->initialise(this); // setup "connections" between components in one game object
}

//...

void PhysicsComponent::initialise(GameObject* go)
{
	m_owner=go;
	m_transformGOC=go->component("Transform");	// components can communicate directly
}

//..

void PhysicsComponent::update()
{
	for(PhysicsComponent* comp : this->colliders())
	{
		GameObject* otherGO=comp->owner();
		if(otherGO->hasComponent("Bullet"))
		{
			BulletComponent* bt=(BulletComponent*)otherGO->component("Bullet");
			DamageMessage* msg=new DamageMessage();
			msg->causedBy=otherGO;
			msg->damage=bt->calcDamage();
			m_owner->sendMessage(msg);	// components can communicate also "indirectly", using messages. All components of "go" receive msg and can react to it.
		}
	}
}

This design was inspired by an article in Game Programming Gems, part 6.


#2ppodsiadly

Posted 07 May 2013 - 05:00 AM

Recently I've been experimenting with component-based game objects. I came to conclusion that the best (for me) approach is to have a GameObject class which is just a container for class derived from IGOComponent. Creation and usage of a game object looks like this:

GameObject* go=world->createObject("Object's unique name");
go->addComponent(world->createComponent("Transform")); // position+rotation, written by the physics component, read, by the graphics component
go->addComponent(world->createComponent("Graphics"));
go->addComponent(world->createComponent("Physics"));
go->addComponent(world->createComponent("NPC AI"));
go->addComponent(world->createComponent("Health"));
go->initialise();

//...

IGOComponent* GameWorld::createComponent(const std::string& type)
{
	IGOComponentMgr* manager=m_managers[type];
	return manager->createComponent(type);	// one manager could handle several types, e.g. "NPC AI" and "Alien AI" would belong the the same manager
}

//...

void GameObject::initialise()
{
	for(IGOComponent* goc : m_components)
		goc->initialise(this); // setup "connections" between components in one game object
}

//...

void PhysicsComponent::initialise(GameObject* go)
{
	m_owner=go;
	m_transformGOC=go->component("Transform");	// components can communicate directly
}

//..

void PhysicsComponent::update()
{
	for(PhysicsComponent* comp : this->colliders())
	{
		GameObject* otherGO=comp->owner();
		if(otherGO->hasComponent("Bullet"))
		{
			BulletComponent* bt=(BulletComponent*)otherGO->component("Bullet");
			DamageMessage* msg=new DamageMessage();
			msg->causedBy=otherGO;
			msg->damage=bt->calcDamage();
			go->sendMessage(msg);	// components can communicate also "indirectly", using messages. All components of "go" receive msg and can react to it.
		}
	}
}

This design was inspired by an article in Game Programming Gems, part 6.


#1ppodsiadly

Posted 07 May 2013 - 03:39 AM

Recently I've been experimenting with component-based game objects. I came to conclusion that the best (for me) approach is to have a GameObject class which is just a container for class derived from IGOComponent. Creation and usage of a game object looks like this:

GameObject* go=world->createObject("Object's unique name");
go->addComponent(world->createComponent("Transform")); // position+rotation, written by the physics component, read, by the graphics component
go->addComponent(world->createComponent("Graphics"));
go->addComponent(world->createComponent("Physics"));
go->addComponent(world->createComponent("NPC AI"));
go->addComponent(world->createComponent("Health"));
go->initialise();

//...

IGOComponent* GameWorld::createComponent(const std::string& type)
{
	IGOComponentMgr* manager=m_managers[type];
	return manager->createComponent(type);	// one manager could handle several types, e.g. "NPC AI" and "Alien AI" would belong the the same manager
}

//...

void GameObject::initialise()
{
	for(IGOComponent* goc : m_components)
		goc->initialise(this); // setup "connections" between components in one game object
}

//...

void PhysicsComponent::initialise(GameObject* go)
{
	m_owner=go;
	m_transformGOC=go->component("Transform");	// components can communicate directly
}

//..

void PhysicsComponent::update()
{
	for(PhysicsComponent* comp : this->colliders())
	{
		GameObject* otherGO=comp->owner();
		if(otherGO->hasComponent("Bullet"))
		{
			BulletComponent* bt=(BulletComponent*)otherGO->component("Bullet");
			IGameMessage* msg=new DamageMessage();
			msg->causedBy=otherGO;
			msg->damage=bt->calcDamage();
			go->sendMessage(msg);	// components can communicate also "indirectly", using messages. All components of "go" receive msg and can react to it.
		}
	}
}

This design was inspired by an article in Game Programming Gems, part 6.


PARTNERS