Sign in to follow this  
code_nerd

GameLoop again

Recommended Posts

Hi folks, i am still confused about this gaming loop thing, in detail i want to accomplish: * A game loop that has different states * each state paints it's own windows.Form * every state can handle it's own OnPaint method I'd like to code the states like this: TitleState * sets Form to 800x600 * creates PictureBox and loads TitleBMP * on MouseClick or Enter next state (MenuState) should be loaded MenuState * loads new Form, creates some Buttons and tiles the actual Form to a "Website" like view (buttons on the left change the content window on the right). * Klicking on Buttons changes the content panel on the right, where different Options and some gameAI is processed (buying/selling troops) PlayGameState * loads a GDI+ created Hexagonal Grid (like Battle isle) * processes UserInput, movement, attact, etc. The loop is for my 2-D HexagonalBattleGame, which is roundbased. I am using GDI+ and C#. Can anybody show me how i can do this best? The mainproblem is as i said: * each state paints it's own windows.Form * every state can handle it's own OnPaint method

Share this post


Link to post
Share on other sites
one way is to make your states part of a class.

Have a base class with some basic virtual member functions. Then create more specific classes that inherit the base class(game, menu)and then define the virtual functions in these classes polymorphically...

this is what i did

Share this post


Link to post
Share on other sites
thanks for the idea, can you spend a skeleton code for me?
I find it quite hard to get an overview... and i never
did something with polymorph.

Many thanks in advantage!

Share this post


Link to post
Share on other sites
Personally I don't beleive that polymorhism is needed with states of an object within a game. What I mean is that within a game (or any program) you can have object's that don't necessarily relate to what the player will see. For example the number of live's left of an enemy. This would be controlled by the enemy object itself and not by the player, or the view of the player, or the game.

Now what you could maybe think of is a game state engine. The state engine would provide comunication with all the other object types that needed to know about a certain state, the obejct states contol the game states and vise versa. This would mean that all base object types would "tell" the state manager about which states it needed to know about on object instansiation.

The obejct manager would have should have 2 input lines and all objects would need a state listener and a state provider..I can provide a base for this if you like...but is the best way to do thing like this in my opinion. Oh you might also problems a with new new states being derivd at runtime. What I mean is that at EVERTING would need to know about all states. The general way of doing this is ith a MASSOVE list (enumg or struct) or you could provide a way od doing this at runtine.....boost hash stuff might help..:)

Right that's the object states that can be seen but what about the file manager and the menu manager..hang on the can use the same bit of kit....groovy!!!

BUT, you were talking about a game loop originally..the best I've seen is on Gamedev. The idea is actually a task mamger. Everything being a task object that is procesed by the kernel (corny names but design wise excellent). Please take a look at the Enginuity articles on Gamedev by SuperPig (One of the GameDev moderators...oh and if you can persuade him to finish them off, would love to see his networkig architecture)

Anyhow.....just some ideas....good luck.

This is a mean bit of technology but well worth the effort

[Edited by - garyfletcher on August 31, 2005 3:27:25 PM]

Share this post


Link to post
Share on other sites
yes, i really would appreciate a base skelleton of your way!
Please post it if you find the time.

"you could maybe think of is a game state engine"

i think i do yes, i already started to write this many times,
but i always failed to seperate my Forms AND keeping everything
i need accessable, so that i just can design forms for every
state, that don't conflict with the forms ot the other states.

"BUT, you were talking about a game loop originally."

Well, i think i meant GameStates and the Loop ;)

Share this post


Link to post
Share on other sites
well i used polymorphism because i use a stack to hold my gamestate objects, and in the winmain i just use gameState.top()->Render();

so it doesnt matter what state is on the stack, with polymorphism i can call the current top state on the stacks render method which of course can be implemented differnetly per state object (menu, game, pause, endgame, etc..)

Share this post


Link to post
Share on other sites
Okay..I can provide some code BUT I've not desined it all yet, as I'm only on the basics yet. I telll you what ...any improvements or ideas you have then let me know. Is that ok?

BTW there is a bit. If you need any explanation then just ask.


#include <iostream>
#include "App.h"

CApplication* CApplication::pApp = 0;

