TGEA 笔记一

来源:互联网 发布:osx rar解压软件 编辑:程序博客网 时间:2024/05/21 07:53

相信我,最好的文档是它引擎自带的Documentation

 

自带的Demo结构介绍:

Root Directory:

Root/generateAllProjects.bat:运行此文件将创建所有列举在allProjects.txt中的VC工程,在读取工程列表后,此文件将生成工程和解决方案并放到buildFiles文件夹下

Root/allProjects.txt:工程列表

Root/compileAllProjects.bat:运行此文件将编译allProjects.txt中的所有工程

Root/syncShrdConsts.bat:不清楚

Root/Documentation:文档

Root/Engine:包含了TGEA的核心源码,

../bin:包含对高级开发有用的可执行工具如doxygen,nasm assmebly.etc等

../lib:包含编译Torque工程所需要的库,如果要添加其它库可以添加到此文件夹

../Source:此文件夹包含了所有组成TGEA的源代码,以模块的形式组织起来

Root/GameExamples:此文件夹下面的每个文件夹包含一个独立的demo,第个示例都显示了TGEA的特性,你可以在这里创建工程

../AtlasDemo:

../TGEDemoAdvanced:

../Forge:

../Stronghold:一个FPS示例

../T3D:

进入一个Demo以后

/DeleteDSOs.bat:删除子文件夹中所有.dso文件

/DeletePrefs.bat:删除所有preference文件,这些文件通常包含一些如屏幕解析度,声音级别之类的信息

/generateProjects:

/source:

/buildFiles:包含的是工程和解决方案,你可以用VC将它们载入时行编译,也可使用compile.bat在命令行进行编译

/config:包含一些将被其他程序调用的配置信息,如engineDoc.conf是用于Doxygen来产生相关文档的。

/Game:包含了所有组成Game的内容包括脚本(scripts),GUIs,assets,editors

/Game/common:此文件夹与scriptsAndAssets相似,但是此文件夹中的内容是被所有的Game工程共享的,也就是说每个Game中都有这个文件夹且内容相同

/Game/profile:此文件夹中的脚本用于检查你的图形卡与引擎的兼容性

/Game/shaders:此文件夹将存储所有的hlsl文件,可以根据不同的功能建立子文件夹来分类不同的shaders

/Game/scriptsAndAssets:你的game的大部分内容将在这个文件夹中,通常这个文件夹分成client,server,data三个子文件夹

../client:你的客户端脚本和数据将存储在此,通常是逻辑方面和GUIs且不被多个玩家所共享的比如一个选择菜单,或者是动作脚本,在Stronghold中,脚本和输入绑定逻辑及任务被存储在文件夹“scripts”中,GUIs和图片存储在文件夹“ui”中

../data:与游戏场景相关的一切东西将在这里找到,如:3D模型,环境数据(天空,地形),声音文件等,其中,DTS文件用于呈现3D模型,存储在“shapes”文件夹,DIFF文件包含建筑和内景模型,存储在"interiors"文件夹中,OGG和WAV文件为音效文件存储在文件夹"sound"中,

../server:服务器端功能和脚本,

/Game/tools:你的GUI editor,debugger及其他工具,这些将影响到每一个玩家,在你的开发过程中将有大量的时间花在处理这个文件夹上,这个文件夹包含用于建立player,AI,weapon,network connection,core game logic等的脚本

 

建立自己的游戏工程,使用SetupNewProject.exe

SetupNewProject.exe打开后,只需要改动第一项工程名,后面两项不要改。

 

以前的toturial.base就是现在的scriptsAndAssets文件夹

MyGame.exe 必须与main.cs放在一起

 

TorqueScript的运行原理?

TorqueScript与c++工程如何配合工作?

 

TorqueScript将不同功能放到不同文件夹的cs文件中,然后通过exec加载,可将其理解为模块化设计,当需要添加某些功能模块时候,直接添加相关功能的程序保存在.cs文件中。

总是载入文件后执行其中的功能,载入的过程中遇到语句就执行遇到函数则"编译",后面可以调用

如有一个文件test.cs

内容为:

function ontest()

{

echo("hello world");

}

 

我想使用ontest函数,如下

exec("test.cs");//相对或绝对路径

ontest();

 

NL相当于/n

/*********************************************************************************************************/

看看scriptAndAssets的main.cs中做了些什么:

loadDir("common");

这个函数定义在root目录下的main.cs中:

 

执行顺序,先从root目录下的

main.cs

开始执行,经过一些 函数声明和变量赋值,执行到

loadMods($userMods);

执行exec(%token @ "/main.cs")实际上的参数是scriptAndAssets/main.cs,即加载了scriptAndAssets/main.cs

这样就遇到了loadDir("common"),而这个是在root/main.cs中定义的:

