SDL学习之2

#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>

///表面
SDL_Surface *g_screenSurface = NULL;//主表面
SDL_Surface *g_Buffer  = NULL;//后台缓冲区页面
SDL_Surface *g_backface  = NULL;//背景页面
SDL_Surface *g_maskface  = NULL;//蒙版页面

//蒙版矩形图片所占据位置变化点
SDL_Rect rBuffer;

long m_lMain_Pitch ;

const int XSIZE = 800;//497;
const int YSIZE = 600;//357;

///  
Uint32 timeLeft(void);//时间控制
void init(void);
void shutDown(void);
void loadRes(void);//装载背景
void OnKeyDown(int key);
void render();
///
int main(int argc, char *argv[])
{

 init();

    bool bDone = false;
 
    while( bDone == false )
    {
        SDL_Event event;
  
        while( SDL_PollEvent( &event ) )
        {
            if( event.type == SDL_QUIT ) 
                bDone = true;
   
            if( event.type == SDL_KEYDOWN )
            {
                if( event.key.keysym.sym == SDLK_ESCAPE )
                    bDone = true;
    OnKeyDown(event.key.keysym.sym);
            }
        }
  
        render();
    }
 
    shutDown();
 return 0;
}
///
void OnKeyDown(int key)
{
 switch(key)
 {
 case SDLK_a:
  //左
  rBuffer.x--; 
  rBuffer.x=rBuffer.x-3;
  if (rBuffer.x<=3) {
   rBuffer.x = 3;
  }
  break;
 case SDLK_s:
  //下
  rBuffer.y++;
  rBuffer.y = rBuffer.y+3;
  if (rBuffer.y>=(g_backface->h-g_maskface->h)) {
   rBuffer.y = g_backface->h-g_maskface->h;
  }
  break;
 case SDLK_d:
  //右
  rBuffer.x++;
  rBuffer.x=rBuffer.x+3;
  if ( rBuffer.x > (g_backface->w-g_maskface->w) )
   rBuffer.x=g_backface->w-g_maskface->w;
  //if ( rBuffer.y > (387-120) ) rBuffer.y=387-120;
  break;
 case SDLK_w:
  //上
  rBuffer.y--;
  rBuffer.y = rBuffer.y-3;
  if (rBuffer.y<=3) {
   rBuffer.y = 3;
  }
  break; 
 }
}
///
void init( void )
{
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "Unable to init SDL: %s/n", SDL_GetError() );
        exit(1);
    }
 
    atexit( SDL_Quit );
 创建主表面///
 g_screenSurface = SDL_SetVideoMode( XSIZE, YSIZE, 32, SDL_HWSURFACE);
 
    if( g_screenSurface == NULL )
    {
        printf( "Unable to set  video: %s/n", SDL_GetError() );
        exit(1);
    }
 
 //m_lMain_Pitch = g_screenSurface->pitch>>2;

 创建后台缓冲区页面///
    if ((g_Buffer = SDL_CreateRGBSurface (
  SDL_SWSURFACE,
  g_screenSurface->w,
  g_screenSurface->h,
  g_screenSurface->format->BitsPerPixel,
  g_screenSurface->format->Rmask,//0x000000ff,
  g_screenSurface->format->Gmask,//0x0000ff00,
  g_screenSurface->format->Bmask,//0x00ff0000,
  g_screenSurface->format->Amask//0xff000000
  )) == NULL)
  return;
 
 rBuffer.x = 0;                                              
 rBuffer.y = 0;           
 rBuffer.w = 120;      
 rBuffer.h = 120;
 
 //加载资源
 loadRes();
 ///启动键盘连击//
 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
}
///
void loadRes( void )
{
 /加载背景图
 g_backface = SDL_LoadBMP("girl.bmp");
 if( g_backface == NULL )
    {
        fprintf(stderr, "Couldn't load /"back.bmp/"", SDL_GetError());
        return;
    }

 g_maskface = SDL_LoadBMP("lg.bmp");
 if( g_maskface == NULL )
    {
        fprintf(stderr, "Couldn't load /"LIGHT.BMP/"", SDL_GetError());
        return;
    }
}

///
Uint32 timeLeft( void )
{
    static Uint32 timeToNextUpdate = 0;
    Uint32 currentTime;
 
    currentTime = SDL_GetTicks();
 
    if( timeToNextUpdate <= currentTime )
    {
        timeToNextUpdate = currentTime + UPDATE_INTERVAL;
        return 0;
    }
    return( timeToNextUpdate - currentTime );
}
///
void shutDown( void )
{
    SDL_FreeSurface( g_screenSurface );
 SDL_FreeSurface( g_Buffer );
 SDL_FreeSurface( g_backface );
 SDL_FreeSurface( g_maskface );
}
///
void render()
{
 SDL_Delay( timeLeft() );
 SDL_BlitSurface( g_backface, NULL, g_Buffer, NULL );
 
 //锁定页面, 进行alpha_blend操作
 SDL_LockSurface(g_Buffer);
 SDL_LockSurface(g_maskface);

 register  Uint32 *d = (Uint32 *)g_Buffer->pixels;
    register  Uint32 *s = (Uint32 *)g_maskface->pixels;
 //得到每一行的像素点数为pitch
 long mpitch = g_maskface->pitch>>2;//这里有问题....总的不到正确的pitch值
 long bpitch = g_Buffer->pitch>>2;
 
  //关键步骤在此,实现alpha混合
 int alpha;
 int ispos , idpos;

 register Uint32 sr,sg,sb,dr,dg,db,sc,dc ;
 
 for (int y=0; y<g_maskface->h; y++)
 {
  idpos=(y+rBuffer.y)*bpitch+rBuffer.x;//gBuffer像素点位置
  ispos=y*mpitch;//g_maskface像素点位置

  for (int x=0; x<g_maskface->w; x++)
  {
   sc = (Uint32)s[ispos++];
   alpha = (int)((sc & 0xff000000)>>24) >> 3 ;
      
   dc = (Uint32)d[idpos];
   
   sr = (sc & 0xFF0000) >> 16 ;
   dr = (dc & 0xFF0000) >> 16 ;
   dr = ((sr * alpha) + (dr *(32-alpha))) >> 5 ;
   
   sg = (sc & 0xFF00) >> 8 ;
   dg = (dc & 0xFF00) >> 8 ;
   dg = ((sg * alpha) + (dg *(32-alpha))) >> 5 ;
   
   sb = sc & 0xFF;
   db = dc & 0xFF;
   db = ((sb * alpha) + (db *(32-alpha))) >> 5 ;
   
   d[idpos++] = (dr <<16)|(dg<<8)|db ;
   
  }
 }
 //
 SDL_UnlockSurface(g_maskface); 
 SDL_UnlockSurface(g_Buffer);

 SDL_BlitSurface( g_Buffer, NULL, g_screenSurface,  NULL);
 
 SDL_Flip( g_screenSurface );
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值