我们可以把表面想象成一张画布,
blit
表面就是把一个表面的某个区域
COPY
到另外一个表面上去。
//The headers
#include " SDL.h"
#include <string>
以上就是我们需要的头文件了。
//The attributes of the screen
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
3
个描述屏幕属性的变量
SCREEN_BPP
是颜色深度,就是每个象素用多少为来表示,我们这里用
4
个字节。
//The surfaces that will be used
SDL_Surface *message = NULL;
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
接着我们又定义了
3
个表面,一个用于显示背景,一个用于显示
Hello World
,还有一个当然是代表屏幕了。
SDL_Surface *load_image( std::string filename )
{
//Temporary storage for the image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
好了,我们可以写一个自己的图像装载函数,该函数负责
Load
图片,并返回一个经过优化的表面,当然图片已经在表面上了。
//Load the image
loadedImage = SDL_LoadBMP( filename.c_str() );
首先我们使用
SDL_LoadBMP()
函数
Load
一张
BMP
格式的图片。应为位图是
24
位,所以我们不应该立即使用该表面,因为屏幕是
32
位的。如果在二各具有不同
format
表面进行
Blit
,那么
SDL
将会不停地进行格式之间的转换,程序就会变得很慢。
.
if( loadedImage != NULL )
{
//Create an optimized image
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old image
SDL_FreeSurface( loadedImage );
}
以上几行代码检查了图片是否被正确加载了,如果有错误的话,那么
loadedImage
将是
NULL
。
SDL_DisplayFormat()
用于创建一个和屏幕表面相同格式的
Surface
。之所以这样做就是为了加快程序速度,避免
SDL
类库在对二个不同格式表面进行
Blit
时进行格式转换。
好了,现在我们拥有二个表面了,一个上面有图片,还有一个是前一个经过格式转换得到的。
因为第一表面我们不需要了,所以我们就要释放掉,
SDL_FreeSurface()
函数就是干这件事情的。
//Return the optimized image
return optimizedImage;
}
好了,我们返回经过优化的表面。
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
//Make a temporary rectangle to hold the offsets
SDL_Rect offset;
//Give the offsets to the rectangle
offset.x = x;
offset.y = y;
接下来,我们再写一个
Blit
函数。
X,Y
是目标表面的偏移量,另外二个自然是要进行
Blit
的二个表面了。
首先我们把偏移量塞入到一个
SDL_Rect
变量里面,这样做的原因很简单,就是
SDL_BlitSurface
只接受
SDL_Rect
结构中的偏移。
SDL_Rect
结构代表一个长方形
.
它有四个成员,左上角的坐标,长和宽。
//Blit the surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
好了,调用
SDL_BlitSurface
实现
Blit
。第二个参数是源表面的要被
Blit
的区域,我们用
NULL
表示要对整个源表面进行
Blit
。
int main( int argc, char* args[] )
{
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return 1;
}
在
SDL_Init()
函数中,我们使用
SDL_INIT_EVERYTHING
参数,表示我们希望启动所有
SDL
子系统,其中包括,视频,声音,时间,以及其他一些制作游戏所用到的组建。
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
现在我们用
SDL_SetVideoMode
函数新建一个窗口,它返回一个指向窗口表面的指针,这样我们就可以把图像往屏幕上
Blit
了。
if( screen == NULL )
{
return 1;
}
如果函数有问题的话,就返回
NULL
。下面我们也可以改变一下窗口的标题。
SDL_WM_SetCaption( "Hello World", NULL );
message = load_image( "hello_world.bmp" );
background = load_image( "background.bmp" );
apply_surface( 0, 0, background, screen );
现在我们把背景
Blit
到屏幕上,在
Blit
背景之前,窗口是黑色,如下图。
再这之后,窗口的背景就改变了。
用同样的方法,我们把
message
也
Blit
到屏幕上去。
apply_surface( 180, 140, message, screen );
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
虽然我们把背景表面和消息表面都
Blit
到屏幕表面上去了,窗口还是一片漆黑,因为我们没有调用
SDL_Flip
函数来更新窗口,记住,屏幕表面是建立在系统内存当中的。
SDL_Delay( 2000 );
好了,让窗口停顿二秒,以免我们什么也不到。
//Free the surfaces
SDL_FreeSurface( message );
SDL_FreeSurface( background );
//Quit SDL
SDL_Quit();
//Return
return 0;
}
好了,我们的主函数也写完了,最后我释放了二个表面,并调用了
SDL_Quit
函数,清理我们所使用到其他资源。
好了,运行一下程序,你不意外你就能看到如下的效果了。如果有什么错误的话,看看第一个教程。