function loadDir(%dir)

{

   setModPaths(pushback($userMods, %dir, ";"));

   exec(%dir @ "/main.cs");

}

其中的exec(%dir @ "/main.cs")又加载了common/main.cs

回到loadMods又exec(%token @ "/main.cs"),加载了tools/main.cs,接着调用

parseArgs(),内容为空

属于root/main.cs中,分析命令行参数,接着调用

onStart(),内容为空

属于root/main.cs文件

 

 

脚本通过activatePackage和deactivatePackage实现了类似继承的机制.

最先加载的package作为父类接口.随后加载的作为其子类.以此类推.

在调用时,首先调用最底层的package.具体例子可以在demo工程中搜索activatePackage.

当一个被加载的脚本中,一个函数有多个实现时,会调用离最后被加载的那个函数实现

 

重新整理

首先是root/main.cs开始执行

接着是common的main.cs

接着是scriptAndAssets的main.cs

然后是tools/main.cs

调用结构为:

root/main.cs{

loadMods(){

loadMods{

exec("scriptAndAssets/main.cs"){

loadDir("common"){

exec("common/main.cs"){

}

}

}

}

exec("tools/main.cs");

}

}

 

接着执行parseArgs(),注意到前面的几个main.cs中又几个package并且activatePackage了,

根据“继承机制”,因此应该先调用最后加载的那个,应该是scriptAndAssets/main.cs中的parseArgs了,然后是common中的main.cs中的parseArgs

同理的还有OnStart()和onExit()等

其中的parent::代表的是前一个包,例如按照加载顺序,依次是/scriptAndAssets/main.cs,/common/main.cs,/root/main.cs,

因而/common/main.cs的parseArgs中的parent指的是scriptAndAssets/main.cs中的内容,以此类推

 

如OnStart(),先是调用/scriptAndAssets/main.cs中的OnStart,他的Parent指的是/common/main.cs,因此parent::OnStart调用的是/common/main.cs/OnStart,而他的Parent又指的是root/main.cs,因此又调用root/main.cs/OnStart

最终的执行顺序是root/main.cs/OnStart(),/common/main.cs/OnStart(),scriptAndAssets/main.cs/OnStart()

了解之后,看到的是parseArgs被调用

common/main.cs/parseArgs{

scriptAndAssets/main.cs/parseArgs{

root/main.cs/parseArgs{

//没有特别内容,只是对命令行参数进行判断,以对相关变量进行设置

}

}

}

接下来调用了OnStart(),此函数的调用顺序与前面的parseArgs相同

 

 

 

scriptAndAssets/main.cs/OnStart