CApplication::~CApplication()
{
std::cout << "CApplication Destructor" << std::endl;
}

void CApplication::Free()
{
std::cout << "CApplication freeing pong" << std::endl;
std::cout << "CApplication freeing pApp" << std::endl;

delete pApp;

std::cout << "CApplication freed" << std::endl;

}

void CApplication::Run(int argc, char *argv[])
{

std::cout << "CApplication Started" << std::endl;

videoTask = new CVideoUpdate(10000);
kernel::CKernel::Instance()->AddTask(videoTask);

inputTask = new CInputTask(20);
kernel::CKernel::Instance()->AddTask(inputTask);

soundTask = new CSoundTask(50);
kernel::CKernel::Instance()->AddTask(soundTask);

globalTimer = new CGlobalTimer(10);
kernel::CKernel::Instance()->AddTask(globalTimer);

pong = new CPongTask(100);
kernel::CKernel::Instance()->AddTask(pong);

//main game loop
kernel::CKernel::Instance()->Execute();

kernel::CKernel::Instance()->Free();

std::cout << "CApplication Done" << std::endl;
}

#include "EventType.h"

namespace event
{
std::size_t CEventType::hash_name(std::string identStr)
{
if (identStr == sWildCardEventType)
return 0;

boost::hash<std::string> hasher;
return hasher(identStr);
}

CEventType& CEventType::operator=(const CEventType& rhs)
{
if (this != &rhs)
{
ident_ = rhs.ident_;
identStr_ = rhs.identStr_;
}

return *this;
}

bool CEventType::operator==(CEventType const& et) const
{
return (GetIdent() == et.GetIdent());
}
}

#include <iostream>
#include "GlobalTimer.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGlobalTimer::CGlobalTimer() : ITask()
{
std::cout << "CGlobalTimer Default Constructor" << std::endl;
}

CGlobalTimer::CGlobalTimer(long p) : ITask(p)
{
priority = p;
std::cout << "CGlobalTimer Long Constructor" << std::endl;
}

CGlobalTimer::CGlobalTimer(const CGlobalTimer& rhs) : ITask(rhs.priority,rhs.canKill)
{
std::cout << "CGlobalTimer Copy Constructor()" << std::endl;
}

CGlobalTimer::~CGlobalTimer()
{
std::cout << "CGlobalTimer Destructor" << std::endl;
}

CGlobalTimer& CGlobalTimer::operator=(const CGlobalTimer& rhs)
{
std::cout << "CGlobalTimer Assignment" << std::endl;

if(this != &rhs)
{
priority = rhs.priority;
canKill = rhs.canKill;
}

return *this;
}

bool CGlobalTimer::Start()
{
std::cout << "CGlobalTimer Start()" << std::endl;

return true;
}

void CGlobalTimer::Update()
{
std::cout << "CGlobalTimer Update()" << std::endl;

}

void CGlobalTimer::Stop()
{
std::cout << "CGlobalTimer Stop()" << std::endl;
}


#include <iostream>
#include "InputTask.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CInputTask::CInputTask() : ITask()
{
std::cout << "CInputTask Default Constructor()" << std::endl;
}

CInputTask::CInputTask(long p) : ITask(p)
{
std::cout << "CInputTask Long Constructor()" << std::endl;
}

CInputTask::CInputTask(const CInputTask& rhs) : ITask(rhs.priority,rhs.canKill)
{
std::cout << "CInputTask Copy Constructor()" << std::endl;
}

CInputTask::~CInputTask()
{
std::cout << "CInputTask Destructor()" << std::endl;
}

CInputTask& CInputTask::operator=(const CInputTask& rhs)
{
std::cout << "CInputTask Assignment" << std::endl;

if(this != &rhs)
{
priority = rhs.priority;
canKill = rhs.canKill;
}

return *this;
}


bool CInputTask::Start()
{
std::cout << "CInputTask Start()" << std::endl;

return true;
}

void CInputTask::Update()
{
std::cout << "CInputTask Update()" << std::endl;

}

void CInputTask::Stop()
{
std::cout << "CInputTask Stop()" << std::endl;

}

#include <iostream>
#include <SDL/SDL.h>
#include "Kernel.h"

