SDL入门教程(五):6、对C++异常机制的思考,代码重写

作者:龙飞

6.1:用bool作为命令是不是画蛇添足了?

        不知道为什么,我总觉得总是用if结构来调用命令让人读起程序来很不连贯。所以,我决定重新修改下,并且异常抛出改为使用类对象,这样是不是更C++一点呢?:)

6.2:修改后的代码。
// FileName: SurfaceClass.h

#ifndef SURFACE_CLASS_H
#define  SURFACE_CLASS_H

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

using  std:: string ;

class  ScreenSurface
{
private :
    
static   int  screenNum;
    
int  width;
    
int  height;
    
int  bpp;
    Uint32 flags;
    SDL_Surface
*  pScreen;
public :
    ScreenSurface();
    ScreenSurface(
int  w,  int  h,  int  b  =   0 , Uint32 f  =   0 );
    
~ ScreenSurface();
    SDL_Surface
*  point()  const ;
    
void  flip()  const ;
};

class  DisplaySurface
{
private :
    
string  fileName;
    SDL_Surface
*  pSurface;
    SDL_Surface
*  pScreen;
public :
    DisplaySurface(
string  file_name,  const  ScreenSurface &  screen);
    
~ DisplaySurface();
    SDL_Surface
*  point()  const ;
    
void  blit()  const ;
    
void  blit( int  at_x,  int  at_y)  const ;
    
void  blit( int  at_x,  int  at_y,
                
int  from_x,  int  from_y,  int  w,  int  h,
                
int  delta_x  =   2 int  delta_y  =   2 const ;
    
void  blitToSurface( const  DisplaySurface &  dst_surface,
                        
int  at_x  =   0 int  at_y  =   0 const ;
    
void  blitToSurface( const  DisplaySurface &  dst_surface,
                        
int  at_x,  int  at_y,
                        
int  from_x,  int  from_y,  int  w,  int  h,
                        
int  delta_x  =   2 int  delta_y  =   2 const ;
};

class  ErrorInfo
{
private :
    
string  info;
public :
    ErrorInfo():info(
" Unknown ERROR! " )
    {}
    ErrorInfo(
const   char *  c_str)
    {
        info 
=   string (c_str);
    }
    ErrorInfo(
const   string &  str):info(str)
    {}
    
void  show()  const
    {
        std::cerr 
<<  info  <<  std::endl;
    }
};

#endif

#include  " SurfaceClass.h "

// VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
// class ScreenSurface

int  ScreenSurface::screenNum  =   0 ;

ScreenSurface::ScreenSurface():
width(
640 ), height( 480 ), bpp( 32 ), flags( 0 )
{
    
if  ( screenNum  >   0  )
        
throw  ErrorInfo( " DONOT create more than ONE screen! " );
    
if  ( SDL_Init(SDL_INIT_VIDEO  <   0  ) )
        
throw  ErrorInfo(SDL_GetError());
    pScreen 
=  SDL_SetVideoMode(width, height, bpp, flags);
    screenNum
++ ;
}

ScreenSurface::ScreenSurface(
int  w,  int  h,  int  b, Uint32 f):
width(w), height(h), bpp(b), flags(f)
{
    
if  ( screenNum  >   0  )
        
throw  ErrorInfo( " DONOT create more than ONE screen! " );
    
if  ( SDL_Init(SDL_INIT_VIDEO  <   0  ) )
        
throw  ErrorInfo(SDL_GetError());
    pScreen 
=  SDL_SetVideoMode(width, height, bpp, flags);
    screenNum
++ ;
}

ScreenSurface::
~ ScreenSurface()
{
    SDL_Quit();
}

SDL_Surface
*  ScreenSurface::point()  const
{
    
return  pScreen;
}

void  ScreenSurface::flip()  const
{
    
if  ( SDL_Flip(pScreen)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

// VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
// class DisplaySurface

DisplaySurface::DisplaySurface(std::
string  file_name,  const  ScreenSurface &  screen):
fileName(file_name)
{
    pSurface 
=  SDL_LoadBMP(file_name.c_str());
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(SDL_GetError());
    pScreen 
=  screen.point();
}

DisplaySurface::
~ DisplaySurface()
{
    SDL_FreeSurface(pSurface);
}

SDL_Surface
*  DisplaySurface::point()  const
{
    
return  pSurface;
}

void  DisplaySurface::blit()  const
{
    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  0 <   0  )
        
throw  ErrorInfo(SDL_GetError());
}


void  DisplaySurface::blit( int  at_x,  int  at_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x;
    offset.y 
=  at_y;

    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  DisplaySurface::blit( int  at_x,  int  at_y,
                          
int  from_x,  int  from_y,  int  w,  int  h,
                          
int  delta_x,  int  delta_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x  -  delta_x;
    offset.y 
=  at_y  -  delta_y;

    SDL_Rect dest;
    dest.x 
=  from_x  -  delta_x;
    dest.y 
=  from_y  -  delta_y;
    dest.w 
=  w  +  delta_x * 2 ;
    dest.h 
=  h  +  delta_y * 2 ;

    
if  ( SDL_BlitSurface(pSurface,  & dest, pScreen,  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  DisplaySurface::blitToSurface( const  DisplaySurface &  dst_surface,  int  at_x,  int  at_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x;
    offset.y 
=  at_y;

    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );

    
if  ( SDL_BlitSurface(pSurface,  0 , dst_surface.point(),  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  DisplaySurface::blitToSurface( const  DisplaySurface &  dst_surface,
                                    
int  at_x,  int  at_y,
                                    
int  from_x,  int  from_y,  int  w,  int  h,
                                    
int  delta_x,  int  delta_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x  -  delta_x;
    offset.y 
=  at_y  -  delta_y;

    SDL_Rect dest;
    dest.x 
=  from_x  -  delta_x;
    dest.y 
=  from_y  -  delta_y;
    dest.w 
=  w  +  delta_x * 2 ;
    dest.h 
=  h  +  delta_y * 2 ;

    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );

    
if  ( SDL_BlitSurface(pSurface,  & dest, dst_surface.point(),  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


 

#include  " SurfaceClass.h "

int  game( int  argc,  char *  argv[]);
int  main( int  argc , char *  argv[])
{
    
int  mainRtn  =   0 ;
    
try  {
        mainRtn 
=  game(argc, argv);
    }
    
catch  (  const  ErrorInfo &  info ) {
        info.show();
        
return   - 1 ;
    }
    
    
return  mainRtn;
}

int  game( int  argc , char *  argv[])
{
    
// Create a SDL screen.
     const   int  SCREEN_WIDTH  =   640 ;
    
const   int  SCREEN_HEIGHT  =   480 ;
    ScreenSurface screen(SCREEN_WIDTH, SCREEN_HEIGHT);

    
// Create 2 SDL surface for the screen that just created.
    DisplaySurface backGround( " bg.bmp " , screen);
    DisplaySurface frontImage(
" image.bmp " , screen);
    
// VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
    
// way2: If use blitToSurface, must get a copy of backGround.
/*

    DisplaySurface backGroundCopy("bg.bmp", screen);
*/
    
// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    
// Blit backGround surface to screen and flip the screen.
    backGround.blit();
    screen.flip();

    
// variable for main loop.
    
// key event for up, down, left and right.
    Uint8 *  keys;
    
// moving image's coordinate.
     int  xpos  =   0 ;
    
int  ypos  =   0 ;
    
// moving image's size.
     const   int  IMG_WIDTH  =   128 ;
    
const   int  IMG_HEIGHT  =   128 ;
    
// main loop.
     bool  gameOver  =   false ;
    
while ( gameOver  ==   false  ){
        
// press ESC or click X to quit.
        SDL_Event gameEvent;
        
while  ( SDL_PollEvent( & gameEvent)  !=   0  ){
            
if  ( gameEvent.type  ==  SDL_QUIT ){
                gameOver 
=   true ;
            }
            
if  ( gameEvent.type  ==  SDL_KEYUP ){
                
if  ( gameEvent.key.keysym.sym  ==  SDLK_ESCAPE ){
                    gameOver 
=   true ;
                }
            }
        }
        
// key event to move image.
        keys  =  SDL_GetKeyState( 0 );
        
if  ( keys[SDLK_UP]  ||  keys[SDLK_w] ){
            ypos 
-=   1 ;
        }
        
if  ( keys[SDLK_DOWN] ||  keys[SDLK_s] ){
            ypos 
+=   1 ;
        }
        
if  ( keys[SDLK_LEFT] ||  keys[SDLK_a] ){
            xpos 
-=   1 ;
        }
        
if  ( keys[SDLK_RIGHT] ||  keys[SDLK_d] ){
            xpos 
+=   1 ;
        }

        
// Hold moving image on the backGround area.
         if  ( xpos  <=   0  )
            xpos 
=   0 ;
        
if  ( xpos  >=  SCREEN_WIDTH  -  IMG_WIDTH )
            xpos 
=  SCREEN_WIDTH  -  IMG_WIDTH;
        
if  ( ypos  <=   0  )
            ypos 
=   0 ;
        
if  ( ypos  >=  SCREEN_HEIGHT  -  IMG_HEIGHT )
            ypos 
=  SCREEN_HEIGHT  -  IMG_HEIGHT;

        
// VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
        
// way1: blit surface to screen
        
// Blit a part of backGround ( a rectangular area ) to screen,
        
// then the original blitted backGround can be "cleaned".
        backGround.blit(xpos, ypos, xpos, ypos, IMG_WIDTH, IMG_HEIGHT);
        
// Blit the image to screen.
        frontImage.blit(xpos, ypos);
        
// Flip the screen
        screen.flip();
        
// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

        
// VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
        
// way2: blit surface to surface, then blit the last surface to screen
/*

        backGroundCopy.blitToSurface(backGround, xpos, ypos, xpos, ypos, IMG_WIDTH, IMG_HEIGHT);
        frontImage.blitToSurface(backGround, xpos, ypos);
        backGround.blit();
        screen.flip();
*/
        
// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    }

    
return   0 ;
}
 

你可能感兴趣的:(SDL入门教程(五):6、对C++异常机制的思考,代码重写)