C#

Fools ignore complexity; pragmatists suffer it; experts avoid it; CREATIVES remove it.

Tuesday, November 10, 2009

Generic interface game flow



Question? is that possible to create an architecture, interface based, which allows you programming a game flow independent of his content?

answer: yes!

Note that Minigame_Pinball and Minigame_Pinball_Score are just interface implementations that don't know nothing about the game flow, they are using IGameObj to connect to the flow and returning a condition from FLOW_CONDITIONS, they register themselves and they are allocated only when I need them :) (it's easy to pre-allocate if you want to)

Now, you can copy the code, create your own game class, derive that from IGameCreateObj and implementing your own IGameObj and have fun!!!!


//class MyOwn : public IGameCreateObj<MyOwn>

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <typeinfo>
#include <time.h>

using namespace std;

enum FLOW_CONDITIONS { LOOP = 0, NEXT_FLOW, BACK, NEXT }; 

class IGameObj
{
public:
 virtual void Init() = 0;
 virtual FLOW_CONDITIONS Loop() = 0;
 virtual void Uninit() = 0;
 virtual IGameObj *CreateANew() = 0;

 virtual ~IGameObj(){};
};

template<class X>
class IGameCreateObj : public IGameObj
{
public:
 //make singleton
 static X* GetInstance() { static X x; return &x; }
 //able to get a copy
 IGameObj *CreateANew() { return new X(); };

 virtual ~IGameCreateObj(){};
};

class Minigame_Pinball : public IGameCreateObj<Minigame_Pinball>
{
private:
 double timeOut;

public:
 void Init() { timeOut = clock(); };
 FLOW_CONDITIONS Loop() 
 { 

  timeOut += clock()-timeOut;

  if (timeOut > 3000) 
   return NEXT;

  cout << "Minigame_Pinball " << timeOut << endl;

  return LOOP; 
 };

 void Uninit() {};
};

class Minigame_Pinball_Score : public IGameCreateObj<Minigame_Pinball_Score>
{
public:
 void Init() {};
 FLOW_CONDITIONS Loop() { return LOOP;};
 void Uninit() {};
};

struct FlowCondition
{
 IGameObj *obj1;
 FLOW_CONDITIONS fc;
 IGameObj *obj2;
};

class IGameFlow
{
public:
 virtual bool Loop() = 0;
};

class GameFlow : public IGameFlow 
{ 
private: 
 vector<const FlowCondition* const> _list; 

 IGameObj *_currentObj;

 IGameObj *AllocType( IGameObj *obj_info )
 {
  IGameObj *mg = NULL;
  mg = obj_info->CreateANew();
  return mg;
 }

 FlowCondition *SearchCondition( FLOW_CONDITIONS fc )
 {
  vector<const FlowCondition* const>::iterator it;
  for( it = _list.begin(); it != _list.end(); ++it )
   if ((*it)->fc == fc) return (FlowCondition *)*it;
  return NULL;
 };

public:
 GameFlow() : _currentObj(NULL) {};

 void RegisterCondition(IGameObj *obj1, const FLOW_CONDITIONS fc, IGameObj *obj2 ) 
 { 
  FlowCondition *p = new FlowCondition();
  p->fc = fc;
  p->obj1 = obj1;
  p->obj2 = obj2;
  _list.push_back( p ); 

  if (_currentObj == NULL)
  {
   _currentObj = AllocType(obj1);
   _currentObj->Init();
  }
  return; 
 } 

 virtual ~GameFlow()
 {
  vector<const FlowCondition* const>::iterator it;
  for( it = _list.begin(); it != _list.end(); ++it )
   delete *it;

  delete _currentObj;
 }

 bool Loop() 
 { 
  FLOW_CONDITIONS fc = _currentObj->Loop();
  if (fc==NEXT_FLOW) return false;

  FlowCondition *tmp = SearchCondition( fc );
  if (tmp != NULL)
  {
   _currentObj->Uninit();
   delete _currentObj;
   _currentObj = AllocType(tmp->obj2);
   _currentObj->Init();
  }

  return true;
 }
};

class GameFlowManager 
{ 
private: 
 vector<const IGameFlow* const> _list; 

 IGameFlow* _gFlowCurrent;

public: 
 GameFlowManager() : _gFlowCurrent(NULL) {};

 void RegisterFlow(IGameFlow *gflow) 
 { 
  if (_gFlowCurrent==NULL) _gFlowCurrent = gflow;
  _list.push_back( gflow ); 
  return; 
 } 

 void Loop()
 {
  while(_gFlowCurrent->Loop())
  {
  }
 }
};


int _tmain(int argc, _TCHAR* argv[])
{
 GameFlow minigameFlow;
 minigameFlow.RegisterCondition( Minigame_Pinball::GetInstance(), NEXT, Minigame_Pinball_Score::GetInstance());
 minigameFlow.RegisterCondition( Minigame_Pinball_Score::GetInstance(), BACK, Minigame_Pinball::GetInstance());
 minigameFlow.RegisterCondition( Minigame_Pinball_Score::GetInstance(), NEXT_FLOW, NULL );

 GameFlowManager game;
 game.RegisterFlow( (IGameFlow*)&minigameFlow );
 game.Loop();

 return 0;
}


Nowadays, I'm working as director of pre-production so "officially" I do not write code, anyway, I hope it can help someone :)

Thursday, February 12, 2009

From 3D coordenates to 2D




I'm working as producer now; thats not really an easy job, no time for anything else a team of 20, but when I have some chance, I'm used to code anything.

This code was done really fast, it convert from any 3d coordenates to 2D, for instance, you can use that to do a 2D map which refers a 3D space.

Vector2D From3DTo2D( const Vector2D &currPos3D, const Vector2D &initialCoord3D, const Vector2D &finalCoord3D, const Vector2D &initialCoord2D, const Vector2D &finalCoord2D )
{
 Vector2D tmp(0,0);

 tmp.X = 1-(finalCoord3D.X-currPos3D.X)/(finalCoord3D.X-initialCoord3D.X);
 tmp.Y = 1-(finalCoord3D.Y-currPos3D.Y)/(finalCoord3D.Y-initialCoord3D.Y);

 tmp.X = ((finalCoord2D.X-initialCoord2D.X)*tmp.X)+initialCoord2D.X;
 tmp.Y = ((finalCoord2D.Y-initialCoord2D.Y)*tmp.Y)+initialCoord2D.Y;

 return tmp;
}
Powered By Blogger