namespace kernel
{
CKernel* CKernel::pKernel = 0;

CKernel::~CKernel()
{
std::cout << "CKernel Destructor()" << std::endl;
}

void CKernel::Free()
{
delete pKernel;
}

int CKernel::Execute()
{
std::cout << "CKernel Execute()" << std::endl;

while(!taskList.empty())
{
std::list<task::ITask*>::iterator it=taskList.begin();
std::list<task::ITask*>::const_iterator itEnd=taskList.end();

task::ITask* t;

for(;it!=itEnd;++it)
{
t=*it;

if(!t->canKill)
{
std::cout << "CKernel Execute() - calling update" << std::endl;
t->Update();
}

t=0;
}

//loop again to remove dead tasks
it=taskList.begin();
task::ITask* t1;

for(;it!=itEnd;)
{
t1=*it;
std::list<task::ITask*>::iterator tmpIt=it;
++it;

if(t1->canKill)
{
std::cout << "CKernel Execute() - calling stop" << std::endl;
t1->Stop();
std::cout << "CKernel Execute() - removing task" << std::endl;
taskList.erase(tmpIt);
delete t1;
std::cout << "CKernel Execute() - Task removed" << std::endl;
}

t1=0;
}

}

return 0;
}

bool CKernel::AddTask(task::ITask* t)
{
std::cout << "CKernel AddTask()" << std::endl;

if(!t->Start())return false;

//keep the order of priorities straight
std::list<task::ITask*>::iterator it=taskList.begin();
std::list<task::ITask*>::const_iterator itEnd=taskList.end();

for(;it!=itEnd;it++)
{
task::ITask* &comp=(*it);
if(comp->priority > t->priority) break;
}

taskList.insert(it, t);
return true;
}

void CKernel::SuspendTask(task::ITask* t)
{
std::cout << "CKernel SuspendTask()" << std::endl;

//check that this task is in our list - we don't want to suspend a task that isn't running
if(std::find(taskList.begin(),taskList.end(),t)!=taskList.end())
{
t->OnSuspend();
taskList.remove(t);
pausedTaskList.push_back(t);
}
}

void CKernel::ResumeTask(task::ITask* t)
{
std::cout << "CKernel ResumeTask()" << std::endl;

if(std::find(pausedTaskList.begin(),pausedTaskList.end(),t)!=pausedTaskList.end())
{
t->OnResume();
pausedTaskList.remove(t);
//keep the order of priorities straight
std::list<task::ITask*>::iterator it=taskList.begin();
std::list<task::ITask*>::const_iterator itEnd=taskList.end();

for(;it!=itEnd;it++)
{
task::ITask* &comp=(*it);
if(comp->priority > t->priority)break;
}
taskList.insert(it, t);
}
}

void CKernel::RemoveTask(task::ITask* t)
{
std::cout << "CKernel RemoveTask()" << std::endl;

if(std::find(taskList.begin(),taskList.end(),t)!=taskList.end())
{
t->canKill=true;
}
}

void CKernel::KillAllTasks()
{
std::cout << "CKernel KillAllTasks()" << std::endl;

std::list<task::ITask*>::iterator it=taskList.begin();
std::list<task::ITask*>::const_iterator itEnd=taskList.end();

for(;it!=itEnd;it++)
{
(*it)->canKill=true;
}
}
}

#include <windows.h>
#include <cstdarg>
#include <iostream>
#include "Log.h"
#include "Messages.h"