{

common/main.cs/OnStart

{

root/main.cs/OnStart

{

//空

}

initDisplayDeviceInfo();

...

exec(common/gameScripts/common.cs);

initializeCommon();//这里面有不少内容

{

/**************************************/

if( $commonInitialized == true )return;

 

GlobalActionMap.bind(keyboard, tilde, toggleConsole);

GlobalActionMap.bind(keyboard, "ctrl p", doScreenShot);

GlobalActionMap.bindcmd(keyboard, "alt enter", "Canvas.toggleFullScreen();","");

GlobalActionMap.bindcmd(keyboard, "alt k", "cls();",  "");

GlobalActionMap.bindCmd(keyboard, "escape", "", "handleEscape();");

 

exec("./audio.cs");exec("./canvas.cs");exec("./cursor.cs");exec("~/gui/profiles.cs");exec("~/gui/cursors.cs");

 

setRandomSeed();setNetPort(0);

initializeCanvas("Torque Game Engine Advanced");//这个要注意一下,canvas.cs中定义的

{

/**************************************/

if($canvasCreated)

{

error("Cannot instantiate more than one canvas!");

return;

}

 

if (!createCanvas(%windowName))//在root/main.cs中

{

error("Canvas creation failed. Shutting down.");

quit();

}

 

$canvasCreated = true;

/**************************************/

}

 

// Common Guis.

exec("~/gui/remap.gui");exec("~/gui/console.gui");exec("~/gui/help.cs");exec("./screenshot.cs");

exec("./scriptDoc.cs");exec("./keybindings.cs");exec("./helperfuncs.cs");

exec("~/clientScripts/metrics.cs");exec("~/clientScripts/recordings.cs");

exec("~/clientScripts/shaders.cs");exec("~/clientScripts/materials.cs");

Canvas.setCursor(DefaultCursor);loadKeybindings();

$commonInitialized = true;

}

/**************************************/

exec("common/unifiedShell/main.cs");

{

/**************************************/

exec("unifiedShell/profiles.cs");

exec("unifiedShell/MainMenuGui.cs");

exec("unifiedShell/OptionsGui.cs");

exec("unifiedShell/OptionsGui.gui");

exec("unifiedShell/GamepadButtonsGui.cs");

exec("unifiedShell/GamepadButtonsGui.gui");

 

exec("unifiedShell/ObjectPickerGui.cs");

exec("unifiedShell/ObjectPickerGui.gui");

/**************************************/

}

exec("common/clentScripts/client.cs");

exec("common/clentScripts/server.cs");

exec("common/gui/guiBreadcrumbsMenu.cs");

}//common/main.cs/OnStart

/*************Initializing MOD: FPS****************/

exec("scriptAndAssets/client/defaults.cs");//缺省配置

exec("scriptAndAssets/server/defaults.cs");

exec("scriptAndAssets/client/prefs.cs");//偏好配置

exec("scriptAndAssets/server/prefs.cs");

exec("scriptAndAssets/client/init.cs");//应该是加载初始化的内容

/*************函数名如下***************/

loadMaterials()

reloadMaterials()

initClient()

loadPlayerPickerData()

loadDefaultMission()

loadMainMenu

/**************************************/

exec("scriptAndAssets/server/init.cs");

/*************函数名如下***************/

initServer()

initDedicated()

/**************************************/

sfxStartup()//common中的,start up the audion system

initServer();

{

initBaseServer();//来自common/server.cs,加载了大量内容

exec("server/scripts/commands.cs");

{

serverCmdToggleCamera()

serverCmdDropPlayerAtCamera()

serverCmdDropCameraAtPlayer()

serverCmdSuicide()

serverCmdPlayCel()

serverCmdPlayDeath()

serverCmdSelectObject()

}

exec("server/scripts/game.cs");

{

//game相关控制,如游戏持续时间,结束所需分数参数设置和Functions that implement game-play

}

}

if ($Server::Dedicated)

initDedicated();

else

initClient();//客户端初始化,来自scriptAndAssets/client/init.cs

{

// The common module provides basic client functionality

initBaseClient();

 

// Use our prefs to configure our Canvas/Window

configureCanvas();//这个

 

//设置窗口标题

if (isObject(Canvas))

Canvas.setWindowTitle(getEngineName() @ " (" @ getVersionString() @ ") - " @ $appName);

 

/// Load client-side Audio Profiles/Descriptions

exec("./scripts/audioProfiles.cs");

}

 

 

}

 

Torquescript基础

Objects:

游戏世界的每个item都是对象,这些对象是用C++定义的但可以通过script访问

对象创建语法:

%var = new ObjectType(Name:CopySource,arg0,..,argn)

{

<datablock = DatablockIdentifier;>

[existing_field0 = InitialValue0;]

...

[existing_fieldM = InitialValueM;]

[dynamic_field0 = InitialValue0;]

...

[dynamic_fieldN = InitialValueN;]

}

 

%var: 用于存储对象句柄

ObjectType:任何定义在引擎或脚本中的从SimObject或者SimObject的子类,从simObject派生的成为游戏世界的物

CopySource:是这个对象的名字,它是个字符串而不是一个变量,不用&或%

arg0,...,argn:是构造函数的参数

datablock: 许多对象(从GameBase派生或GameBase的子类)需要一个datablocks来初始化相关属性

existing_fieldM datablock:相关值或对象的相关属性,existing_field0 = InitialValue0,也就是对这两种属性进行初始化

dynamic_fieldN:创建的新的属性(将只存在于脚本中)

 

句柄(handles)和名称(names):

每个对象都对应着唯一的句柄值,但对象名不一定唯一,如果你又多个对象拥有相同的名字,那么在你引用那个名字只能找到其中的一个

 

属性(fields)和命令(commands)

脚本中的fields和commands相当于c++中的对象成员和方法,访问成员使用"."运算符

TorqueScript允许创建动态属性,动态属性与一个对象的实例相联系,并且可以随意的添加和删除,添加一个动态属性是自动的,如果你试图读取一个不存在的属性将返回空,也没有动态属性被创建,然而当你试图写入一个不存在的属性时,一个匹配的动态属性将被创建,且被赋值

同样的,还支持函数的动态添加。

 

包(Packages)

创建语法

package package_name()

{

function function_definition0()

{

....

}

...

function function_definitionN()

{

...

}

}

需要注意的是:

一个函数可以再多个packages中被定义

一个packages中只能包含函数

datablocks不能包含在包中

用ActivatePackage(package_name)来激活包,用DeactivatePackage(package_name)来使包无效

 

命名空间(Namespaces)

可以在不同的空间定义相同的函数,引用时你将手动选择调用哪个命名空间的函数或者自动调用。

如果你使用::建立一个函数,这并不意味着这个函数属于某个命名空间,如果::前的表达式不是一个类名或空间名,你将创建的只是一个唯一的函数名

原创粉丝点击