用SDL写游戏

SDL( Simple DirectMedia Layer)是一个跨平台的multimedia library ,包含了对video,audio,keyboard,mouse的支持。
它的接口比较简洁,你甚至不需要知道Win32 API,就可以写出游戏来。它封装了跟
平台相关的部分。它使我想起了TC下面的graphics BGI

官方地址:   http://www.libsdl.org/

下面是我用SDL写的一个小游戏
run.jpg


1.骨架程序

#include  " sdl.h "
#pragma comment(lib,
" sdl.lib " )
#pragma comment(lib,
" sdlmain.lib " )

int  main( int  argc, char   **  argv)
{
    
// Init SDL
    SDL_Init( SDL_INIT_VIDEO );
    atexit(SDL_Quit);
    screen 
=  SDL_SetVideoMode( 400 , 480 , 0 ,SDL_SWSURFACE);
    SDL_WM_SetCaption(
" RUN " ,NULL);

    
// load resource
    
//

    
bool  pause  =   false ;
    
bool  gone  =   true ;

    SDL_Event 
event ;
    
while (gone)
    {
        
if (SDL_PollEvent( & event ) > 0 )
        {
            
if ( event .type  ==  SDL_QUIT)
            {
                
break ;
            }
            
else   if ( event .type  ==  SDL_KEYDOWN)
            {
        
// handle event
        
//
            }
            
else   if ( event .type  ==  SDL_KEYUP)
            {
        
// handle event
        
//
            }
        }
        
else   if ( ! pause)
        {
            run(); 
        }
    }

    
// release resource
    
//
     return   0 ;
}


SDL_Init : 初始化子系统
SDL_SetVideoMode:设置分辨率
SDL_WM_SetCaption: 设置窗口标题
SDL_PollEvent:查询事件,用户的输入

2.表面的概念

表面(SDL_Surface)是SDL中一个重要的概念,精灵都是保存在表面中

SDL_Surface  *  temp  =  SDL_CreateRGBSurface(SDL_SRCCOLORKEY, w, h,  32 ,
                
0 0 0 0 );
            
rc.x 
=  x  *  w ;
rc.y 
=  y  *  h;
            
SDL_BlitSurface(surf,
& rc,temp, 0 );
           
SDL_SetColorKey(temp,SDL_SRCCOLORKEY,transcolor);

SDL_CreateRGBSurface 创建一个表面
SDL_BlitSurface 表面之间的copy
SDL_SetColorKey 设定表面的透明色

ps:主表面是由SDL_SetVideoMode返回的,也可以通过 SDL_GetVideoSurface查询到

3. 声音的使用

游戏离不开声音,SDL也提供了支持

void  play_sound( const   char   * file)
{
    
int  index;
    SDL_AudioSpec wave;
    Uint8 
* data;
    Uint32 dlen;
    SDL_AudioCVT cvt;

    
/*  寻找一个空的(或者完成了的)音频口  */
    
for  ( index = 0 ; index < NUM_SOUNDS;  ++ index ) {
        
if  ( sounds[index].dpos  ==  sounds[index].dlen ) {
            
break ;
        }
    }
    
if  ( index  ==  NUM_SOUNDS )
        
return ;

    
/*  加载声音文件,并转换成16位、立体声、22kHz格式  */
    
if  ( SDL_LoadWAV(file,  & wave,  & data,  & dlen)  ==  NULL ) {
        fprintf(stderr, 
" 无法加载 %s: %s\n " , file, SDL_GetError());
        
return ;
    }
    SDL_BuildAudioCVT(
& cvt, wave.format, wave.channels, wave.freq,
                            AUDIO_S16,   
2 ,              22050 );
    cvt.buf 
=  (unsigned  char   * )malloc(dlen * cvt.len_mult);
    memcpy(cvt.buf, data, dlen);
    cvt.len 
=  dlen;
    SDL_ConvertAudio(
& cvt);
    SDL_FreeWAV(data);

    
/*  将音频数据放入音频口(立刻开始回放了)  */
    
if  ( sounds[index].data ) {
        free(sounds[index].data);
    }
    SDL_LockAudio();
    sounds[index].data 
=  cvt.buf;
    sounds[index].dlen 
=  cvt.len_cvt;
    sounds[index].dpos 
=   0 ;
    SDL_UnlockAudio();
}