namespace logger
{
CLogger* CLogger::pLog = 0;

CLogger::CLogger()
{
}

CLogger::~CLogger()
{
}

bool CLogger::Init()
{
// load localise strings
if(!LoadStrings()) return false;

m_bAlog = false;
m_bClog = false;
m_bSlog = false;

return true;
}

void CLogger::Free()
{
std::cout << "CLogger freeing Log" << std::endl;
std::cout << "CLogger freeing pLog" << std::endl;

delete pLog;

std::cout << "CLogger freed" << std::endl;

}

void CLogger::Write(int target, const char *msg, ...)
{
va_list args; va_start(args,msg);
char szBuf[1024];
vsprintf(szBuf,msg,args);

std::stringstream aStream;

aStream<<__TIME__<<":";
aStream<<szBuf<<"\n";

if(target&LOG_APP)
{
if (!m_bAlog)
{
appLog.open("applog.txt");
m_bAlog = true;
}

appLog << szBuf<<"\n";
#ifdef DEBUG
appLog.flush();
#endif
}

if(target&LOG_CLIENT)
{
if (!m_bClog)
{
clientLog.open("clientlog.txt");
m_bClog = true;
}

clientLog<< aStream.str();
#ifdef DEBUG
clientLog.flush();
#endif
}

if(target&LOG_SERVER)
{
if (!m_bSlog)
{
serverLog.open("serverlog.txt");
m_bSlog = true;
}

serverLog<< aStream.str();
#ifdef DEBUG
serverLog.flush();
#endif
}

if(target&LOG_USER)
{
MessageBox(NULL,szBuf,"Message",MB_OK);
}

va_end(args);
}

void CLogger::Write(int target, const unsigned long msgID, ...)
{
va_list args; va_start(args, msgID);
char szBuf[1024];
vsprintf(szBuf,logStrings[msgID].c_str(),args);
Write(target,szBuf);
va_end(args);
}

bool CLogger::LoadStrings()
{
std::ifstream inFile("data/messages.txt");
if(!inFile.is_open())return false;

std::string line;

std::string::size_type strSize = 0;
char strStart = 0;
char strEnd = 0;

while(!inFile.eof() && getline(inFile,line))
{
/* Check for comments */
if(line[0] == '#')
continue;

strSize = line.size();
std::string message;
unsigned long msgID = 0;
int field = 1;
int j = 0;
bool breakLoop = false;

for (int i = 0; i < strSize;)
{

while (line[j] != ',' && j < strSize)
{
++j;
}

switch (field)
{
case 1:
{
/* Do nothing - 1st field is just the message identifier */
}
break;

case 2:
{
msgID = atol((line.substr(i,j)).c_str());
}
break;

case 3:
{
message = line.substr(i,j);
}
break;

default:
std::cerr << "Unknown field in message file" << std::endl;
breakLoop = true;
break;
}

if (breakLoop)
{
break;
}

++j;
i=j;

if (field == 3)
field = 1;
else
++field;
}

logStrings.insert(stringsPair(msgID,message));
}

return true;
}

}


#include <iostream>
#include "Pong.h"
#include "InputTask.h"
#include "App.h"
#include "GlobalTimer.h"

CPongTask::CPongTask() : task::ITask()
{
std::cout << "CPongTask Default Constructor" << std::endl;
}

CPongTask::CPongTask(long p) : task::ITask(p)
{
std::cout << "CPongTask Long Constructor" << std::endl;
}

CPongTask::CPongTask(const CPongTask& rhs) : task::ITask(rhs.priority,rhs.canKill)
{
std::cout << "CPongTask Copy Constructor" << std::endl;
}

CPongTask::~CPongTask()
{
std::cout << "CPongTask Destructor" << std::endl;
}

CPongTask& CPongTask::operator=(const CPongTask& rhs)
{
std::cout << "CPongTask Assignment" << std::endl;

if(this != &rhs)
{
priority = rhs.priority;
canKill = rhs.canKill;
}

return *this;
}

bool CPongTask::Start()
{
std::cout << "CPongTask Start()" << std::endl;
callCount = 0;

return true;
}

void CPongTask ::Update()
{
std::cout << "CPongTask Update()" << std::endl;

++callCount;

std::cout << "callCount = " << callCount << std::endl;

if (callCount == 100)
{
std::cout << "Killing all tasks" << std::endl;

kernel::CKernel::Instance()->KillAllTasks();
}

return;
}


CSoundTask::CSoundTask() : task::ITask()
{
std::cout << "CSoundTask Default Constructor()" << std::endl;
}

CSoundTask::CSoundTask(long p) : task::ITask(p)
{
std::cout << "CSoundTask Long Constructor()" << std::endl;
}

CSoundTask::CSoundTask(const CSoundTask& rhs) : task::ITask(rhs.priority,rhs.canKill)
{
std::cout << "CSoundTask Copy Constructor()" << std::endl;
}

CSoundTask::~CSoundTask()
{
std::cout << "CSoundTask Destructor()" << std::endl;
}

