Sign in to follow this  

Game state manager??? (see last post please)

This topic is 3811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

See last post please How should a game state manager work... I'm having a really hard time understanding the methodology behind it. Zahlman gave me an example but I'm retarded or something so i didn't understand it. From how my (retarded eyes) see it was like this. Game class has all the functionality for linking two objects together... IE if we need to check for a monster/player collision the game class has a didCollide method... The inside the main game loop we create an event loop. magic message loop stuff --- dont understand askForTimerEventEvery(30 * MILLISECONDS) ---- dont understand while receiving events { event e = getEvent() switch(event types) type timer:game.update() type keypress:game.keypress() type refresh: game.draw() Can someone explain to me how such an event handler would work? (or have a link to an event handler they have used) I think it would be some sort of stack of events that push subclass events into it to be executed... Example abstract base class Event subclass TimedEvent(adds time into the event) ... subclass KeyDownEvent(adds keyboard reader/ processing) ... Do my questions make sense? Or should I just give up? Here's zahlman's example:
class Game {
  Keystate ks;
  typedef std::vector<Monster> MonsterSeq;
  MonsterSeq creatures; // includes player and monsters
  Player player;
  int empoweredTimer; // 0 means player is not empowered; nonzero means the
  // empowered state will last that many more ticks.
  // Don't model the walls as objects and iterate through that for collision.
  // Instead, model the map as a grid of objects, and let creatures have a
  // position within it. Creating the illusion of "moving between tiles", or
  // making walls connect and be rounded, is strictly up to the rendering code.
  enum {WALL, DOT, POWERPILL, EMPTY} Tile;
  Tile tiles[X][Y];
  Tile TheVoid;
 
  public:
  Game(): TheVoid(WALL), empoweredTimer(0) {
    // set up creatures
  }
 
  void update() {
    bool startEmpowering = false;
    for (CreatureSeq it = creatures.begin(); it != creatures.end(); ++it) {
      it->update(*this);
    }
    if (player.update(ks, Tiles[x][y])) { empoweredTimer = EMPOWERED_DURATION; }
    else if (playerIsEmpowered()) { empoweredTimer--; }
  }
 
  void keyPressed(int keyCode) {
    // modify the Keystate somehow
  }
 
  const Keystate& getKeys() const { return ks; }
 
  Tile& tileAt(int x, int y) {
    assert (x >= 0 && x < X && y >= 0 && y < Y);
    return Tiles[x][y];
  }
 
  // We have read-only access to "the void", which is solid wall.
  const Tile& tileAt(int x, int y) const {
    if (!(x >= 0 && x < X && y >= 0 && y < Y)) {
      return TheVoid;
    }
    return Tiles[x][y];
  }
 
  bool playerIsEmpowered() { return empoweredTimer > 0; }
 
  void checkMonsterCollision(int x, int y) {
    if (player.isAt(x, y)) {
      if (playerIsEmpowered()) { /* eat ghost */ }
      else { /* kill player */ }
    }
  }
}
 
// We won't use polymorphism here, but the base class is still useful for
// reusing functionality:
class Creature {
  int x, y;
};
 
class Monster: public Creature {
  void update(Game& g) {
    g.checkMonsterCollision(x, y);
    if (g.playerIsEmpowered()) {
      // flee from player; check for walls in adjacent tiles
      // and then set an appropriate new location.
    } else {
      // chase player; check for walls in adjacent tiles
      // and then set an appropriate new location.
    }
    g.checkMonsterCollision(x, y);
  }
};
 
class Player: public Creature {
  bool update(Game& g) {
    bool result = false;
    // Depending on g.getKeys(), change x and y.
 
    switch (g.tileAt(x, y)) { // calls const version
      case POWERPILL: result = true; // and fall through
      case DOT: case EMPTY:
        g.tileAt(x, y) = EMPTY; break; // calls non-const version
      default: /* undo the change to x and y. */
    }
    return result;
  }
};
 
int WinMain(LPTRLOLHUEGAPIPROVIDEDTHINGY args) {
  Game g;
  doMagicMessagePumpStuff();
  askForATimerEventEvery(30 * MILLISECONDS);
  while (receivingEvents) {
    Event e = giveMeAnEvent();
    switch (e.type) {
      case LOLTIMER: g.update(); g.draw(); break;
      case LOLKEYPRESS: g.keyPressed(e.keyCode); break;
      case LOLREFRESH: g.draw(); break;
    }
  }
}




THanks, durfy [Edited by - Durfy on July 7, 2007 7:16:14 PM]

Share this post


Link to post
Share on other sites
For event systems you can use several solutions. One of the easiest to use is enforcing which events a game object must implemented through an interface.

For instance, say you want inform a gameobject it has collided, that it has received damage and that it is being destroyed. You could shove these into an basic IEvents class, a la

class IEvents
{
virtual void OnCollide(GameObject &collideWith) = 0;
virtual void OnReceiveDamage(GameObject &source, int amount) = 0;
virtual void OnDestroy() = 0;
}



You would have all your objects implement this interface, and then you call from the main loop the OnCollide on the 2 corresponding game objects.

Toolmaker

Share this post


Link to post
Share on other sites
Thanks for the explanation would this be a good alternate solution?

#ifndef DURFSTATEMANAGER_H
#define DURFSTATEMANAGER_H

#include <vector>
#include "DurfMessage"
using namespace std;
class DurfStateManager {
private:
vector <Message> MessageStack;
public:
// Add a message to the queue
void QueueMessage(Message message);

// Message specific handling in here
// For each message if message.conditionMet() do message.action()
// If a message's action has been executed pop it from the stack
void ProcessMessages();

};

#endif







#ifndef DURFMESSAGE_H
#define DURFMESSAGE_H

class DurfMessage {
private:
// Special identifier for each message(key)
int messageid;

// Type of message so our handler knows what to do with it
string type;

public:
// What the message should do when condition met
void action();

// Different for every type of message(there will be message subclasses)
bool conditionMet();

// What type of message is it?
string getType();
};
#endif








I think this would work... It is a complex design making you create a new class for every type of message but how many message types could there be? .... Or I could take the alternate approach where all messages execute at a certain time and keypress events would just be processed with a time of 0....

I'm not sure if i'm going in the right direction is this a good way to do it?
EDIT also i should probably rename the message(bad named) class as Event class no?
-durfy

Share this post


Link to post
Share on other sites
The reason I think I need a state manager is so that I can have my game do actions at specific times.

For example:
When you empower pacman he is able to eat the ghosts.. But after a certain time another event happens that makes them able to eat pac man again. It was suggested that I use states to accomplish this....
Am I at least at a good start in my above post?
-durfy

[Edited by - Durfy on July 7, 2007 9:47:38 PM]

Share this post


Link to post
Share on other sites
I'm using a game state manager as well, but i don't go too low for the states. E.g. for a game i have a GSGame, GSEdit, GSMenu, GSHighscore and so on. Most of the time i have only a single GSGame state.

For different ingame modes (display get ready, play, display game over) i revert to enums. A lot of enum modes share the same code (display etc.) so a whole new class might be a bit overkill.

Share this post


Link to post
Share on other sites

This topic is 3811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this