用Brew开发游戏,首先要解决的就是菜单的问题。
考虑到Brew自带的IMenuCtl控件因为风格过于一致,并不适合用在游戏当中。游戏需要的是一个自定义的图形化菜单系统。下面,我们就来一步步设计一个简单的图形化菜单。
首先,描述一下菜单的结构,菜单中多个菜单项组成,每个菜单项有两个状态:选中或正常。
typedef struct _GMenuItem
{
int itemCode; //菜单项的ID
int x; //菜单项显示的坐标X
int y; //菜单项显示的坐标Y
IImage *normalIcon; //正常显示的图像
IImage *selectIcon; //选中显示的图像
} GMenuItem;
typedef struct _GMenu
{
GMenuItem * pMenuItems; //菜单项数组
int itemType; //菜单项图像类型(是PNG或BCI)
int itemLocation;//菜单项坐标类型(中点或左上角)
int itemCount; //菜单项的个数
int selectIndex; //当前选中的菜单项索引
} GMenu;
{
int itemCode; //菜单项的ID
int x; //菜单项显示的坐标X
int y; //菜单项显示的坐标Y
IImage *normalIcon; //正常显示的图像
IImage *selectIcon; //选中显示的图像
} GMenuItem;
typedef struct _GMenu
{
GMenuItem * pMenuItems; //菜单项数组
int itemType; //菜单项图像类型(是PNG或BCI)
int itemLocation;//菜单项坐标类型(中点或左上角)
int itemCount; //菜单项的个数
int selectIndex; //当前选中的菜单项索引
} GMenu;
这里要补充说明的是,我采用两个不同的图像表示菜单项的状态,所以整个菜单的图像文件就是2*itemCount个。其实我们也可以将菜单项的图像文件拼成一个大的BMP图像,然后用DrawFrame来显示,可以减小图像文件的数目。
之所以我没有这样做,有两个考虑,一是我希望菜单支持选中图像与未选中图像的尺寸不同,比如未选中是菜单项是60*20,选中后它变成80*30,所以,我增加了一个itemLocation属性,如果itemLocation = GMENU_LOCATION_DEFAULT,表示菜单项的坐标是左上角,反之itemLocation = GMENU_LOCATION_CENTER,表示菜单项的坐标是中点。这样就可以实现选中项浮在未选中项之上的效果。 二是我希望菜单可以支持BCI动画(使用itemType来区别),这样就可以做出更漂亮的菜单效果了。
然后,我们实现几个方法:
//初始化菜单
extern void GMenu_Init(GMenu * pMenu,int count,int type,int location);
//释放菜单资源
extern void GMenu_Release(GMenu *pMenu);
//增加一个菜单项
extern void GMenu_AddItem(GMenu * pMenu,int code,int x,int y,IImage * nIcon,IImage * sIcon);
//绘制菜单
extern void GMenu_Draw(GMenu *pMenu);
//移动菜单项
extern void GMenu_Next(GMenu *pMenu);
extern void GMenu_Prev(GMenu *pMenu);
//获取菜单选中项的ID
extern int GMenu_GetSelectedItemCode(GMenu *pMenu);
extern void GMenu_Init(GMenu * pMenu,int count,int type,int location);
//释放菜单资源
extern void GMenu_Release(GMenu *pMenu);
//增加一个菜单项
extern void GMenu_AddItem(GMenu * pMenu,int code,int x,int y,IImage * nIcon,IImage * sIcon);
//绘制菜单
extern void GMenu_Draw(GMenu *pMenu);
//移动菜单项
extern void GMenu_Next(GMenu *pMenu);
extern void GMenu_Prev(GMenu *pMenu);
//获取菜单选中项的ID
extern int GMenu_GetSelectedItemCode(GMenu *pMenu);
方法实现起来并不困难,我就不再罗嗦了。