CSoundTask& CSoundTask::operator=(const CSoundTask& rhs)
{
std::cout << "CSoundTask Assignment" << std::endl;

if(this != &rhs)
{
priority = rhs.priority;
canKill = rhs.canKill;
}

return *this;
}

bool CSoundTask::Start()
{
std::cout << "CSoundTask Start()" << std::endl;

return true;
}

void CSoundTask::OnSuspend()
{
std::cout << "CSoundTask OnSuspend()" << std::endl;
}

void CSoundTask::Update()
{
std::cout << "CSoundTask Update()" << std::endl;

}

void CSoundTask::OnResume()
{
std::cout << "CSoundTask onResume()" << std::endl;
}

void CSoundTask::Stop()
{
std::cout << "CSoundTask Stop()" << std::endl;
}


#include <iostream>
#include "VideoUpdate.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CVideoUpdate::CVideoUpdate() : task::ITask(), scrWidth(800),scrHeight(600),scrBPP(16)
{
std::cout << "CVideoUpdate Default Constructor()" << std::endl;
}

CVideoUpdate::CVideoUpdate(long p) : task::ITask(p), scrWidth(800),scrHeight(600),scrBPP(16)
{
std::cout << "CVideoUpdate long Constructor()" << std::endl;
}

CVideoUpdate::CVideoUpdate(const CVideoUpdate& rhs) : task::ITask(rhs.priority,rhs.canKill), scrWidth(rhs.scrWidth),scrHeight(rhs.scrHeight),scrBPP(rhs.scrBPP)
{
std::cout << "CVideoUpdate Copy Constructor()" << std::endl;
}

CVideoUpdate::~CVideoUpdate()
{
std::cout << "CVideoUpdate Destructor()" << std::endl;
}

CVideoUpdate& CVideoUpdate::operator=(const CVideoUpdate& rhs)
{
std::cout << "CVideoUpdate Assignment" << std::endl;

if(this != &rhs)
{
scrWidth = rhs.scrWidth;
scrHeight = rhs.scrHeight;
scrBPP = rhs.scrBPP;
priority = rhs.priority;
canKill = rhs.canKill;
}

return *this;
}

bool CVideoUpdate::Start()
{
std::cout << "CVideoUpdate Start()" << std::endl;

return true;
}

void CVideoUpdate::Update()
{
std::cout << "CVideoUpdate Update()" << std::endl;
}

void CVideoUpdate::Stop()
{
std::cout << "CVideoUpdate Stop()" << std::endl;

}
[/source}

These are the headers:

[source}
#ifndef INCLUDE_APP_H
#define INCLUDE_APP_H

#include "VideoUpdate.h"
#include "GlobalTimer.h"
#include "InputTask.h"
#include "SoundTask.h"
#include "Pong.h"

class CApplication
{

CApplication(){}
CApplication(const CApplication&);
CApplication operator=(const CApplication&);

static CApplication* pApp;

public:

~CApplication();

static CApplication* Instance()
{
if (!pApp)
{
pApp = new CApplication;
}

return pApp;
}

CVideoUpdate* videoTask;
CInputTask* inputTask;
CSoundTask* soundTask;
CGlobalTimer* globalTimer;
CPongTask* pong;

void Run(int argc, char *argv[]);
void Free();

protected:

};

#endif

#ifndef INCLUDE_EVENT_H
#define INCLUDE_EVENT_H

#include "EventData.h"
#include "EventType.h"

namespace event
{
class CEvent
{
CEvent();

public:

explicit CEvent(const char* pEventTypeName,
float fTime = 0.f,
IEventDataPtr pData = IEventDataPtr((IEventData*)NULL))
: type_(pEventTypeName),time_(fTime),userData_(pData)
{}

explicit CEvent(const std::string& sEventType,
float fTime = 0.f,
IEventDataPtr pData = IEventDataPtr((IEventData*)NULL))
: type_(sEventType),
time_(fTime),
userData_(pData)
{}

CEvent(const CEvent& e) : type_(e.type_), time_(e.time_), userData_(e.userData_)
{}

virtual ~CEvent()
{}

CEvent& operator=(const CEvent& rhs)
{
if (this != &rhs)
{
type_ = rhs.type_;
time_ = rhs.time_;
userData_ = rhs.userData_;
}

return *this;
}

const CEventType& GetType() const
{
return type_;
}

float GetTime() const
{
return time_;
}

IEventDataPtr GetData() const
{
return userData_;
}

template <typename T>
T* GetDataPtr() const
{
return reinterpret_cast<T *>(userData_.get());
}

private:

CEventType type_;
float time_;
IEventDataPtr userData_;
};

}

