I'm with Disch regarding the spawning. I've used a method based on timing with a restriction on the number of baddies presently in play to control spawning rates flexibly enough.
I have what I think is a good method for the pathing of enemies.
A path can have an arbitrarily complex shape when assembled in sections (or legs). I create a class hierarchy of legs with different shapes, one class for a straight line, another for circular arcs, parabolic arcs, etc. The leg::move() is therefore virtual. A path is assembled in a linked list fashion, with each leg having a pointer to the next leg of the path (and perhaps the previous leg in doubly link list fashion if you desire motion in either direction along the path).
Each leg class has at least 2 constructors. One ctor is for the 1st leg on the path and takes arguments specifying all parameters for the leg. For the straight line leg it would take both end points as arguments (and assign pLegNext = NULL). For a circular arc leg this ctor takes the start point, center point and the angle through which the leg sweeps.
The 2nd ctor takes a pointer to the previous leg on the path as an argument so the legs can be joined (use the endpoint of the previous leg as the start point of the leg being constructed), and so the linkage can be assigned ( prevLeg->pLegNext = this; ). This ctor also takes the leg endpoint as an argument.
I create a config file with arguments for all legs on all paths to be constructed for the game. From this file I create a vector<leg*>. In a config file for the enemies I provide an unsigned int as index to the 1st leg for its path in the vector<leg*>. Finally, the leg::move() returns a leg* to the leg the enemy is currently on. It returns a pointer to the next leg of the path when the end of the current leg is reached. The enemy::move() therefore calls the leg::move() like so:
1 2 3 4 5
|
enemy::move()
{
if( pLeg ) pLeg = pLeg->move(s, x, y);// this keeps pLeg updated. pLeg is a member of the enemy class.
// other code for frame animation, etc...
}
|
The parameter 's' is owned by the enemy for its position on the leg and x,y is the enemy position. These are passed by reference to leg::move() so they may be updated.
As an example, a closed oval path with a leg for bringing the enemy on screen would be constructed of 5 legs. The "entry leg" links to the 1st straight leg, which links to the 1st semi-circular leg, which links to the 2nd straight leg, which links to the 2nd semi-circular leg, which links finally back to the 1st straight leg.
This description isn't complete, but I hope it gives you some good ideas.
EDIT: Description of leg::move() code.