#ifndef GAMESTATE_H
#define GAMESTATE_H
#include "gameengine.h"
class CGameState
{
public:
virtual void Init() = 0;
virtual void Cleanup() = 0;
virtual void Pause() = 0;
virtual void Resume() = 0;
virtual void HandleEvents(CGameEngine* game) = 0;
virtual void Update(CGameEngine* game) = 0;
virtual void Draw(CGameEngine* game) = 0;
void ChangeState(CGameEngine* game, CGameState* state) {
game->ChangeState(state);
}
protected:
CGameState() { }
};
#endif
gameengine.h
#ifndef GAMEENGINE_H
#define GAMEENGINE_H
#include "SDL.h"
#include '
using namespace std;
class CGameState;
class CGameEngine
{
public:
void Init(const char* title, int width=640, int height=480,
int bpp=0, bool fullscreen=false);
void Cleanup();
void ChangeState(CGameState* state);
void PushState(CGameState* state);
void PopState();
void HandleEvents();
void Update();
void Draw();
bool Running() { return m_running; }
void Quit() { m_running = false; }
SDL_Surface* screen;
private:
// the stack of states
vector
bool m_running;
bool m_fullscreen;
};
#endif
gameengine.cpp
#include ''
#include "SDL.h"
#include "gameengine.h"
#include "gamestate.h"
void CGameEngine::Init(const char* title, int width, int height,
int bpp, bool fullscreen)
{
int flags = 0;
// initialize SDL
SDL_Init(SDL_INIT_VIDEO);
// set the title bar text
SDL_WM_SetCaption(title, title);
if ( fullscreen ) {
flags = SDL_FULLSCREEN;
}
// create the screen surface
screen = SDL_SetVideoMode(width, height, bpp, flags);
m_fullscreen = fullscreen;
m_running = true;
printf("CGameEngine Init\n");
}
void CGameEngine::Cleanup()
{
// cleanup the all states
while ( !states.empty() ) {
states.back()->Cleanup();
states.pop_back();
}
// switch back to windowed mode so other
// programs won't get accidentally resized
if ( m_fullscreen ) {
screen = SDL_SetVideoMode(640, 480, 0, 0);
}
printf("CGameEngine Cleanup\n");
// shutdown SDL
SDL_Quit();
}
void CGameEngine::ChangeState(CGameState* state)
{
// cleanup the current state
if ( !states.empty() ) {
states.back()->Cleanup();
states.pop_back();
}
// store and init the new state
states.push_back(state);
states.back()->Init();
}
void CGameEngine::PushState(CGameState* state)
{
// pause current state
if ( !states.empty() ) {
states.back()->Pause();
}
// store and init the new state
states.push_back(state);
states.back()->Init();
}
void CGameEngine::PopState()
{
// cleanup the current state
if ( !states.empty() ) {
states.back()->Cleanup();
states.pop_back();
}
// resume previous state
if ( !states.empty() ) {
states.back()->Resume();
}
}
void CGameEngine::HandleEvents()
{
// let the state handle events
states.back()->HandleEvents(this);
}
void CGameEngine::Update()
{
// let the state update the game
states.back()->Update(this);
}
void CGameEngine::Draw()
{
// let the state draw the screen
states.back()->Draw(this);
}
introstate.h
#ifndef INTROSTATE_H
#define INTROSTATE_H
#include "SDL.h"
#include "gamestate.h"
class CIntroState : public CGameState
{
public:
void Init();
void Cleanup();
void Pause();
void Resume();
void HandleEvents(CGameEngine* game);
void Update(CGameEngine* game);
void Draw(CGameEngine* game);
static CIntroState* Instance() {
return &m_IntroState;
}
protected:
CIntroState() { }
private:
static CIntroState m_IntroState;
SDL_Surface* bg;
SDL_Surface* fader;
int alpha;
};
#endif
introstate.cpp
#include
#include "SDL.h"
#include "gameengine.h"
#include "gamestate.h"
#include "introstate.h"
#include "playstate.h"
CIntroState CIntroState::m_IntroState;
void CIntroState::Init()
{
SDL_Surface* temp = SDL_LoadBMP("intro.bmp");
bg = SDL_DisplayFormat(temp);
SDL_FreeSurface(temp);
// create the fader surface like the background with alpha
fader = SDL_CreateRGBSurface( SDL_SRCALPHA, bg->w, bg->h,
bg->format->BitsPerPixel,
bg->format->Rmask, bg->format->Gmask,
bg->format->Bmask, bg->format->Amask );
// fill the fader surface with black
SDL_FillRect (fader, NULL, SDL_MapRGB (bg->format, 0, 0, 0)) ;
// start off opaque
alpha = 255;
SDL_SetAlpha(fader, SDL_SRCALPHA, alpha);
printf("CIntroState Init\n");
}
void CIntroState::Cleanup()
{
SDL_FreeSurface(bg);
SDL_FreeSurface(fader);
printf("CIntroState Cleanup\n");
}
void CIntroState::Pause()
{
printf("CIntroState Pause\n");
}
void CIntroState::Resume()
{
printf("CIntroState Resume\n");
}
void CIntroState::HandleEvents(CGameEngine* game)
{
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
game->Quit();
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_SPACE:
game->ChangeState( CPlayState::Instance() );
break;
case SDLK_ESCAPE:
game->Quit();
break;
}
break;
}
}
}
void CIntroState::Update(CGameEngine* game)
{
alpha--;
if (alpha < 0)
alpha = 0;
SDL_SetAlpha(fader, SDL_SRCALPHA, alpha);
}
void CIntroState::Draw(CGameEngine* game)
{
SDL_BlitSurface(bg, NULL, game->screen, NULL);
// no need to blit if it's transparent
if ( alpha != 0 )
SDL_BlitSurface(fader, NULL, game->screen, NULL);
SDL_UpdateRect(game->screen, 0, 0, 0, 0);
}
main.cpp
#include "gameengine.h"
#include "introstate.h"
int main ( int argc, char *argv[] )
{
CGameEngine game;
// initialize the engine
game.Init( "Engine Test v1.0" );
// load the intro
game.ChangeState( CIntroState::Instance() );
// main loop
while ( game.Running() )
{
game.HandleEvents();
game.Update();
game.Draw();
}
// cleanup the engine
game.Cleanup();
return 0;
}
댓글 없음:
댓글 쓰기