I peaked at your code and did a quick run. Based on the point of view being more from the side than above, do you need pathfinding?
You could use a hidden sprite to detect when they are in range, and move them to appropriate locations, having them battle there.
You could also probably use a function to handle moving/battling and simply have them continue moving after toward their target, and when they overlap with say a spawnpoint/base, have them perform a different action (aka attack a base).
Otherwise I would check debug mode and see what's taking the most cpu cycles.
Also, regarding improving AI, the event -overlapping another object- can trigger a bunch of different options, maybe with a random function to perform a different attack, like something stronger than a basic attack, or using an ability. If you don't prefer random, you could add an instance variable that adds up over time/attacks performed that then executes the other actions you want to add.
Smarter AI can be anything from extra actions, and performing actions based on state, so for example, low hp, or when another unit dies.
Thanks for the answer.
What would you put in place of pathfinding?
I put pathfinding because of the obstacles that the scenario will have, and also for the units do not stay one on top of the other.
Now for the functions I do not have much experience with them, I will read the documentation and try to do what I said
And the AI I wanted to say was: the units meet intelligently - eliminate the enemy - if there is more enemy in their reach, go to it, otherwise continue to the enemy base.