Enemy swarm inside a TArray

We don't want to stop to a single enemy, do we? It wouldn't be a great challenge... so we're going to create a list of enemies, so we can manage them even when there are more than one simultaneously on the map.

First of all, I want a way to spawn them randomly on the borders of the map; for this purpose, I'm going to create a line of hidden hexagons all around the map, something like this:


where the white tiles are the classic ones, and the gray ones will not be rendered, and will simply be used as starting "spawn coordinates" for the enemies.

At the moment, I'll do this by assigning them the value "2" in the tiles[][] array during the map creation, but later I'm going to save them in a map file, once we manage the loading of the maps from File System.

Next, I need a list of all active enemies in the map. The structucture I'm going to use is a TArray, that is a dynamic list of any object. This means we don't have to declare its size, but it can automatically shrink or enlarge as we need it.

This is the syntax for its declaration:

TArray<AenemyClass*> enemies;

This means we are creating a TArray of pointers to the class AenemyClass, amd its name will be enemies.

Then we can initialize it using the function Init():

enemies.Init(e1, 1);

Where I tell it to initialize itself with 1 copy of my object e1 (I created it here).

Now, to add other objects we can simply use the method Add():

enemies.Add(e2);

Where e2 is another enemy I'm spawning at a random location.

Now it's just a matter of substituting all the code where we used e1 with a simple cycle across our TArray. So, for example, this part:


will now become something like this:


The meaning of this bit of code is:

FOR  each element E inside the TArray ENEMIES:  if E exists, perform its method LOGIC.

That's it, we're now performing the same action for each element inside the TArray.

Particular attention must be paid to the method DestroyItems().

Removing objects inside an array while we're cycling in it is always dangerous, and Unreal will warn us with a red error in the log if we attempt to do so. A way around I used to avoid this is the following:


In the method DestroyItems I simply cycle through each element of the array and, if it has the flag destroy set to true, I destroy the object and I set its pointer inside the array to nullptr.
After the for loop I simply remove the elements that equal to nullptr. the method Remove() removes all objects that are equal to nullptr, so if i.e. 2 enemies must be destroyed in the same turn, this will correctly remove both of them.

Commenti