[sdlpal]游戏开始界面文字的绘制

看这篇前建议看下这篇文章帮助理解


上一篇简单讲了下开始界面背景图的绘制过程,当然具体的代码细节没完全理解清楚,但是整体思路应该不会差多少。我又看了下文字的绘制,所以这节就是讲文字的绘制思路了,由于文字的绘制更繁琐,代码更多,就不像上节那样把代码贴出来讲了,也是简单讲下思路(可能比上一节还简单…),具体代码细节还没全看懂。日后能花时间看懂就最好了。
进入主题前,我先讲下文字的概念,当然只是个人的理解。在屏幕上显示的文字和在屏幕上显示的图片其实没多大区别,它们都是由一堆像素构成的。事实上计算机只能处理数字,在屏幕上看到的各种花里胡哨的东西,在计算机中都是一堆二进制,它们各不相同,操作控制(甚至连这些控制命令也是一堆二进制,因为这些命令也是存放在计算机中的)它们的逻辑也不同,所以显示出来也各不相同。像素也是一堆二进制。其实我们可以用SDL创建一个空的texture,然后手动在代码中填写它的pixels,这块pixels有宽和高,你只要在不同的位置填上不同的数字(一般是0~255)就行了,然后利用SDL将它绘制到屏幕上。当然,这会很难看,因为你是乱填的,如果你要认认真真的填出你想要的样子,这就要浪费很多时间了。因此,才会出现各种作图软件和绘画软件,你只需要在屏幕上像画画一样将它画出来并保存到一种特定格式的文件中,需要用到的时候再用代码读取出它的像素数据,然后绘制到屏幕上。文字也是像素,但是它有点特殊,一般都是将很多文字保存到一张纹理中,需要用到的时候再按一定的逻辑从这张纹理中找到对应的文字绘制出来,这里的逻辑肯定不比”Hello World”简单。我们肯定见过一些字体文件,像什么font.ttf,这样的文件中保存着字体的一些信息,然后有专门的字体库,像freetype,可以对文件进行解析,然后转换成一张纹理,再然后从这张纹理中选取对应的文字进行显示。


说了一堆废话应该对文字有大概的理解了,下面进入主题,Pal游戏中也有字体文件:wor16.ascwor16.fon。asc文件保存着每个汉字在fon文件中的下标,fon文件保存着字体的位图信息,每个汉字保存到计算机中都是一个唯一的二进制数,通过这个数在asc文件中得到下标,再用这个下标得到字体在fon中的位置,最后得到字体的位图信息,就可以在屏幕上绘制文字了。sdlpal源码中有对这两个文件解析。font.c文件中,我们可以看到3个函数:PAL_LoadISOFont()PAL_LoadEmbeddedFont()PAL_LoadUserFont()。它们分别处理了ISO字体(sdlpal源码中自定的)、游戏内嵌字体(也就是上面提到的那两个字体文件)、和用户定义的字体(我们自己提供的字体文件,好像是在cfg文件中配置的)。对于ISO字体,我们可以看ascci.hfontglyph.h,这里定义了几个数组,数组元素是一大堆数字,具体是如何显示成文字的我也还不太清楚。看上面3个函数的源码,可以知道它们都是将解析出来的数据保存到了unicode_font这个变量中。然后绘制字体的时候时调用下面这个函数:该函数是根据wChar给的字符,从unicode_font中查找对应的字模数据(wChar就是一个下标)。函数内部的具体细节就不讲了,暂时还没弄清楚。

// 将一串文字填充到一个SDL_Surface中(其实就是gpScreen),然后Blit到SDL_Texture中(其实就是gpTexture)
// 再拷贝到SDL_Renderer(其实就是gpRenderer),就可以显示到屏幕上了
void PAL_DrawCharOnSurface(
    uint16_t    wChar,      // 需要显示的文字
    SDL_Surface *lpSurface, // 将文字填充到一个surface,调用的时候这个参数都是gpScreen
    PAL_POS     pos,        // 在屏幕中的位置  
    uint8_t     bColor,     // 字体的颜色:0x00 ~ 0xFF
    BOOL        fUse8x8Font // 是否使用8x8字体(我也不清楚这是什么效果...)
);

上面只是讲了下获取字体的过程(讲的很混乱…),下面讲下游戏开始界面那两个菜单的绘制过程。这里写图片描述
uigame.c中,有个INT PAL_OpeningMenu(VOID)(该函数负责整个开始界面的绘制),里面调用了ui.c中的函数来绘制菜单(也就是两行文字):

WORD
PAL_ReadMenu(
   LPITEMCHANGED_CALLBACK    lpfnMenuItemChanged, // 菜单改变后的回调函数
   LPCMENUITEM               rgMenuItem,       // 菜单选项,里面可配置文字、位置、是否激活等信息
   INT                       nMenuItem,       // 菜单数量
   WORD                      wDefaultItem,         // 默认菜单
   BYTE                      bLabelColor           // 字体颜色
)

上面这个函数又调用了text.c里面的绘制文字函数:

VOID
PAL_DrawText(
   LPCWSTR    lpszText,   // 需要绘制的文字
   PAL_POS    pos,        // 在屏幕中的位置
   BYTE       bColor,     // 字体颜色
   BOOL       fShadow,    // 是否有阴影(阴影其实就是绘制两种不同颜色的字体,错下位就形成了阴影)
   BOOL       fUpdate,   // 是否需要刷新
   BOOL       fUse8x8Font // 是否使用8*8点阵字体
)

而上面这个函数又调用了font.c中的绘制单个字体的函数:

PAL_DrawCharOnSurface() // 该函数在开头有提到

游戏开始界面的文字绘制大致就是这样了,里边的细节没讲到。没完全理清楚是一个原因,还有个原因就是全贴出来说的话就太长太啰嗦了。
后面我会单独写篇用SDL绘制点阵字体的文章,帮助理解这里的一些内容。 : )

猜你喜欢

转载自blog.csdn.net/ALonWol/article/details/81265830
今日推荐