科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件送给初学者的礼物:游戏编程起源连载二 (2)

送给初学者的礼物:游戏编程起源连载二 (2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

送给初学者的礼物:游戏编程起源连载二 (2)

作者:ant3000 来源:http://bbs.bc-cn.net 2007年11月8日

关键字: 起源 游戏编程 Linux

  • 评论
  • 分享微博
  • 分享邮件

位图

想要往程序里添加图象,通过位图资源可能是最简单的办法了。位图是Windows之本,当然提供了一些函数来处理位图,请记住,如果你使用了太多的位图,你的EXE文件将要非常巨大。在资源脚本中设置位图同图标和光标没什么区别:









[identifier] BITMAP [filename]

有一个函数LoadBitmap(),同LoadCursor()和LoadIcon()的用法很相似,它将得到一个句柄,由于我还没有讲过图形(graphics),就不具体说函数的功能了,你可以猜一猜它是怎样工作的,一旦你得到了图形句柄,你将怎样使用它呢?更多的留待以后再讲。不要担心,现在只是要你有点儿准备。下面看看我们还应该学点儿什么。

字符串表格

字符串表

字符串表是我最喜欢的资源类型。正象你所想的:一个充满字符串的庞大表格。字符串表有很多用处。你可以用它存储你的文件名称,游戏中的人物对话,消息框中的文本,菜单中的文本等等。在资源脚本里建立一个字符串表很容易,就像这样:

STRINGTABLE
{
// entries go here
}

一个字符串表由几部分组成:一个标识字符串的数字;紧跟着一个逗号;然后是加了双引号的字符串本身。字符串表里的字符串被允许使用溢出符号,如

或 。注意,字符串表本身并没有标识符,所以每个程序只能有一个字符串表。一个简单的字符串表可能象下面这个样子:

// program information
STRINGTABLE
{
    1, "3D Space Game v1.0"
    2, "Written by The Masked Coder"
    3, "(C) 2000 WienerDog Software"
}

从程序的字符串表里调用字符串,将使用——你可能猜到了——LoadString()函数。这是它的原形:

int LoadString(
    HINSTANCE hInstance, // handle to module containing string resource
    UINT uID,            // resource identifier
    LPTSTR lpBuffer,     // pointer to buffer for resource
    int nBufferMax       // size of buffer
);

函数返回的实数是字符的数量,不包括空字符,它将被赋值到程序数据段的缓冲区中去,相当于字符串的长度。如果你调用了一个空字符串或者调用失败,都将返回0。下面来看看具体参数:

※ HINSTANCE hInstance:同以前的一样,你所有操纵项目的句柄。

※ UINT uID:你想要调用的字符串的数码标识符。

※ LPTSTR lpBuffer:指向接收字符串的字符数组的指针。

※ int nBufferMax:缓冲区的字节长度。如果被调用的字符串的长度大于缓冲区的长度,字符串将被按照缓冲区的大小缩减。

例如,调用“WienerDog Software’s copyright”的信息,代码应该如下:

char buffer[80];
LoadString(hinstance, 3, buffer, sizeof(buffer));

尽管在资源脚本中字符串使用数字声明,而不是标识符,但我通常在使用字符串表时,习惯于在头文件中用#define定义一下字符串的声明数字。针对上面的代码,我可能加一行:

#define ST_WIENERDOGCOPYRIGHT 3

这样一来,用LoadString()函数时,你的程序代码更容易读懂,也使你的思路更加清晰。但也并不是意味着你必须为字符串表里的每一个字符串都定义一个常量标识符。当字符串表相当大时,或者你感觉记不清时,就应该定义常量标识符。我通常在每个常量标识符的前面加上一个前缀ST_。具体的说,ST_FILENAMES作为存储文件名称字符串的索引,ST_DIALOGUE作为人物对话字符串的索引,等等。

菜单

这是我们要讲的最后一个Windows资源,当然,不是为了凑数才讲的哦。窗口的菜单条紧接在标题栏的下发显示,这个菜单有时被称为“主菜单”或“顶层菜单”。菜单通常在建立窗口类时被调用。还记得吗?上一章中窗口类建立过程中,有这样一行:

sampleClass.lpszMenuName = NULL;

如果你正在建立一个窗口程序,并希望有菜单,你就得需要用到菜单资源。它的脚本文件可能要复杂一点儿,但下面是一个最基本的框架:

[identifier] MENU
{
    POPUP [menu name]
    {
        MENUITEM [item name], [identifier]
    }
}

[identifier]标识符是你知道的:一个字符串或一个数字常量。在MENU的大括号中,可以有一个或者几个POPUP(弹出式)菜单,每一个都有一个下拉菜单,[menu name]中填入菜单名称。在POPUP的大括号中,可以有一个或者多个菜单条,[item name]中填入菜单条名称,后面必须跟着一个数字常量的标识符。(所谓数字常量的标识符,就是用#define定义过的标识符。如:#define MENUID_NEW 101)如果你还想在菜单里建立热键,就要用(&)符号。在你想成为热键的字符前加上&,例如,你想用Alt+F代替用鼠标点击File按钮,你就应该写成 &File ,菜单的名称都要用双引号引上。看看下面的例子就更清楚了:

MAIN_MENU MENU
{
    POPUP "&File"
    {
        MENUITEM "&New", MENUID_NEW
        MENUITEM "&Open...", MENUID_OPEN
        MENUITEM "&Save", MENUID_SAVE
        MENUITEM "Save &As...", MENUID_SAVEAS
        MENUITEM "E&xit", MENUID_EXIT
    }

    POPUP "&Help"
    {
        MENUITEM "&Contents", MENUID_CONTENTS
        MENUITEM "&Index...", MENUID_INDEX
        MENUITEM "&About", MENUID_ABOUT
    }
}

你还可以在POPUP下建立子菜单,你自己琢磨吧,我就不讲了,我们还得往下进行。获得菜单资源的句柄,我们需要用LoadMenu()函数,它的原形如下:

HMENU LoadMenu(
    HINSTANCE hInstance, // handle to application instance
    LPCTSTR lpMenuName   // menu name string or menu-resource identifier
);

现在你应该已经熟悉这些参数了。第一个参数是你的程序实例的句柄,第二个是你的菜单资源的标识符。如果你使用了数字常量作为标识符,别忘了使用MAKEINTRESOURCE()这个宏转换一下哦!现在,你有两个方法为窗口创建菜单。第一个方法是在创建窗口类时直接设置:

sampleClass.lpszMenuName = LoadMenu(hinstance, MAKEINTRESOURCE(MAIN_MENU));

第二个方法是在设置窗口类时,让lpszMenuName等于NULL,以后再加入菜单。当你要建立两个独立的菜单,而又不想定义不同的窗口类时,这个选择是很有意义的,你需要用SetMenu()函数:

BOOL SetMenu(
    HWND hWnd,   // handle to window
    HMENU hMenu, // handle to menu
);
查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章