#endif

#ifndef INCLUDE_EVENTDATA_H
#define INCLUDE_EVENTDATA_H

#include <boost/shared_ptr.hpp>

namespace event
{
class IEventData
{
public:
virtual ~IEventData(){}
};

typedef boost::shared_ptr<IEventData> IEventDataPtr;
}

#endif

#include <string>
#include <boost/functional/hash/hash.hpp>

namespace event
{
const std::string sWildCardEventType = "*";

class CEventType
{
CEventType();
std::size_t ident_;
std::string identStr_;

public:

static std::size_t hash_name(std::string identStr);

explicit CEventType(const char* pIdentStr) : ident_(CEventType::hash_name(std::string(pIdentStr))), identStr_(pIdentStr)
{}

explicit CEventType(const std::string& identStr) : ident_(CEventType::hash_name(identStr)), identStr_(identStr)
{}

CEventType(const CEventType& et) : ident_(et.ident_), identStr_(et.identStr_)
{}

CEventType& operator=(const CEventType& rhs);

std::size_t GetIdent() const
{
return ident_;
}

const std::string& GetIdentStr() const
{
return identStr_;
}

bool operator<(CEventType const& et) const
{
return (GetIdent() < et.GetIdent());
}

bool operator==(CEventType const& et) const;


private:


};


}

#endif

#ifndef INCLUDE_TIMER_H
#define INCLUDE_TIMER_H

#include "InputTask.h"

class CGlobalTimer : public task::ITask
{
public:
CGlobalTimer();
CGlobalTimer(long p);
CGlobalTimer(const CGlobalTimer& rhs);
virtual ~CGlobalTimer();
CGlobalTimer& operator=(const CGlobalTimer& rhs);

unsigned long size(){return sizeof(*this);}

bool Start();
void Update();
void Stop();

protected:

private:

};

#endif

#ifndef INCLUDE_ITASK_H
#define INCLUDE_ITASK_H

#include "Kernel.h"
#include "Task.h"

class CInputTask : public task::ITask
{
public:
CInputTask();
CInputTask(long p);
CInputTask(const CInputTask& rhs);
virtual ~CInputTask();
CInputTask& operator=(const CInputTask& rhs);

bool Start();
void Update();
void Stop();


protected:

private:

};

#endif

#ifndef INCLUDE_KERNEL_H
#define INCLUDE_KERNEL_H

#include <iostream>
#include <string>
#include <list>
#include "Task.h"

namespace kernel
{
class CKernel
{
CKernel(){}
CKernel(const CKernel&);
CKernel& operator=(const CKernel&);

static CKernel* pKernel;

public:
~CKernel();

static CKernel* Instance()
{
if (!pKernel)
{
pKernel = new CKernel;
}

return pKernel;
}

void Free();

int Execute();
bool AddTask(task::ITask* t);
void SuspendTask(task::ITask* t);
void ResumeTask(task::ITask* t);
void RemoveTask(task::ITask* t);
void KillAllTasks();

protected:
std::list<task::ITask*> taskList;
std::list<task::ITask*> pausedTaskList;


};

}

#endif

#ifndef INCLUDE_LOG_H
#define INCLUDE_LOG_H

#include <fstream>
#include <string>
#include <sstream>
#include <map>
#include "Messages.h"

// some constants
const int LOG_APP=1;
const int LOG_CLIENT=2;
const int LOG_SERVER=4;
const int LOG_USER=8;

const int MAX_LOG_STRINGS=500;

namespace logger
{
class CLogger
{
CLogger();
CLogger(const CLogger&);
CLogger operator=(const CLogger&);

static CLogger* pLog;
bool m_bAlog;
bool m_bClog;
bool m_bSlog;

public:

~CLogger();

static CLogger* Instance()
{
if (!pLog)
{
pLog = new CLogger;
}

return pLog;
}

public:

bool Init();
void Free();
void Write(int target, const char* msg, ...);
void Write(int target, const unsigned long msgID, ...);

protected:
std::ofstream appLog;
std::ofstream clientLog;
std::ofstream serverLog;

//std::string logStrings[MAX_LOG_STRINGS];
std::map<const unsigned long, std::string> logStrings;
typedef std::pair<const unsigned long, std::string> stringsPair;

bool LoadStrings();
};
}

#endif


#ifndef MESSAGES_INCLUDE_H
#define MESSAGES_INCLUDE_H

#define IDS_NO_ERROR 0
#define IDS_UNRELEASED_OBJECT 1
#define IDS_CANT_CONNECT 2
#define IDS_UNHANDLED_MESSAGE 3
#define IDS_CANT_SERVE 4
#define IDS_SERVER_SOCKET_OPEN 5
#define IDS_TRANSMIT_FAIL 6
#define IDS_CLIENT_SOCKET_OPEN 7
#define IDS_GENERIC_SUB_INIT_FAIL 8
#define IDS_BAD_DISPLAYMODE 9
#define IDS_PROFILE_HEADER1 10
#define IDS_PROFILE_HEADER2 11
#define IDS_PROFILE_SAMPLE 12
#define IDS_TEXTURE_LOAD_FAILED 13
#define IDS_TEXTURE_FIND_FAILED 14

#endif

#ifndef INCLUDE_PONG_H
#define INCLUDE_PONG_H

#include "InputTask.h"
#include "GlobalTimer.h"

class CPongTask : public task::ITask
{
public:
CPongTask();
CPongTask(long p);
CPongTask(const CPongTask& rhs);
virtual ~CPongTask();
CPongTask& operator=(const CPongTask& rhs);

bool Start();
void Update();
void Stop(){};

unsigned long size(){return sizeof(*this);}

private:

int callCount;

};

#endif

#ifndef INCLUDE_STASK_H
#define INCLUDE_STASK_H

#include "InputTask.h"

class CSoundTask : public task::ITask
{
public:
CSoundTask();
CSoundTask(long p);
CSoundTask(const CSoundTask& rhs);
virtual ~CSoundTask();
CSoundTask& operator=(const CSoundTask& rhs);

bool Start();
void OnSuspend();
void Update();
void OnResume();
void Stop();

unsigned long size(){return sizeof(*this);}

private:

protected:

};

#endif

#ifndef INCLUDE_STASK_H
#define INCLUDE_STASK_H

#include "InputTask.h"

class CSoundTask : public task::ITask
{
public:
CSoundTask();
CSoundTask(long p);
CSoundTask(const CSoundTask& rhs);
virtual ~CSoundTask();
CSoundTask& operator=(const CSoundTask& rhs);

bool Start();
void OnSuspend();
void Update();
void OnResume();
void Stop();

unsigned long size(){return sizeof(*this);}

private:

protected:

};

#endif
#ifndef INCLUDE_VTASK_H
#define INCLUDE_VTASK_H

#include "InputTask.h"

class CVideoUpdate : public task::ITask
{
public:
CVideoUpdate();
CVideoUpdate(long p);
CVideoUpdate(const CVideoUpdate& rhs);
virtual ~CVideoUpdate();
CVideoUpdate& operator=(const CVideoUpdate& rhs);
unsigned long size(){return sizeof(*this);}


bool Start();
void Update();
void Stop();

protected:

int scrWidth;
int scrHeight;
int scrBPP;

private:

};

#endif
[/source}

Am sure you can get the source and headers all together....oh I don't think that the whole of the event manager is there yet...but am Sure that you can write most of it youself. An if not THen I will gove you a hand...coz I doing it myself and am sure that people on here will have better ideas...I hope!!!!

Share this post


