Nebula2探秘14-nGuiServer的创建与使用

本文详细介绍了Nebula2中的nGuiServer组件,包括其创建、初始化及事件注册过程。通过实例展示了如何在Nebula2中集成并使用nGuiServer创建GUI控件,以及设置皮肤和画刷等。

Nebula2探秘14-nGuiServer的创建与使用

happykevins文

关于nGui:
nGui是Nebula2本身集成的GUI系统。虽然Radon在mangalore中已经集成了对CEGUI的支持,但是nGui相比之下更加简单易用,而且紧密地与Nebula2结合,不存在CEGUI诸多的兼容性问题。另外其天生支持中文,所以在制作简单的游戏UI时可以考虑使用nGui系统。CEGUI是一个非常流行的开源的GUI系统,目前版本是0.5,虽然Bug很多而且不支持中文(网上已有很多的解决方案),但是其功能强大,并且CEGUI社区正在积极制作其相关工具,想要制作精美且复杂的UI系统的话可以考虑使用。在之后的教程中我会介绍在Nebula2中集成CEGUI的方法。

nGui的维护:
像一般的NebulaServers一样,nGui的创建过程大概分为3步:1.向Kernel添加ngui包;2.在kernel中创建nguiserver;3.调用nguiserver的初始化方法(Open)。另外在游戏循环中每帧都需要调用Trigger的方法以保证ngui正确处理用户输入,这需要有ninputserver的支持。最后在程序结束前要调用Close()方法以确保ngui正确释放资源。

nGui的初始化:
nGui的过程分为3步:1.设置nGui的skin。2.定制画刷列表。3.添加用户控件。其中前两个步骤Nebula2在startup.tcl中已经提供了默认的实现,用户也可以自由替换这些信息以实现自己期待的效果。添加用户控件可以通过两个途径来实现:1.通过kernelserver的new来创建。2.通过guiserver的newwindow来创建。其实他们本质上没有什么区别,guiserver也是通过kernelserver来创建的,只不过帮你维护了当前rootwindow的noh路径而已,nGui的所有控件都存放在noh的"/res/gui"下。

nGui的事件注册:
nGui的事件可以通过每个控件的SetXXCammond(cmd_name)来注册(XX为事件类型),传入参数cmd_name为脚本中对应的事件处理函数名,使用起来非常方便。

程序代码如下:

/****************************************************************************/
/*Nebula2-Tutorial14*/
/*UsingnGuiServer*/
/*author:happykevins*/
/****************************************************************************/

///----------------------------------------------------------------------------
///+必要头文件

//nebula2includes
#include"kernel/nkernelserver.h"
#include
"kernel/nfileserver2.h"
#include
"script/ntclserver.h"
#include
"gfx2/nd3d9server.h"
#include
"gfx2/ncamera2.h"
#include
"gui/nguiserver.h"
#include
"tools/nmayacamcontrol.h"
#include
"scene/nsceneserver.h"

#include
"gui/nguiwindow.h"
#include
"gui/nguilabel.h"
#include
"gui/nguitextlabel.h"
#include
"gui/nguitextbutton.h"

#include
"../NebulaUtils/nutildefs.h"
#include
"../NebulaUtils/nkernelinfo.h"

///-必要头文件
///----------------------------------------------------------------------------

///----------------------------------------------------------------------------
///+链接库
#pragmacomment(lib,"wsock32.lib")
#pragmacomment(lib,"d_microtcl.lib")
#pragmacomment(lib,"d_nkernel.lib")
#pragmacomment(lib,"d_nnebula.lib")
#pragmacomment(lib,"d_ntoollib.lib")
#pragmacomment(lib,"d_ngui.lib")

#pragmacomment(lib,"dxguid.lib")
#pragmacomment(lib,"dxerr9.lib")
#pragmacomment(lib,"d3d9.lib")
#pragmacomment(lib,"d3dx9d.lib")
#pragmacomment(lib,"dinput8.lib")

#pragmacomment(lib,"d_ndinput8.lib")
#pragmacomment(lib,"d_ndirect3d9.lib")
///-链接库
///----------------------------------------------------------------------------

///----------------------------------------------------------------------------
///+声明使用的Nebula2Package&Module
nNebulaUseModule(ntclserver);
nNebulaUseModule(nresource);
nNebulaUseModule(nresourceserver);
nNebulaUseModule(ninputserver);

nNebulaUseModule(nfont2);
nNebulaUseModule(nmesh2);
nNebulaUseModule(nmesharray);
nNebulaUseModule(nshader2);
nNebulaUseModule(ntexture2);
nNebulaUseModule(ngfxserver2);

nNebulaUseModule(nsceneserver);
nNebulaUseModule(nshadowserver2);
nNebulaUseModule(nscenenode);
nNebulaUseModule(ntransformnode);
nNebulaUseModule(nabstractcameranode);
nNebulaUseModule(nclippingcameranode);
nNebulaUseModule(nreflectioncameranode);

nNebulaUseModule(nvariableserver);
nNebulaUseModule(nconserver);

nNebulaUsePackage(ngui);
nNebulaUsePackage(ndirect3d9);
nNebulaUsePackage(ndinput8);
///-声明使用的Nebula2Package&Module
///----------------------------------------------------------------------------
nCamera2cam;
nMayaCamControlccam;
nKernelInfoHelperks_info(NULL);
nTclServer
*tcl=NULL;
nKernelServer
*ks=NULL;
nD3D9Server
*gfx2=NULL;
nInputServer
*input=NULL;
nSceneServer
*scene=NULL;
nGuiServer
*gui=NULL;

///----------------------------------------------------------------------------
///+添加GUI控件
///
voidSetupGUI()
{
constfloatborderSize=0.02f;
//createadummyrootwindow
//gui->SetRootWindowPointer(0);
nGuiWindow*userRootWindow=gui->NewWindow("nguiwindow",true);
n_assert(userRootWindow);
rectanglenullRect(vector2(
0.0f,0.0f),vector2(1.0f,1.0f));
userRootWindow
->SetRect(nullRect);

//nGuiWindow*userRootWindow=gui->GetRootWindowPointer();

ks
->PushCwd(userRootWindow);

//createlogolabel
nGuiLabel*rightLabel=(nGuiLabel*)ks->New("nguilabel","RightLogo");
n_assert(rightLabel);
vector2rightLabelSize
=gui->ComputeScreenSpaceBrushSize("n2logo");
rectanglerightRect;
rightRect.v0.
set(1.0f-rightLabelSize.x-borderSize,1.0f-rightLabelSize.y-borderSize);
rightRect.v1.
set(1.0f-borderSize,1.0f-borderSize);
rightLabel
->SetRect(rightRect);
rightLabel
->SetDefaultBrush("n2logo");
rightLabel
->SetPressedBrush("n2logo");
rightLabel
->SetHighlightBrush("n2logo");
rightLabel
->OnShow();

//createahelptextlabel
nGuiTextLabel*textLabel=(nGuiTextLabel*)ks->New("nguitextlabel","HelpLabel");
n_assert(textLabel);
textLabel
->SetText("Esc:系统菜单请不要点击"Har/Scn/Dis/Cha" 由于没有连接以上服务,会导致程序崩溃!");
textLabel
->SetFont("GuiSmall");
textLabel
->SetAlignment(nGuiTextLabel::Left);
textLabel
->SetColor(vector4(1.0f,1.0f,1.0f,1.0f));
textLabel
->SetClipping(false);
vector2textExtent
=textLabel->GetTextExtent();
rectangletextRect(vector2(
0.0f,0.0f),textExtent);
textLabel
->SetRect(textRect);
textLabel
->OnShow();

//createacustombutton
nGuiTextButton*toggleBtn=(nGuiTextButton*)ks->New("nguitextbutton","ToggleBtn");
n_assert(toggleBtn);
toggleBtn
->SetText("系统菜单");
toggleBtn
->SetCommand("UIEvent_ToggleBtn");//脚本中的函数名
toggleBtn->SetFont("GuiSmall");
toggleBtn
->SetAlignment(nGuiTextButton::Center);
toggleBtn
->SetRect(rectangle(vector2(0.0f+borderSize,1-0.1f+borderSize),vector2(0.15f-borderSize,1.0f-borderSize)));
toggleBtn
->SetDefaultBrush("button_n");
toggleBtn
->SetPressedBrush("button_p");
toggleBtn
->SetHighlightBrush("button_h");
toggleBtn
->OnShow();

ks
->PopCwd();

//setthenewuserrootwindow
gui->SetRootWindowPointer(userRootWindow);

}
///
///+添加GUI控件
///----------------------------------------------------------------------------

///----------------------------------------------------------------------------
///+初始化环境,创建需要的Server
///
boolInitApp()
{
///创建KernelServer
ks=n_new(nKernelServer);

///----------------------------------------------------------------------------
///+向KernelServer中添加Package&Module
nNebulaAddModule(ntclserver);
nNebulaAddModule(nresource);
nNebulaAddModule(nresourceserver);
nNebulaAddModule(ninputserver);

nNebulaAddModule(nfont2);
nNebulaAddModule(nmesh2);
nNebulaAddModule(nmesharray);
nNebulaAddModule(nshader2);
nNebulaAddModule(ntexture2);
nNebulaAddModule(ngfxserver2);

nNebulaAddModule(nsceneserver);
nNebulaAddModule(nshadowserver2);
nNebulaAddModule(nscenenode);
nNebulaAddModule(ntransformnode);
nNebulaAddModule(nabstractcameranode);
nNebulaAddModule(nclippingcameranode);
nNebulaAddModule(nreflectioncameranode);

nNebulaAddModule(nvariableserver);
nNebulaAddModule(nconserver);

ks
->AddPackage(ndinput8);
ks
->AddPackage(ngui);
ks
->AddPackage(ndirect3d9);
///+向KernelServer中添加Package&Module
///----------------------------------------------------------------------------

///获得FileServer设置shaders的路径
nFileServer2*file=(nFileServer2*)ks->Lookup("sys/servers/file2");
///设置系统路径
file->SetAssign("home","bin:../../");
file
->SetAssign("renderpath","home:datafiles/shaders");
file
->SetAssign("shaders","renderpath:fixed");
file
->SetAssign("scripts","home:datafiles/scripts");

///创建tclserver
tcl=(nTclServer*)ks->New("ntclserver","/sys/servers/script");
///创建ResourceServer
ks->New("nresourceserver","/sys/servers/resource");
///创建variableserver
ks->New("nvariableserver","/sys/servers/variable");
///创建guiserver(RenderPath依赖)
gui=(nGuiServer*)ks->New("nguiserver","/sys/servers/gui");
///创建ConsoleServer(RenderPath依赖)
ks->New("nconserver","/sys/servers/console");
///创建InputServer(GuiServer依赖)
input=(nInputServer*)ks->New("ndi8server","/sys/servers/input");
///创建D3D9Server
gfx2=(nD3D9Server*)ks->New("nd3d9server","/sys/servers/gfx");
///创建sceneserver
scene=(nSceneServer*)ks->New("nsceneserver","/sys/servers/scene");
///创建shadowserver
ks->New("nshadowserver2","/sys/servers/shadow");

///初始化显示模式
nDisplayMode2mode;
mode.SetXPos(
150);
mode.SetYPos(
100);
mode.SetWidth(
640);
mode.SetHeight(
480);

///将显示模式应用到d3d9server
gfx2->SetDisplayMode(mode);
gfx2
->SetCamera(cam);

///启动sceneserver(启动d3d9server)
scene->SetRenderPathFilename("renderpath:dx7_renderpath.xml");
if(!scene->Open())
{
returnfalse;
}

///启动GUIServer
nStringret;
tcl
->RunScript("scripts:T14_GuiServer.tcl",ret);
gui
->Open();

///启动InputServer
input->Open();
ret.Clear();
tcl
->RunFunction("OnT14MapInput",ret);

///设置GUI环境
SetupGUI();

returntrue;
}
///
///+初始化环境,创建需要的Server
///----------------------------------------------------------------------------

///----------------------------------------------------------------------------
///+初始化环境,创建需要的Server
///
boolCloseApp()
{
///关闭GUIServer
gui->Close();
///关闭sceneserver(关闭d3d9server)
scene->Close();

///销毁KernelServer
n_delete(ks);

returntrue;
}
///
///+初始化环境,创建需要的Server
///----------------------------------------------------------------------------

///----------------------------------------------------------------------------
///+Application
intmain(intargc,constchar**argv)
{
///初始化Application
if(!InitApp())
{
n_error(
"程序初始化失败! ");
return0;
}

ks_info.SetKernelServer(ks);
ks_info.LogNOH(
"/");

///这里相当于游戏循环,gfx2->Trigger()将触发win32的消息泵
while(gfx2->Trigger()&&tcl->Trigger())
{
///TriggerTimeServer
nTimeServer::Instance()->Trigger();
doubletime=nTimeServer::Instance()->GetTime();

///TriggerInputServer
input->Trigger(time);

///处理GUI事件,需要inputserver的支持
gui->Trigger();

///BeginScene(BeginFrame)
if(scene->BeginScene(ccam.GetViewMatrix()))
{
//RenderScene
scene->RenderScene();

//EndScene
scene->EndScene();

//PresentScene(EndFrame)
scene->PresentScene();
}

///FlushEvents
input->FlushEvents();

n_sleep(
0.00f);
}

///释放资源
if(!CloseApp())
{
n_error(
"释放资源失败! ");
return0;
}

return0;
}
///-Application
///----------------------------------------------------------------------------

脚本代码如下:

#-------------------------------------------------------------------------------
#T14_GuiServer.tcl
#
#ThisisextractfromthethecentralNebularuntimestartupscript
#whichisusedforNebula2TutorialGuiServer
#
#ThescriptmainlysetsupthenGuiVariablesandMapInputs
#
#(C)2003RadonLabsGmbH
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#OnGuiServerOpen
#
#ThisfunctioniscalledwhentheNebula2GUIserverisopened.
#-------------------------------------------------------------------------------

procOnGuiServerOpen{}{
setcwd[psel]

#工具提示
#initializethedefaulttooltip

setguiRoot[/sys/servers/gui.getrootpath]
sel
$guiRoot
newnguitooltipTooltip
selTooltip
.setdefaultbrush"tooltip"
.setfont"GuiSmall"
.setcolor0001
.setalignment"left"
.setborder0.0050.005
sel
..

#设置Gui外观相关信息
#definethesystemskin

setskin[/sys/servers/gui.newskinsystem]
sel
$skin
#settexturepathpre-andpostfix(NOTE:don'tchangepathtotextures:system!!!)
.settextureprefix"home:datafiles/textures/system/"
.settexturepostfix".dds"

#activeandinactivewindowmodulationcolor
.setactivewindowcolor1.01.01.01.0
.setinactivewindowcolor0.60.60.60.6
.setbuttontextcolor0.00.00.01.0
.settitletextcolor0.00.00.01.0
.setlabeltextcolor0.00.00.01.0
.setentrytextcolor0.00.00.01.0
.settextcolor0.00.00.01.0
.setmenutextcolor0.00.00.01.0

#####################################################################
#+添加画刷
#
#definebrushes

.beginbrushes

#windowtitlebar,windowbackground,tooltipbackground
.addbrushtitlebarskin6615210201.01.01.01.0
.addbrushwindowskin8154441.01.01.01.0
.addbrushtooltipskin8154441.01.00.8780.8
.addbrushpinkskin8154441.00.01.01.0
.addbrushdragboxskin8154441.00.80.80.5

#textentryfield
.addbrushtextentry_nskin446124880.70.70.71.0
.addbrushtextentry_pskin446124880.80.80.81.0
.addbrushtextentry_hskin446124880.90.90.91.0
.addbrushtextcursorskin446124880.40.40.41.0

#thewindowclosebutton
.addbrushclose_nskin3884016161.01.01.01.0
.addbrushclose_hskin4044016161.01.01.01.0
.addbrushclose_pskin4204016161.01.01.01.0

#thewindowsizebutton
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值