作者:龙飞
3.1:一些小的修改
我觉得写C++的程序,一是看起来确实比较C++一点,二是相对于C的“精炼”,C++要的是“健壮”。所以,其实我不太满意用C风格字符串作为ScreenSurface的成员数据,所以做了修改。这也是为了在程序中构建ScreenSurface对象的时候可以使用string。
3.1:一些小的修改
我觉得写C++的程序,一是看起来确实比较C++一点,二是相对于C的“精炼”,C++要的是“健壮”。所以,其实我不太满意用C风格字符串作为ScreenSurface的成员数据,所以做了修改。这也是为了在程序中构建ScreenSurface对象的时候可以使用string。
class
ScreenSurface
{
private :
//
std:: string windowName;
public :
//
ScreenSurface( int w, int h, const std:: string & window_name = " NULL " , int b = 0 , Uint32 f = 0 );
};
相应的,我们修改了2个构造函数。
{
private :
//
std:: string windowName;
public :
//
ScreenSurface( int w, int h, const std:: string & window_name = " NULL " , int b = 0 , Uint32 f = 0 );
};
ScreenSurface::ScreenSurface():
width( 640 ), height( 480 ), bpp( 32 ), flags( 0 ), windowName( " NULL " )
{
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, const std:: string & window_name, 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 ++ ;
if ( window_name != " NULL " ) {
windowName = window_name;
SDL_WM_SetCaption(windowName.c_str(), 0 );
}
else
windowName = " NULL " ;
}
width( 640 ), height( 480 ), bpp( 32 ), flags( 0 ), windowName( " NULL " )
{
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, const std:: string & window_name, 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 ++ ;
if ( window_name != " NULL " ) {
windowName = window_name;
SDL_WM_SetCaption(windowName.c_str(), 0 );
}
else
windowName = " NULL " ;
}
第二个地方,我修改了TextSurface构造函数的参数顺序,并且将默认的字体改为Windows都自带的“新罗马时代”字体times.ttf。我将字体参数放在最后,将字体大小参数提前了,这样更符合习惯上的使用规律。
class
TextSurface:
public
DisplaySurface
{
public :
TextSurface( const std:: string & msg_name, const std:: string & message, const ScreenSurface & screen,
Uint8 r = 0xFF , Uint8 g = 0xFF , Uint8 b = 0xFF ,
int ttf_size = 28 , const std:: string & ttf_fileName = " times.ttf " );
~ TextSurface();
};
{
public :
TextSurface( const std:: string & msg_name, const std:: string & message, const ScreenSurface & screen,
Uint8 r = 0xFF , Uint8 g = 0xFF , Uint8 b = 0xFF ,
int ttf_size = 28 , const std:: string & ttf_fileName = " times.ttf " );
~ TextSurface();
};
(在DisplaySurface里相应的构造函数也做类似的修改,略)
3.2:回顾SDL事件轮询
SDL_PollEvent()的作用,是事件一旦被触发,就会响应一次,注意它的响应并不是连续不断的。比如你按下某个键,即触发了一次事件。即使你按着不松开,也仅仅是触发了一次,所以SDL_PollEvent()也只响应一次。
下面的程序,演示键盘事件中,方向键被按下后的反馈信息。
3.3:演示程序
//
UVi Soft (2008)
// Long Fei (lf426), E-mail: zbln426@163.com
#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 ;
const std:: string WINDOW_NAME = " Key Presses " ;
ScreenSurface screen(SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_NAME);
// Fill background.(default is black)
screen.fillColor();
screen.flip();
// Load a textSurface
TextSurface upMessage( " upMsg " , " Up was pressed. " , screen);
TextSurface downMessage( " downMsg " , " Down was pressed. " , screen, 0xFF , 0 , 0 );
TextSurface leftMessage( " leftMsg " , " Left was pressed. " , screen, 0 , 0xFF , 0 );
TextSurface rightMessage( " rightMsg " , " Right was pressed. " , screen, 0 , 0 , 0xFF );
TextSurface otherMessage( " otherMsg " , " Other key was pressed. " , screen, 100 , 100 , 100 , 35 );
// Main loop.Press ESC or click X to quit.
bool gameOver = false ;
SDL_Event gameEvent;
int x = 200 ;
int y = 200 ;
while ( gameOver == false ){
while ( SDL_PollEvent( & gameEvent) != 0 ){
if ( gameEvent.type == SDL_KEYDOWN ){
screen.fillColor();
switch ( gameEvent.key.keysym.sym ){
case SDLK_UP:
upMessage.blit(x, y -- );
break ;
case SDLK_DOWN:
downMessage.blit(x, y ++ );
break ;
case SDLK_LEFT:
leftMessage.blit(x -- , y);
break ;
case SDLK_RIGHT:
rightMessage.blit(x ++ , y);
break ;
default :
otherMessage.blit(x, y);
}
screen.flip();
}
if ( gameEvent.type == SDL_QUIT ){
gameOver = true ;
}
if ( gameEvent.type == SDL_KEYUP ){
if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
gameOver = true ;
}
}
}
}
return 0 ;
}
// Long Fei (lf426), E-mail: zbln426@163.com
#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 ;
const std:: string WINDOW_NAME = " Key Presses " ;
ScreenSurface screen(SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_NAME);
// Fill background.(default is black)
screen.fillColor();
screen.flip();
// Load a textSurface
TextSurface upMessage( " upMsg " , " Up was pressed. " , screen);
TextSurface downMessage( " downMsg " , " Down was pressed. " , screen, 0xFF , 0 , 0 );
TextSurface leftMessage( " leftMsg " , " Left was pressed. " , screen, 0 , 0xFF , 0 );
TextSurface rightMessage( " rightMsg " , " Right was pressed. " , screen, 0 , 0 , 0xFF );
TextSurface otherMessage( " otherMsg " , " Other key was pressed. " , screen, 100 , 100 , 100 , 35 );
// Main loop.Press ESC or click X to quit.
bool gameOver = false ;
SDL_Event gameEvent;
int x = 200 ;
int y = 200 ;
while ( gameOver == false ){
while ( SDL_PollEvent( & gameEvent) != 0 ){
if ( gameEvent.type == SDL_KEYDOWN ){
screen.fillColor();
switch ( gameEvent.key.keysym.sym ){
case SDLK_UP:
upMessage.blit(x, y -- );
break ;
case SDLK_DOWN:
downMessage.blit(x, y ++ );
break ;
case SDLK_LEFT:
leftMessage.blit(x -- , y);
break ;
case SDLK_RIGHT:
rightMessage.blit(x ++ , y);
break ;
default :
otherMessage.blit(x, y);
}
screen.flip();
}
if ( gameEvent.type == SDL_QUIT ){
gameOver = true ;
}
if ( gameEvent.type == SDL_KEYUP ){
if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
gameOver = true ;
}
}
}
}
return 0 ;
}