#include "timer.h"
// Creates a template so multiple objects can use this class.
template <class T>
class AIState
{
private:
T* object; // The object being controlled.
public:
// Executed when state is entered.
virtual void enter( Timer& time ) =0;
// Called when the the object is updated.
virtual void execute( Timer& time ) =0;
// Exectue when the state is exited.
virtual void exit( Timer& time ) =0;
};
But something hit me. I want the program to automatically know when a new instance of AIState is created and add it to a pool of already defined AI routines without anyone accessing the Enemy class or any other class (besides main). The problem is, I have no idea how to do this.
The problem extends further than that. I want my AI to be hard-defined for each level, I want the same AI executed for the 1st enemy, the 100th enemy, etc.
Thanks.
Flexible AI implementation question.
I'm creating a simple, side-scrolling shooting game. I have about three attacks already defined right in the Enemy class. However, something hit me. What if I handed the code off to someone so they can come up with all the routines?
I researched this and came up with one solution, a state machine. I'm using this template class as a base for all AI routines:
You could add a static variable to the class:
AIState{ static bool instance_count_chaged; };
bool AIState::instance_count_changed;
This could be set to true in the AIState constructor and the destructor. Then when whoever needs to know about it does their thing, it could be reset to false.
Or if the action is only going to happen on construction/destruction of an AIState object which will be auto-added to the pool, then it might make more sense to have the pool object handle all creation/destruction of AIState objects. It has to know about AIState objects already, in order to store them.
[Edited by - AngleWyrm on April 1, 2008 10:07:05 PM]
AIState{ static bool instance_count_chaged; };
bool AIState::instance_count_changed;
This could be set to true in the AIState constructor and the destructor. Then when whoever needs to know about it does their thing, it could be reset to false.
Or if the action is only going to happen on construction/destruction of an AIState object which will be auto-added to the pool, then it might make more sense to have the pool object handle all creation/destruction of AIState objects. It has to know about AIState objects already, in order to store them.
[Edited by - AngleWyrm on April 1, 2008 10:07:05 PM]
--"I'm not at home right now, but" = lights on, but no ones home
Quote: Original post by os3330
I want the program to automatically know when a new instance of AIState is created and add it to a pool of already defined AI routines without anyone accessing the Enemy class or any other class (besides main).
Are you expecting states to be created at compile time, application start-up/initialisation or during runtime?
Presumably all states will be known at compile time, a subset of useable states will be determined during initialisation (typically from config files) and usage of states will be determined during runtime. If you expect something different, please indicate.
Yes, I want the program to know every single AI routine at runtime (so it doesn't need to compile). I see that config files can help, but I have no idea how to implement that.
What you're describing is the separation of game logic from game code. This is a very good thing to do. There are a variety of ways to do this with differing levels of abstraction and complexity. For example, you could work out all of the possible behaviours that NPCs could have at compile time and use runtime config files to assign specific behaviours to certain NPCs. Alternatively you could provide a scripting interface to your game code and then code all of your AI in the script language (which is then interpreted at runtime).
The former has far less flexibility and may actually prove harder to implement in the long term. The latter will have a higher initial overhead as it requires the inclusion of a scripting interface and then designing AI within that scripting language.
If I were you I would start out simple. Design everything to be known at compile time. Get a working FSM-based AI going. You'll need to provide different instantiations of the AI for different enemy types, but you can also abstract much of this away using the State pattern you have presented above. Then work out how to abstract the logic away into a separate layer... then tansfer this to an external layer that can be read at runtime. Finally you'll be in a position to understand what parts of the AI can be managed in an external script and which parts are just internal components to be manipulated by the script.
(The short summary of the end result: you'll end up with a system where the event handlers for your AIState class are scripted externally and the internal mechanisms just manage the triggering of these handlers)
The former has far less flexibility and may actually prove harder to implement in the long term. The latter will have a higher initial overhead as it requires the inclusion of a scripting interface and then designing AI within that scripting language.
If I were you I would start out simple. Design everything to be known at compile time. Get a working FSM-based AI going. You'll need to provide different instantiations of the AI for different enemy types, but you can also abstract much of this away using the State pattern you have presented above. Then work out how to abstract the logic away into a separate layer... then tansfer this to an external layer that can be read at runtime. Finally you'll be in a position to understand what parts of the AI can be managed in an external script and which parts are just internal components to be manipulated by the script.
(The short summary of the end result: you'll end up with a system where the event handlers for your AIState class are scripted externally and the internal mechanisms just manage the triggering of these handlers)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement