#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 );
}