The EntitySpawned delegate allows custom code to react to an entity instance being created. For example a game may want to add an Entity to a custom list when spawned.
The following code assigns a custom EntitySpawned delegate which adds any created ball instance to the CustomBallList:
Factories must have their Initialize method called before they are used. In many cases the Initialize method is automatically called in Glue generated code. This article explores when the Initialize method is called for you and when you must call it yourself. The Initialize method also controls which list is populated by a factory. This article also discusses this, specifically as it applies to inheritance. For an in-depth look at using Factories, see the tutorial on "Created by Other Entities"
First we'll look at a very simple scenario. Consider an Entity called "Enemy". In this example, Enemy has its "CreatedByOtherEntities" set to true, meaning Glue will automatically generate a Factory called EnemyFactory. Let's say that there is also a Screen called GameScreen, and that GameScreen has a PositionedObjectList of Enemies. To summarize, if the following conditions are met, then Initialize will be called:
An Entity has CreatedByOtherEntities set to true
A Screen has a PositionedObjectList of the Entity mentioned in the previous point
Glue assumes that newly-created Enemies should be put in the PositionedObjectList in GameScreen (assuming GameScreen is the current Screen). In other words, the EnemyFactory can be used when GameScreen is live; the GameScreen will automatically call Initialize on the EnemyFactory. If GameScreen did not have a list of Enemies, Glue would not automatically Initialize the EnemyFactory. This means that if you intend to use EnemyFactory's CreateNew method in a Screen which does not contain a PositionedObjectList of Enemies, then you must manually call Initialize on EnemyFactory. Also, keep in mind that if you are manually calling Initialize, then you must manually call Destroy on the Factory. Destroy should probably be called in your Screen's CustomDestroy method.
PositionedObjectLists in Entities will not Initialize factories: Entities that include PositionedObjectLists of Entities that have an associated factory will not Initialize the factory. In this case you must either place a PositionedObjectList in your Screen, or you must manually call Initialize on the factory passing in the PositionedObjectList in your Entity. Therefore, if working with a Bullet object in an Entity, your code might look like this:
An Initialize call (whether in custom or generated code) will only put the Factory in a valid state for the given Screen. In other words, if GameScreen automatically calls Initialize on EnemyFactory, other Screens must still call Initialize (and Destroy) on EnemyFactory if your code calls EnemyFactory.CreateNew. The Initialize call expires at the end of the current Screen and must be called again (either manually or through generated code).
In the section above, we discussed that Glue will automatically generate code to call Initialize on a given Factory if the current Screen has a PositionedObjectList of the associated Entity. However, let's consider a more complicated situation: In this example we will use an Entity called Enemy which is the base Entity for three other Entities as shown in the following diagram:
Enemy
Orc
Dragon
Troll
We'll assume that Orc, Dragon, and Troll are all Entities which have matching Factories - that is, they all have CreatedByOtherEntities set to true. As mentioned above, if there is a PositionedObjectList of Orc, Dragon, or Troll, then the associated Factory will automatically have Initialize called. However, it is common to create PositionedObjectLists of base types to simplify custom code. In other words, GameScreen may have a PositionedObjectList of type Enemy. In this case, Glue also assumes that you intend to associate the List of the base type (Enemy in this example) with any of the derived types (Orc, Dragon, and Troll). Therefore, if you have a PositionedObjectList of Enemy, then OrcFactory, DragonFactory, and TrollFactory will all be initialized automatically. Also, they will be initialized using the PositionedObjectList of Enemies, so any Troll, Dragon, or Orc that you create will be put in that list.
Next let's look at a situation where there are three entities in an inheritance chain:
Enemy
Dragon
RedDragon
We'll assume RedDragon is an Entity that is CreatedByOtherEntities, so there is a RedDragonFactory. As explained above, RedDragonFactory will be automatically Instantiated in a Screen if:
The screen includes a PositionedObjectList of type Enemy
-- OR --
The Screen includes a PositionedObjectList of type RedDragon
But what if the Screen only contains a PositionedObjectList of Dragon (the type "inbetween" Enemy and RedDragon)? In this situation, Glue does not assume you intend to have the RedDragonFactory instantiated. Glue will only automatically instantiate the RedDragonFactory if there is a PositionedObjectList of the most base Entity (Enemy in this case) or most derived (RedDragon in this case) in a given Screen. However, you can still customize how the behavior of the Factory works using the EntitySpawned Action and manually adding newly-created Entities to any List.
If your screen contains multiple lists of the same type, Glue will generate code to add entities to all lists. For example, if your game has an entity called Enemy and you have two lists (GroundEnemies and AirEnemies), then any Enemy factory (or factory of entity deriving from Enemy) will insert into both lists. A list can be removed from automatic association with a factory in Glue (this requires GLUX version 3 or greater). This value is true by default, but can be set to false to prevent Glue from automatically associating any factories with the list.
Factory-List association can also be adjusted in code by calling RemoveList. To remove the lists from the factory:
The CreateNew function is used to create a new instance of the Entity corresponding to the calling factory. In simple cases, the only requirement is simply calling this method an a new instance will be created and available for use in your code. For information on CreateNew in the context of a tutorial, see .
This code assumes that your project has an Entity called "Enemy" and that it has a corresponding Factory:
Usually entities which are created with factories are created on some condition. Examples include:
Reacting to input. For example, the player presses a button to shoot a bullet.
Reacting to a collision event. For example, the player collides with a trigger to spawn an item.
Reacting to time condition. For example, an enemy spawner creates an enemy once every 10 seconds.
The following code shows how to create a bullet whenever the user presses the space bar.
The CreateNew method also takes a Layer argument. This layer specifies which Layer the created object should be a part of. Entities are usually created in Screen custom code or in the custom code of other Entities.
If you are creating an Entity through a Factory in a Screen, then you can pass the Layer which you would like the newly-created Entity to be a part of in the CreateNew method. This will usually be a Layer which is a part of the Screen (usually created through Glue). The following code assumes a Layer called HudLayer:
If this is not the case, then the creating Entity must have reference to the Layer which is to be used. You may need to set this reference up purely in custom code.
The term "Factories" comes from the . Factories are objects for creating new instances of certain types of Entities. Factories provide the following benefits:
Entities created in a factory are automatically added to screen lists (by default).
Factories provide a standard way to create entities which is especially useful for systems like Tiled to instantiate new entities.
Factories can pool Entities which can greatly reduce allocated memory for Entities which are created and destroyed frequently. For more information see the property.
If your game requires the creation of entities in code (such as the player shooting bullets or enemies appearing at an enemy spawn point), then factories are usually the answer.
When adding a new entity, the Create Factory checkbox is automatically checked. In most cases this should be left as true since most entities should be created by factories so they can be properly added to their corresponding lists (usually in GameScreen).
To use a factory in code, use the CreateNew method when you would like to create a new entity. For example, you can create an Enemy instance in the CustomInitialize of your screen as shown in the following code:
The SortAxis property can be set if a factory is associated with a PositionedObjectList which should remain sorted (typically for performance reasons). By default the SortAxis is null, so no sorting will be performed on insertion.
The code example below assumes the following:
An entity named Entity with the CreatedByOtherEntities value set to True:
A screen with an Enemy list:
The following code in the GameScreen.CustomInitialize method will result in a sorted list of enemies:
This code produces results shown in the following image:
The SortAxis property is null by default. It is reset to null whenever the factory has its Destroy method called. Factories are typically destroyed when a screen is destroyed. Therefore, if SortAxis is assigned to a non-null value in a Screen (such as in CustomInitialize ), this SortAxis value will persist until that Screen is destroyed. This behavior allows multiple screens to use different SortAxis values for the same factory. It also allows the same screen to use different SortAxis values for different levels to improve partitioning efficiency.
SortAxis results in a factory inserting instances of newly-created entities into the target list so that the list is always sorted. While this increases the amount of time that each individual insert takes, it removes the requirement to call a sort function after-the-fact (which can be expensive on large, unsorted lists) This can provide a small performance boost.
If the Entity that is being instantiated through the Factory is to be on the same Layer as the Entity calling the code, then the can be used:
If you are calling CreateNew you may see an exception indicating that you must call Initialize before using the factory. . If you are seeing this exception it means that the factory that you are trying to use when calling CreateNew has not yet been initialized. If you've used factories before then you may be thinking "I never had to call Initialize before, why do I have to now?" Initialize will automatically be called for you if you are using a Screen which contains a list of the given Entity type, and if that list was created through Glue. In other words, if you have an Entity called Bullet, and a factory called BulletFactory, then BulletFactory will automatically be initialized if your game is currently in a Screen which has a list of Bullets added to it in Glue. If you do not have a list of the given object type, but you want to instantiate that object at runtime, then you will manually need to call Initialize on the factory. For more information about Initialize, see .
If you have unchecked this option, you can add factories after an entity is created. For more information, see the .
Glue automatically generates factories for any entity which has its Created by Other Entities property set to true. For information on this property, see the page.