4.一些有用的模块

#include  " sdl_image.h "

/*
 * Return the pixel value at (x, y)
 * NOTE: The surface must be locked before calling this!
 
*/
Uint32 getpixel(SDL_Surface 
* surface,  int  x,  int  y)
{
    
int  bpp  =  surface -> format -> BytesPerPixel;
    
/*  Here p is the address to the pixel we want to retrieve  */
    Uint8 
* =  (Uint8  * )surface -> pixels  +  y  *  surface -> pitch  +  x  *  bpp;

    
switch (bpp) {
    
case   1 :
        
return   * p;

    
case   2 :
        
return   * (Uint16  * )p;

    
case   3 :
        
if (SDL_BYTEORDER  ==  SDL_BIG_ENDIAN)
            
return  p[ 0 <<   16   |  p[ 1 <<   8   |  p[ 2 ];
        
else
            
return  p[ 0 |  p[ 1 <<   8   |  p[ 2 <<   16 ;

    
case   4 :
        
return   * (Uint32  * )p;

    
default :
        
return   0 ;        /*  shouldn't happen, but avoids warnings  */
    }
}


/*
 * Set the pixel at (x, y) to the given value
 * NOTE: The surface must be locked before calling this!
 
*/
void  putpixel(SDL_Surface  * surface,  int  x,  int  y, Uint32 pixel)
{
    
int  bpp  =  surface -> format -> BytesPerPixel;
    
/*  Here p is the address to the pixel we want to set  */
    Uint8 
* =  (Uint8  * )surface -> pixels  +  y  *  surface -> pitch  +  x  *  bpp;

    
switch (bpp) {
    
case   1 :
        
* =  pixel;
        
break ;

    
case   2 :
        
* (Uint16  * )p  =  pixel;
        
break ;

    
case   3 :
        
if (SDL_BYTEORDER  ==  SDL_BIG_ENDIAN) {
            p[
0 =  (pixel  >>   16 &   0xff ;
            p[
1 =  (pixel  >>   8 &   0xff ;
            p[
2 =  pixel  &   0xff ;
        } 
else  {
            p[
0 =  pixel  &   0xff ;
            p[
1 =  (pixel  >>   8 &   0xff ;
            p[
2 =  (pixel  >>   16 &   0xff ;
        }
        
break ;

    
case   4 :
        
* (Uint32  * )p  =  pixel;
        
break ;
    }
}

bool  showpic(SDL_Surface  * surface, const   char   * filename)
{
    SDL_Surface 
* image;

    
/*  Load the BMP file into a surface  */
    image 
=  IMG_Load(filename);
    
if  (image  ==  NULL) {
        fprintf(stderr, 
" Couldn't load %s: %s\n " ,filename,SDL_GetError());
        
return   false ;
    }

    
/*  Blit onto the screen surface  */
    
if (SDL_BlitSurface(image, NULL, surface, NULL)  <   0 )
        fprintf(stderr, 
" BlitSurface error: %s\n " , SDL_GetError());

    SDL_UpdateRect(surface, 
0 0 , image -> w, image -> h);

    
/*  Free the allocated BMP surface  */
    SDL_FreeSurface(image);

    
return   true ;
}

SDL_Surface
*  createsurf( const   char   *  filename)
{
    SDL_Surface 
* image;

    
/*  Load the BMP file into a surface  */
    image 
=  IMG_Load(filename);
    
if  (image  ==  NULL) {
        fprintf(stderr, 
" Couldn't load %s: %s\n " ,filename,SDL_GetError());
        
return   0 ;
    }

    
return  image;
}

getpixel 取得像素的颜色
putpixel 画点
showpic 加载一个图片到某个表面
createsurf 从文件中创造表面

SDL有大量的示例和第三方库可以使用,非常的不错
最后推荐一个SDL写的超级玛丽游戏
http://smclone.sourceforge.net/



你可能感兴趣的:(用SDL写游戏)