Defining a new entity class in C++

Defining the entity class and its properties

Class declaration

Let's have a look at the declaration (typically stored in a .h file): To keep it simple we define just three properties for the Light entity: “enabled”, “diffuse colour”, and “position”. Furthermore we override two event callbacks (onInitialise() and onTick()). In the class implementation we go into further detail of the underlying implementations.

class Light : public Entity
{
	YAKE_DECLARE_ENTITY(Light)
public:
	OBJECT_PROPS_BEGIN(Light)
		OBJECT_PROP("diffuseColour", Color, Color(1,1,1,1))
		OBJECT_PROP("position", Vector3, Vector3(0,0,0))
		OBJECT_PROP("enabled", bool, true)
	OBJECT_PROPS_END()
protected:
	Light();
	virtual void onInitialise(object_creation_context& creationCtx);
	virtual void onTick();
};

Class implementation

For this example it would be enough to use the define and implement the constructor. We override the onTick() and onInitialise() methods just to show how it's done.

YAKE_DEFINE_ENTITY_1( Light, Entity )
 
Light::Light()
{
}
void Light::onTick()
{
	Entity::onTick(); // <- Don't forget to inherit base entity class' functionality!
	// Custom code here...
}
void Light::onInitialise(object_creation_context& creationCtx)
{
	Entity::onInitialise(creationCtx); // <- Again!
	// Custom code here...
}

Defining the visual component for the entity

The concepts are quite similar to defining an entity itself.

Class declaration

class LightVisual : public EntityComponent
{
	YAKE_DECLARE_ENTITY_COMPONENT( LightVisual, "light.visual" );
protected:
	virtual void onInitialise(object_creation_context& creationCtx);
	virtual void onTick();
private:
	SharedPtr<graphics::ISceneNode>		mpSN;
	graphics::ILight*			mpLight;
	bool					mLightEnabled;
};

Class implementation

Register component:

YAKE_REGISTER_ENTITY_COMPONENT( LightVisual );

Constructor:

LightVisual::LightVisual( Entity& owner ) :
	EntityComponent( owner ),
	mpLight(0),
	mLightEnabled(false)
{}

The initialisation code (including basic error handling):

void LightVisual::onInitialise(object_creation_context& creationCtx)
{
	EntityComponent::onInitialise(creationCtx);
	//if (!isServer())
	{
		YAKE_ASSERT( creationCtx.mpGWorld );
 
		// Create a graphics::ILight object.
		mpLight = creationCtx.mpGWorld->createLight();
		YAKE_ASSERT( mpLight );
 
		// Create a graphics::ISceneNode object for moving our light around.
		mpSN.reset( creationCtx.mpGWorld->createSceneNode() );
		YAKE_ASSERT( mpSN.get() );
 
		mpSN->attachLight( mpLight ); // Attach the light to the scene node.
 
		// Configure the light (type, colour ...)
		mpLight->setType( graphics::ILight::LT_POINT );
		mpLight->setDiffuseColour( Color(1,0,0) );
		mpLight->setEnabled( true );
 
		getOwner().getProperty("enabled")->setValue(true);
 
		mpSN->setPosition( Vector3(0,20,0) );
	}
}

Each tick we update the Light entity's properties to the graphics light object. This is just one possible implemenation. Another approach would be to do this every frame (onFrame()) or via an event or callback/signals based system. Everything's possible.

For each property we check whether the values has actually changed. If it has, we update the visual component's graphics objects accordingly and reset the properties' “dirty” flags.

void LightVisual::onTick()
{
	// position
	Property* pProp = getOwner().getProperty("position");
	YAKE_ASSERT( pProp );
	if (pProp->hasChanged())
	{
		YAKE_ASSERT( mpSN );
		if (pProp && mpSN)
			mpSN->setPosition( pProp->getValueAs<Vector3>() );
		pProp->setHasChanged( false );
	}
	// enabled
	pProp = getOwner().getProperty("enabled");
	YAKE_ASSERT( pProp );
	if (pProp->hasChanged())
	{
		YAKE_ASSERT( mpLight );
		if (pProp && mpLight)
			mpLight->setEnabled( pProp->getValueAs<bool>() );
		pProp->setHasChanged( false );
	}
	// colour
	pProp = getOwner().getProperty("diffuseColour");
	YAKE_ASSERT( pProp );
	if (pProp->hasChanged())
	{
		YAKE_ASSERT( mpLight );
		if (pProp && mpLight)
			mpLight->setDiffuseColour( pProp->getValueAs<Color>() );
		pProp->setHasChanged( false );
	}
}
 
tutorials/ent/custom/init.txt · Last modified: 2008/02/21 21:59 (external edit)
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki