Skip to main content
GameDev.net gamedev.net
🔒 Locked

Implementing a State....

Started by gameplayprogammer Oct 18, 2008 at 7:15 AM 5 replies 1.1k views
Original Post
gameplayprogammer
gameplayprogammer
I have a class Object that can go into four states during my game. In each of these states i need to call some of the Objects methods. For example, in StateAttack, my object constantly looks around for something to move close to and attack. Am i meant to pass a pointer to the Object into each of the states? Check out my code sample and comments for exactly what i mean. BTW Object can not be a singleton, as i will have many instances.


class Object
{
some methods
some members
void Update(float dt);
std:vector<State*> states;
}

void Object::Update(float dt)
{
   for(all states)
      state->Update(dt); 

// here is my problem, the state class will know nothing about class Object
// so it cannot 
}

// assume StateAttack is derived from some base State class
void StateAttack::Update(float dt)
{
// does not have access to class Object's
// members or methods so cannot implement the effects
// of the state on class Object
// how do you get round this? pass a reference of or a pointer?
// are you meant to update class Object's here

}


AAA
AAA
The simplest solution would be to change StateAttack::Update to:

void StateAttack::Update(Object& obj, float dt)

and pass in your object.
ToohrVyk
ToohrVyk
"A state" cannot exist. You always speak of "The state of something": the state of the union, the state of affairs, the state of the art, and so on. It seems that you have forgotten to make "of something" an essential part of your state implementation.

As such, if you have "the state of object X", it should be fairly straightforward to have that state manipulate object X. In this case, X should be a constructor argument to each state class.

Basiror
Basiror
This sounds a lot like a circular dependency problem

1. Object is in some state of class State or some derivative
2. Some instance of class State shall be responsible for actions of instances class Object

So you delegate the objects responsibility to another object.

I would keep these states object internal using a switch statement

Or do you plan to use them for several derivatives of class Object?

http://www.8ung.at/basiror/theironcross.html
gameplayprogammer
gameplayprogammer
AAA - i thought about that but isn't that just moving code from class Object into the State classes. Not sure thats what i want.
ToohrVyk - same as above but a better implementation i think.

i already have all the states of the object handled internally like so...

void Object::UpdateStateAttack(float dt)
{
// update attacking

}

Basiror - i was trying to convert this behavior to a state machine because thats a way of structuring code in games.

problem is doing something like...

void StateAttack::Update(Object& obj,float dt)
{
obj->UpdateStateAttack(dt);
}

or...

void StateAttack::Update(Object& obj,float dt)
{
// here you would put the contents of Object::UpdateStateAttack(float dt)
// directly
}

seems wrong design...

i just want an object to own it's states of behaviour and change between them using a state machine structure.

i think the solution is to make class State's friend's of class Object?

Wyrframe
Wyrframe
Think of it not as a state, but a mindset. Your "StateAttack" is an "AggroState".
class AggroState: public State {public:   virtual void update(Entity& actor, float dt) {     // Query actor for its surroundings (it queries its surroundings for other entities)     // Search its surroundings for a creature unallied with the actor     // Move the actor towards the target.     // If close enough to attack, do so.   };};class Entity {public:   shared_ptr<State> state;   void setBrain(shared_ptr<State> aState)      { state = aState; }   void update(float dt) {      if ( state.isValid() )         state->update(*this, dt);   }};


One key aspect of this is that setting specific targets and tasks would be a constructor argument of your mindsets. To have entities obey larger-scope goals, let your entity keep a stack of states, update the one on top of the stack, and have states pop themselves off the stack if they deem themselves unaccomplishable or complete.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
Basiror
Basiror
If you handle it like Wyrframe your states are actually callbacks that define the behaviour of your objects.

So your objects are just an "abstract data type" that holds the information, that defines the state of an object.

Thats how I handle my entities. I associate each entity type with a table of functions names that define the behaviour and upon an event I lookup if there exists a handler for that specific event and execute the function.


The event handlers are lua scripts in my case.
Each handle that changes the state of an entity simple applies the changes to its attributes.

Setting up the function table during initialization corresponds to ToorVyks suggestion I think.



http://www.8ung.at/basiror/theironcross.html

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.