SDL游戏开发教程05(显示文字和其他格式的图片)--DirectFB

wqeq



     本节将介绍如何加载其他格式的图片,同时,介绍如何显示文字。效果图如下
  

 
 其中背景图片是我从网上下载的一张JPG图片,已经将它上传在了附件中。

 

 

显示其它格式图片:

 

要显示png、jpg、gif等格式的图片,我们需要下载SDL_image库

http://www.libsdl.org/projects/SDL_image/


 
 
 下载上图中标记出来的文件,然后解压。

1、将解压后include目录下的SDL_image.h文件拷贝到C:\MinGW\include\SDL目录下

2、将解压后include目录下的SDL_image.lib文件拷贝到C:\MinGW\lib目录下

3、将解压后include目录下的所有dll文件拷贝到C:\MinGW\bin目录下。

注意:我在这样做的时候出现了一个问题,当程序写好之后,在Eclipse下面运行报找不到驱动程序的错误,但自己手动进入到生成的EXE目录中双击运行程序没有问题。后来我将include目录下的所有dll文件拷贝到C:\WINDOWS\system32就好了,如果你也遇到和我一样的问题,可以参考这种解决方法。至于造成这个问题的原因,暂时还不清楚。

 

经过上面的准备,我们可以开始写代码了,其实加载图片的代码很简单。

Cpp代码   收藏代码
  1. SDLSurfacePtr SDLVideo::LoadImage(std::string fileName)  
  2. {  
  3.     SDL_Surface *surface = IMG_Load(fileName.c_str());  
  4.     if(NULL == surface)  
  5.     {  
  6.         throw SDLException(std::string("IMG_Load加载图片时发生错误:") + SDL_GetError());  
  7.     }  
  8.     return SDLSurfacePtr(new SDLSurface(surface));  
  9. }  

 通过比较原来加载BMP格式图片的代码

Cpp代码   收藏代码
  1. SDLSurfacePtr   SDLVideo::LoadBMP(std::string file)  
  2. {  
  3.     SDL_Surface *surface = SDL_LoadBMP(file.c_str());  
  4.     if(NULL == surface)  
  5.     {  
  6.         throw SDLException(std::string("SDL_LoadBMP加载BMP图片时发生错误:") + SDL_GetError());  
  7.     }  
  8.   
  9.     return SDLSurfacePtr(new SDLSurface(surface));  
  10. }  

     其实就一个地方不同,一个用的是IMG_load函数,一个是SDL_LoadBMP函数。这里将加载图片的函数放到了SDLVideo类中。如果需要加载其他格式的图片调用LoadImage函数就可以了,同时LoadImage也可以加载BMP格式的图片,所以在这里LoadBMP函数基本上没什么用处了。

 

    我们下一步要做的就是封装一个专门加载图片的类SDLImageManager,用来对加载的图片进行管理,这里主要是对图片进行缓冲,避免频繁的访问硬盘,提高程序效率。头文件:

Cpp代码   收藏代码
  1. #ifndef RESOURCEMANAGER_H_  
  2. #define RESOURCEMANAGER_H_  
  3.   
  4. #include "SDLSurface.h"  
  5. #include <map>  
  6. class SDLImageManager  
  7. {  
  8.     friend class SDL;  
  9. private:  
  10.     SDLImageManager();  
  11. public:  
  12.     virtual ~SDLImageManager();  
  13. public:  
  14.     //获取图片  
  15.     SDLSurfacePtr loadImage(std::string fileName);  
  16.   
  17.     //获取图片,并将图片中的某种颜色去掉,使去掉的那部分颜色为透明,这样就不会覆盖掉底层图片的颜色  
  18.     //详细介绍见http://lazyfoo.net/SDL_tutorials/lesson05/index.php  
  19.     SDLSurfacePtr loadImageWithoutColor(std::string fileName, Uint8 r, Uint8 g, Uint8 b );  
  20. private:  
  21.     std::map<std::string, SDLSurfacePtr>  buffer;  
  22.   
  23. };  
  24.   
  25. #endif /* RESOURCEMANAGER_H_ */  
 

其中loadImage用来获取一张图片,成员变量buffer用来缓冲已经加载的图片。loadImageWithoutColor的功能主要是去除图片的底色,避免底色覆盖掉底层图片的颜色,这样解释可能不好懂,我也没有什么更好的办法,大家可以去http://lazyfoo.net/SDL_tutorials/lesson05/index.php,上面有详细的介绍。

    源文件:

Cpp代码   收藏代码
  1. #include "SDLImageManager.h"  
  2. #include "SDLCore.h"  
  3. #include <boost/lexical_cast.hpp>  
  4.   
  5. SDLImageManager::SDLImageManager()  
  6. {  
  7.   
  8. }  
  9.   
  10. SDLImageManager::~SDLImageManager()  
  11. {  
  12.   
  13. }  
  14.   
  15. SDLSurfacePtr SDLImageManager::loadImage(std::string fileName)  
  16. {  
  17.     //先到缓冲区去找  
  18.     std::map<std::string, SDLSurfacePtr>::iterator it = buffer.find(fileName);  
  19.     //如果找到就返回  
  20.     if(it != buffer.end())  
  21.     {  
  22.         return it->second;  
  23.     }  
  24.   
  25.   
  26.     //否则从硬盘加载图片  
  27.     SDLSurfacePtr loadedImage = SDL::video()->LoadImage( fileName.c_str() );  
  28.   
  29.     //将文件格式调整成程序需要的格式  
  30.     SDLSurfacePtr image = SDL::video()->DisplayFormat( loadedImage );  
  31.   
  32.     //放入缓冲区  
  33.     buffer.insert(std::make_pair(fileName, image));  
  34.   
  35.     return image;  
  36. }  
  37.   
  38. SDLSurfacePtr SDLImageManager::loadImageWithoutColor(std::string fileName, Uint8 r, Uint8 g, Uint8 b )  
  39. {  
  40.     /** 
  41.      * 根据文件名和要去除的颜色生成一个唯一的键, 
  42.      * 在缓冲区类同文件名,但一个是原图,一个是去除某种颜色的图可能共存, 
  43.      * 所以这里用fileName作为键值有可能覆盖掉缓冲区中的原图。 
  44.      * 存储每种颜色分量的空间是一个字节,所以最大数据不会超过255,这里简单的乘上1000就可以满足要求了。 
  45.      * 比如这里传入的参数是aaa.jpg, 255, 255, 255;那么得到的结果就是aaa.jpg255255255。 
  46.      * 这里boost::lexical_cast是boost里面一个常用的函数,用来做数据之间的转换。 
  47.      */  
  48.     std::string key = fileName  
  49.         + boost::lexical_cast<std::string>(r*1000*1000)  
  50.         + boost::lexical_cast<std::string>(g*1000)  
  51.         + boost::lexical_cast<std::string>(b);  
  52.     std::map<std::string, SDLSurfacePtr>::iterator it = buffer.find(key);  
  53.     if(it != buffer.end())  
  54.     {  
  55.         return it->second;  
  56.     }  
  57.   
  58.     SDLSurfacePtr loadedImage = SDL::video()->LoadImage( fileName.c_str() );  
  59.     SDLSurfacePtr image = SDL::video()->DisplayFormat( loadedImage );  
  60.     Uint32 colorKey = SDL::video()->MapRGB(image->value()->format, r, g, b);  
  61.     SDL::video()->SetColorKey(image, SDL_SRCCOLORKEY, colorKey);  
  62.     buffer.insert(std::make_pair(key, image));  
  63.   
  64.     return image;  
  65. }  

 加载图片的相关准备工作已经完成。

 

 

显示文字:

要显示true type字体,我们需要下载SDL_ttf库。http://www.libsdl.org/projects/SDL_ttf/
  
 
 
   然后按照上面介绍SDL_image的方法,将下载下来的文件放到相应的目录下。这边不再重述。

为了管理字体,我们同上面一样也新建了一个SDLFontManager类

Cpp代码   收藏代码
  1. #ifndef SDLFONTMANAGER_H_  
  2. #define SDLFONTMANAGER_H_  
  3.   
  4. #include "SDLFont.h"  
  5. class SDLFontManager  
  6. {  
  7.     friend class SDL;  
  8. private:  
  9.     SDLFontManager();  
  10. private:  
  11.     /** 
  12.      * 初始化TTF环境 
  13.      */  
  14.     void Init();  
  15. public:  
  16.     virtual ~SDLFontManager();  
  17. public:  
  18.     /** 
  19.      * 打开字体 
  20.      * name     字体文件路径 
  21.      * size     待打开字体的大小 
  22.      */  
  23.     SDLFontPtr OpenFont(std::string name, int size);  
  24. };  
  25.   
  26. #endif /* SDLFONTMANAGER_H_ */  
 
Cpp代码   收藏代码
  1. #include "SDLFontManager.h"  
  2.   
  3. SDLFontManager::SDLFontManager()  
  4. {  
  5.     // TODO Auto-generated constructor stub  
  6.   
  7. }  
  8.   
  9. SDLFontManager::~SDLFontManager()  
  10. {  
  11.     TTF_Quit();//退出TTF环境  
  12. }  
  13.   
  14. void SDLFontManager::Init()  
  15. {  
  16.     if(TTF_WasInit())  
  17.     {  
  18.         return;  
  19.     }  
  20.   
  21.     if(-1 == TTF_Init())  
  22.     {  
  23.         throw SDLException(std::string("TTF_Init初始化TTF库时发生错误:") + SDL_GetError());  
  24.     }  
  25. }  
  26.   
  27. SDLFontPtr SDLFontManager::OpenFont(std::string name, int size)  
  28. {  
  29.     TTF_Font *font = TTF_OpenFont(name.c_str(), size);  
  30.     if(NULL == font)  
  31.     {  
  32.         throw SDLException(std::string("TTF_OpenFont打开字体时发生错误:") + SDL_GetError());  
  33.     }  
  34.     return SDLFontPtr(new SDLFont(font));  
  35. }  

 上面的代码很简单,初始化TTF环境 -> 打开字体 ->退出TTF环境

其中SDLFontPtr的定义为

Cpp代码   收藏代码
  1. typedef boost::shared_ptr<SDLFont> SDLFontPtr;  

 由于字体打开后需要关闭,所以这里用了智能指针,在SDLFontPtr不再被使用的时候,它会调用SDLFont的delete函数。SDLFont的定义

Cpp代码   收藏代码
  1. #ifndef SDLFONT_H_  
  2. #define SDLFONT_H_  
  3. #include <SDL/SDL_ttf.h>  
  4. #include "boost/shared_ptr.hpp"  
  5. #include "SDLSurface.h"  
  6. #include <string>  
  7. #include "SDLException.h"  
  8. class SDLFont  
  9. {  
  10.     friend class SDLFontManager;  
  11. private:  
  12.     SDLFont(TTF_Font *font);  
  13. public:  
  14.     virtual ~SDLFont();  
  15. public:  
  16.     /** 
  17.      * 渲染字体 
  18.      * message  文字内容 
  19.      * color    文字颜色 
  20.      */  
  21.     SDLSurfacePtr RenderTextSolid(std::string message, SDL_Color color);  
  22.     SDLSurfacePtr RenderUNICODESolid(std::string message, SDL_Color color);  
  23.     SDLSurfacePtr RenderUNICODEBlended(std::string message, SDL_Color color);  
  24.     SDLSurfacePtr RenderUNICODEShaded(std::string message, SDL_Color fg, SDL_Color bg);  
  25.   
  26.     /** 
  27.      * 获取和设置字体的样式 
  28.      */  
  29.     int  GetFontStyle();  
  30.     void SetFontStyle(int style);//参见SDL/SDL_ttf.h中的宏定义  
  31. private:  
  32.     /* 
  33.      * 获取message中包含的Unicode字符个数 
  34.      * 如果message="你好abc", 则返回5 
  35.      * 如果message="你好啊", 则返回3 
  36.      */  
  37.     int getUnicodeCharCountByGb2312(std::string message);  
  38.     /** 
  39.      * 将GB2312编码转换成UNICODE编码 
  40.      */  
  41.     Uint16 * getUnicodeByGb2312(std::string message);  
  42. private:  
  43.     TTF_Font *font;  
  44. };  
  45. typedef boost::shared_ptr<SDLFont> SDLFontPtr;  
  46. #endif /* SDLFONT_H_ */  
Cpp代码   收藏代码
  1. #include "SDLFont.h"  
  2. #include <iostream>  
  3. SDLFont::SDLFont(TTF_Font *font)  
  4. {  
  5.     this->font = font;  
  6. }  
  7.   
  8. SDLFont::~SDLFont()  
  9. {  
  10.     if (font != NULL)  
  11.     {  
  12.         TTF_CloseFont(font);  
  13.     }  
  14. }  
  15.   
  16. SDLSurfacePtr SDLFont::RenderTextSolid(std::string message, SDL_Color color)  
  17. {  
  18.     SDL_Surface* image = TTF_RenderText_Solid(font, message.c_str(), color);  
  19.     if (image == NULL)  
  20.     {  
  21.         throw SDLException(std::string("TTF_RenderText_Solid渲染字体时发生错误:")  
  22.                 + SDL_GetError());  
  23.     }  
  24.     return SDLSurfacePtr(new SDLSurface(image));  
  25. }  
  26.   
  27. SDLSurfacePtr SDLFont::RenderUNICODESolid(std::string message, SDL_Color color)  
  28. {  
  29.     Uint16 * text = getUnicodeByGb2312(message);  
  30.     SDL_Surface* image = TTF_RenderUNICODE_Solid(font, text, color);  
  31.     delete[] text;  
  32.     if (image == NULL)  
  33.     {  
  34.         throw SDLException(std::string("TTF_RenderUNICODE_Solid渲染字体时发生错误:")  
  35.                 + SDL_GetError());  
  36.     }  
  37.     return SDLSurfacePtr(new SDLSurface(image));  
  38. }  
  39.   
  40.   
  41. int SDLFont::getUnicodeCharCountByGb2312(std::string message)  
  42. {  
  43.     int     number = 0;  
  44.     for (unsigned int i = 0; i < message.length(); i++)  
  45.     {  
  46.         //判断最高位是不是0,如果是0表示是一个ASCII码,否则是一个汉字  
  47.         //一个汉字占用两个字符,所以变量i需要++  
  48.         if ((message.at(i) & 0x80) != 0)  
  49.         {  
  50.             i++;  
  51.         }  
  52.         number++;  
  53.     }  
  54.   
  55.     return number;  
  56. }  
  57.   
  58. Uint16 * SDLFont::getUnicodeByGb2312(std::string message)  
  59. {  
  60.         /** 
  61.          * 获取字符串中包含的UNICODE字符数量,主要是为了后面转换时分配内存 
  62.          * 这里其实不用精确具体的个数,只要保证chNum大于实际的个数就行了 
  63.          * 因为一个汉字占用两个字节,所以这里用int chNum = message.length()也可以 
  64.          * 如果message中不含汉字,则message.length()==getUnicodeCharCountByGb2312(message) 
  65.          * 如果message含有汉字,则message.length()>getUnicodeCharCountByGb2312(message) 
  66.          */  
  67.         int chNum = getUnicodeCharCountByGb2312(message);  
  68.         //int chNum = message.length();  
  69.   
  70.         wchar_t * wmessage=new wchar_t[chNum];  
  71.         char *chset = setlocale(LC_CTYPE,"chs");//设置当前字符集,返回字符集的描述  
  72.         if(chset == NULL)//如果返回NULL,表示该环境中没有这种字符集  
  73.         {  
  74.             throw SDLException("setlocale设置当前环境为简体中文时发生错误,可能是系统不支持简体中文:");  
  75.         }  
  76.   
  77.         //将GB2312转换成UNICODE字符集  
  78.         //返回实际转换的UNICODE字符个数  
  79.         int wchNum = mbstowcs(wmessage,message.c_str(),chNum);  
  80.         if(wchNum == -1)//如果里面包含了非法的GB2312字符编码  
  81.         {  
  82.             throw SDLException(std::string("mbstowcs中文字符转UNICODE时发生错误:"));  
  83.         }  
  84.         setlocale(LC_CTYPE,"");//设置回原来的字符集  
  85.   
  86.         Uint16 *text = new Uint16[wchNum+1];  
  87.         text[wchNum] = 0;  
  88.         for (int i = 0; i < wchNum; i++)  
  89.         {  
  90.             text[i] = wmessage[i];  
  91.         }  
  92.         delete[] wmessage;  
  93.   
  94.         return text;  
  95. }  
  96.   
  97. SDLSurfacePtr SDLFont::RenderUNICODEBlended(std::string message, SDL_Color color)  
  98. {  
  99.     Uint16 * text = getUnicodeByGb2312(message);  
  100.     SDL_Surface* image = TTF_RenderUNICODE_Blended(font, text, color);  
  101.     delete[] text;  
  102.     if (image == NULL)  
  103.     {  
  104.         throw SDLException(std::string("TTF_RenderUNICODE_Blended渲染字体时发生错误:")  
  105.                 + SDL_GetError());  
  106.     }  
  107.     return SDLSurfacePtr(new SDLSurface(image));  
  108. }  
  109. SDLSurfacePtr SDLFont::RenderUNICODEShaded(std::string message, SDL_Color fg, SDL_Color bg)  
  110. {  
  111.     Uint16 * text = getUnicodeByGb2312(message);  
  112.     SDL_Surface* image = TTF_RenderUNICODE_Shaded(font, text, fg, bg);  
  113.     delete[] text;  
  114.     if (image == NULL)  
  115.     {  
  116.         throw SDLException(std::string("TTF_RenderUNICODE_Blended渲染字体时发生错误:")  
  117.                 + SDL_GetError());  
  118.     }  
  119.     return SDLSurfacePtr(new SDLSurface(image));  
  120. }  
  121.   
  122. int  SDLFont::GetFontStyle()  
  123. {  
  124.     return TTF_GetFontStyle(font);  
  125. }  
  126.   
  127. void SDLFont::SetFontStyle(int style)  
  128. {  
  129.     TTF_SetFontStyle(font, style);  
  130. }  
 

    SDLFont对TTF库中的函数进行了封装,并且增加了对gb2312格式编码的处理。这里使用的规范是封装SDL库的成员函数开头字母大写,其余的成员函数开头字母小写 ,后面的章节中将继续采用该规范。

    在程序中,像std::string a="你好"这样的代码,编译器会根据系统的默认编码方式对"你好"这个字符串进行存储,我们现在用的系统都是简体中文,所以"你好"在内存中的编码方式一般为简体中文的方式,简体中文的编码方式有多种,这里给函数取的名字和写的注释都是GB2312,但实际的编码方式可能不是这个。只是GB2312比较常见,不管是GB2312还是GB其它的编码格式,mbstowcs都会将它转换成UNICODE编码格式。

    这里用mbstowcs进行编码转换,并不代表只有这一种方式,也不是因为它是最好的,而是由于它使用起来比较简单。网上有很过关于编码转换的讨论,也有一些开源的项目,其中比较出名的是libiconv。我们在这里进行编码转换单纯是为了显示中文,并且是以系统中有简体中文环境为前提,怎样使我们的程序能在其他语言环境中运行,需要对程序做国际化支持的考虑。这里推荐Gettext项目。

 

    上面怎么加载图片和显示文字的准备工作都已经做好,下一步是怎么使用这些类进行显示。代码如下

Cpp代码   收藏代码
  1. #include "Lesson02.h"  
  2.   
  3. Lesson02::Lesson02()  
  4. {  
  5.     // TODO Auto-generated constructor stub  
  6.   
  7. }  
  8.   
  9. Lesson02::~Lesson02()  
  10. {  
  11.     // TODO Auto-generated destructor stub  
  12. }  
  13.   
  14. void Lesson02::onRender()  
  15. {  
  16.     //先绘制背景图片  
  17.     SDL::video()->BlitSurface(image, NULL, screen, NULL);  
  18.   
  19.     //将文字显示在screen的中央  
  20.     SDL_Rect rect;  
  21.     rect.x = screen->value()->w/2 - message->value()->w/2;  
  22.     rect.y = screen->value()->h/2 - message->value()->h/2;  
  23.     SDL::video()->BlitSurface(message, NULL, screen, &rect);  
  24. }  
  25. void Lesson02::onInit()  
  26. {  
  27.     //加载背景图片  
  28.     image = SDL::imageManager()->loadImage("E:\\code_picture\\464d64dd7512752d5982dd84.jpg");  
  29.     //创建字体  
  30.     SDLFontPtr font = SDL::fontManager()->OpenFont("E:\\code_picture\\wqy-zenhei.ttc", 20);  
  31.     //设置字体样式  
  32.     font->SetFontStyle(TTF_STYLE_UNDERLINE | TTF_STYLE_ITALIC);  
  33.   
  34.     //渲染文字,这里的两种颜色一个是前景色,一个是背景色  
  35.     //渲染文字后返回的其实就是一张图片,和loadImage加载的图片没什么两样  
  36.     message = font->RenderUNICODEShaded("大家好(Hello, Everybody)"  
  37.             , SDL::assistant()->makeColor(0, 0, 0)  
  38.             , SDL::assistant()->makeColor(255, 0, 0));  
  39.   
  40.     //大家可以试试下面注释掉的这两行代码,看看他们的不同效果  
  41.     /*message = font->RenderUNICODESolid("大家好(Hello, Everybody)", SDL::assistant()->makeColor(255, 0, 0)); 
  42.     message = font->RenderUNICODEBlended("大家好(Hello, Everybody)", SDL::assistant()->makeColor(255, 0, 0)); 
  43. */  
  44.   
  45. }  

     由于我们前期的准备工作比较充分,所以到具体使用的时候代码就很简单,这里不再做解释。其中wqy-zenhei.ttc是文泉驿字体,网上有相关介绍,你也可以使用C:\WINDOWS\Fonts目录下随便一个可以支持中文的字体,比如simhei.ttf。

 

最后,需要添加连接选项,增加SDL_image和SDL_ttf,如下图:

 

最后重新编译整个工程即可。这里贴出来并不是全部代码,而是一些比较重要的代码,完整的代码见附件。


     本节将介绍如何加载其他格式的图片,同时,介绍如何显示文字。效果图如下
  

 
 其中背景图片是我从网上下载的一张JPG图片,已经将它上传在了附件中。

 

 

显示其它格式图片:

 

要显示png、jpg、gif等格式的图片,我们需要下载SDL_image库

http://www.libsdl.org/projects/SDL_image/


 
 
 下载上图中标记出来的文件,然后解压。

1、将解压后include目录下的SDL_image.h文件拷贝到C:\MinGW\include\SDL目录下

2、将解压后include目录下的SDL_image.lib文件拷贝到C:\MinGW\lib目录下

3、将解压后include目录下的所有dll文件拷贝到C:\MinGW\bin目录下。

注意:我在这样做的时候出现了一个问题,当程序写好之后,在Eclipse下面运行报找不到驱动程序的错误,但自己手动进入到生成的EXE目录中双击运行程序没有问题。后来我将include目录下的所有dll文件拷贝到C:\WINDOWS\system32就好了,如果你也遇到和我一样的问题,可以参考这种解决方法。至于造成这个问题的原因,暂时还不清楚。

 

经过上面的准备,我们可以开始写代码了,其实加载图片的代码很简单。

 通过比较原来加载BMP格式图片的代码

     其实就一个地方不同,一个用的是IMG_load函数,一个是SDL_LoadBMP函数。这里将加载图片的函数放到了SDLVideo类中。如果需要加载其他格式的图片调用LoadImage函数就可以了,同时LoadImage也可以加载BMP格式的图片,所以在这里LoadBMP函数基本上没什么用处了。

 

    我们下一步要做的就是封装一个专门加载图片的类SDLImageManager,用来对加载的图片进行管理,这里主要是对图片进行缓冲,避免频繁的访问硬盘,提高程序效率。头文件:

 

其中loadImage用来获取一张图片,成员变量buffer用来缓冲已经加载的图片。loadImageWithoutColor的功能主要是去除图片的底色,避免底色覆盖掉底层图片的颜色,这样解释可能不好懂,我也没有什么更好的办法,大家可以去http://lazyfoo.net/SDL_tutorials/lesson05/index.php,上面有详细的介绍。

    源文件:

 加载图片的相关准备工作已经完成。

 

 

显示文字:

要显示true type字体,我们需要下载SDL_ttf库。http://www.libsdl.org/projects/SDL_ttf/
  
 
 
   然后按照上面介绍SDL_image的方法,将下载下来的文件放到相应的目录下。这边不再重述。

为了管理字体,我们同上面一样也新建了一个SDLFontManager类

Cpp代码   收藏代码
  1. #ifndef SDLFONTMANAGER_H_  
  2. #define SDLFONTMANAGER_H_  
  3.   
  4. #include "SDLFont.h"  
  5. class SDLFontManager  
  6. {  
  7.     friend class SDL;  
  8. private:  
  9.     SDLFontManager();  
  10. private:  
  11.     /** 
  12.      * 初始化TTF环境 
  13.      */  
  14.     void Init();  
  15. public:  
  16.     virtual ~SDLFontManager();  
  17. public:  
  18.     /** 
  19.      * 打开字体 
  20.      * name     字体文件路径 
  21.      * size     待打开字体的大小 
  22.      */  
  23.     SDLFontPtr OpenFont(std::string name, int size);  
  24. };  
  25.   
  26. #endif /* SDLFONTMANAGER_H_ */  
 

 上面的代码很简单,初始化TTF环境 -> 打开字体 ->退出TTF环境

其中SDLFontPtr的定义为

Cpp代码   收藏代码
  1. typedef boost::shared_ptr<SDLFont> SDLFontPtr;  

 由于字体打开后需要关闭,所以这里用了智能指针,在SDLFontPtr不再被使用的时候,它会调用SDLFont的delete函数。SDLFont的定义

 

    SDLFont对TTF库中的函数进行了封装,并且增加了对gb2312格式编码的处理。这里使用的规范是封装SDL库的成员函数开头字母大写,其余的成员函数开头字母小写 ,后面的章节中将继续采用该规范。

    在程序中,像std::string a="你好"这样的代码,编译器会根据系统的默认编码方式对"你好"这个字符串进行存储,我们现在用的系统都是简体中文,所以"你好"在内存中的编码方式一般为简体中文的方式,简体中文的编码方式有多种,这里给函数取的名字和写的注释都是GB2312,但实际的编码方式可能不是这个。只是GB2312比较常见,不管是GB2312还是GB其它的编码格式,mbstowcs都会将它转换成UNICODE编码格式。

    这里用mbstowcs进行编码转换,并不代表只有这一种方式,也不是因为它是最好的,而是由于它使用起来比较简单。网上有很过关于编码转换的讨论,也有一些开源的项目,其中比较出名的是libiconv。我们在这里进行编码转换单纯是为了显示中文,并且是以系统中有简体中文环境为前提,怎样使我们的程序能在其他语言环境中运行,需要对程序做国际化支持的考虑。这里推荐Gettext项目。

 

 

最后重新编译整个工程即可。这里贴出来并不是全部代码,而是一些比较重要的代码,完整的代码见附件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值