Link to post
Share on other sites
thanks for posting the code, but since it is most likely C++ (i am using C#)
i don't really understand it ;)

I have a "new try", but i still fail to implement that i have
a seperate Form in every State (or one MainForm with
seperate UserControls for each state), if someone could hack that
code into my skelleton i would really, really be VERY thankfull...
or at least tell me where i should place what to get this work.


##########MainForm.cs##########
using System;
using System.Windows.Forms;
using System.Drawing;

namespace ArchitectureI

{

public class stringholder
{
public string output;

public void change(string newString)
{
output = newString;
}
}

public class Arch : System.Windows.Forms.Form

{
private System.Windows.Forms.Panel panel_title;
private System.Windows.Forms.PictureBox pictureBox1;


GameStateManager gamestateManager;
stringholder pretendDevice;


protected override void OnPaint(PaintEventArgs pea)
{
panel_title.Visible = false;
pea.Graphics.DrawString(pretendDevice.output,this.Font, Brushes.Black, 0,0);
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
if((int)e.KeyChar == (int)Keys.Enter)
{
//MessageBox.Show("You pressed Enter");
gamestateManager.switchState(new PlayingGameState(pretendDevice));
Invalidate();
}

if((int)e.KeyChar == (int)Keys.Escape)
{
gamestateManager.switchState(new TitleScreen(pretendDevice));
Invalidate();
}
}

public Arch()
{
pretendDevice = new stringholder();
pretendDevice.change("No State");
gamestateManager = new GameStateManager(new TitleScreen(pretendDevice));
}

static void Main(){


Arch arch = new Arch();
arch.InitializeComponent();
arch.Show();

while(arch.Created)
{
arch.gamestateManager.process();
Application.DoEvents();
}
}

#region Windows Forms Designer generated code
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent() {
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Arch));

this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.panel_title = new System.Windows.Forms.Panel();
this.panel_title.SuspendLayout();
this.SuspendLayout();
//
// pictureBox1
//
//this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("titlescreen")));
this.pictureBox1.Image = Image.FromFile("titlescreen.bmp");
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(800, 600);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// panel_title
//
this.panel_title.Controls.Add(this.pictureBox1);
this.panel_title.Location = new System.Drawing.Point(-8, -8);
this.panel_title.Name = "panel_title";
this.panel_title.Size = new System.Drawing.Size(800, 600);
this.panel_title.TabIndex = 0;
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(792, 573);
this.Controls.Add(this.panel_title);
this.Name = "MainForm";
this.Text = "MainForm";
this.panel_title.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
}
}


##########GameState.cs##########
using System;
using System.Windows.Forms;
using System.Drawing;

namespace ArchitectureI
{
public interface GameState
{
void render();
}
}


##########GameStateManager.cs##########
using System;
namespace ArchitectureI

{
public class GameStateManager
{
private GameState state;
public void process()
{
if(state != null)
state.render();
}
public GameStateManager(GameState intialState)
{
state = intialState;
}
public GameState switchState(GameState newState)
{
GameState oldState = state; //store current state
state = newState; //replace current state
return(oldState); //return old value
}
}
}

##########ExampleStates.cs##########

using System;
using System.Windows.Forms;
using System.Drawing;

namespace ArchitectureI

{

public class TitleScreen : GameState
{
stringholder s;
bool boxShowed = false;

public TitleScreen(stringholder output)
{
// Logic
s = output;

}

public void render()
{
// painting
s.change("In TitleScreenState!");
if(!boxShowed){
MessageBox.Show("In TITLE!");
boxShowed=true;
}

}
}
public class PlayingGameState : GameState
{
stringholder s;
bool boxShowed = false;

public PlayingGameState(stringholder output)
{
s = output;
}
protected void OnPaint(PaintEventArgs pea)

{

//pea.Graphics.DrawString(pretendDevice.output,this.Font, Brushes.Black, 0,0);

}
public void render()
{
s.change("In PlayingGameState!");
if(!boxShowed){
MessageBox.Show("In PLAYINGGAME!");
boxShowed=true;
}

}


}

}




[Edited by - code_nerd on August 31, 2005 5:41:23 PM]

Share this post


Link to post
Share on other sites
So does C# provide an inbult evevent handler? I know windows does.

Hey an angorithim surpasses a platform. If you've got an idea that is better than mine then please say.

In fact plesae ANYONE!!!! I'd love to here it.

The more speed the better.

I must admit that I'd be spurised..now if that's not a challenge I don't know what is!!!

Share this post


Link to post
Share on other sites

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