stratagus的ai规则:
stratagus这个高仿war2的程序会分时间段来调用ai的处理函数。它的ai规则主要是用一些ai函数来定义,
比如说某方电脑可以定义对应的ai规则函数,记得是通过类似aidefine, aineed, aiwait, aiattack的函数进行ai规则的定义,比如说aineed 兵种 个数,然后aiwait会阴塞直到程序ai处理到达条件才继续执行后面的ai规则函数,这就可以非常方便的定义各种电脑的ai行为,比如说生产出aineed一些农民,然后等待,够出就会aineed兵营之类,等待够了就aineed多少个兵,aiattack开始尝试出兵攻击玩家.
另外这个游戏的迷雾作法是以地图块记录阵营迷雾表,地图块的unit进出会进行刷新,而迷雾简单地用预处理好的迷雾图块(作法跟地表纹理一样的)进行拼接渲染,这种作法跟当前war3的作法基本一致,只是war3的迷雾图块是实时更新的,迷雾可以动态圆滑过渡(在之前一文章分析过了),而这个迷雾图则只能按格子跳动,不能圆滑渐变。
另外存下一下以前的跟踪流程,以备用。
stratagus流程
一。 脚本Start Game按钮调用 RunMap(mapname)中执行程序中StartMap(map)
二。 程序中CreateGame后GameMainLoop中游戏循环处理.
//---------------------------------------------------------------------------
一。祥细:
1. 脚本初始:
程序通过加载stratagus.lua进行初始设置, 并装载其它脚本,通过
DefineUnitType(..)来定义各种类型unit的属性
2. 渲染初始:
InitVideo()
3. 声音初始:
InitSound() && InitMusic()
4. 加载字体:
LoadFonts()
5. 显示splash:
ShowTitleScreens
6. 单位管理器初始:
UnitManager.Init(); // Units memory management
7. 界面加载:
PreMenuSetup(); // Load everything needed for menus
8. 界面:
在MenuLoop()中加载guichan.lua,这会运行RunProgramStartMenu() //如果是编辑器则是另一函数
创建WarMenu界面,上面Single Player Game按钮绑定RunSinglePlayerGameMenu()函数,
响应后里面再创建另一个WarMenu界面,并绑定Start Game函数为
RunMap(mapname),该函数会调用InitGameVariables遍历调用初始化函数表InitFuncs[]()中每个函数.
最后调用程序的StartMap(map)游戏开始
//---------------------------------------------------------------------------
二。祥细:
1. CreateGame中:
a. 迷雾初始
InitVisionTable
b. .smp地图初始:
执行.smp地图(lua文件来的, 就两行调用DefinePlayerTypes()定义PlayerType和PresentMap()函数设置地图信息)
DefinePlayerTypes("person","nobody","nobody","nobody","nobody","person") //neutral||computer||person||nobody||rescue-passive||rescue-active
PresentMap("Mysterious Dragon Isle", 2, 128, 128, 1)
c. 玩家初始:
遍历16个玩家进行CreatePlayer创建(从Player[]取出), ThisPlayer=Players[NetLocalPlayerNumber];
应用上述b中设置的PlayerType进行team设置(中立=0,电脑=1,玩家=2+i, PlayerRescuePassive及PlayerRescueActive=2+i,)
b. InitUnitTypes
初始type->BuildingRules, type->stats[player](stats->Costs,stats->Variables)
c. .sms地图加载:
执行.sms地图(lua文件来的),其中
用类似以下方法设置几个玩家资源等信息(如下第一个参数0表示玩家号, 本地图有0-5个玩家)
SetStartView(0, 80, 30)
SetPlayerData(0, "Resources", "gold", 2000)
SetPlayerData(0, "Resources", "wood", 1500)
SetPlayerData(0, "Resources", "oil", 1000)
SetPlayerData(0, "RaceName", "orc")
SetAiType(0, "wc2-air-attack")
SetStartView(1, 0, 0)
SetPlayerData(1, "Resources", "gold", 2000)
...
然后LoadTileModels("scripts/tilesets/wasteland.lua")(这个函数同等于直接执行lua脚本)
在wasteland.lua中执行了DefineTileset(...)来设置一堆地形中各图块资源位置
并调用BuildTilesetTables()程序进行处理, 接着调用 Load("scripts/scripts.lua")这个会据当前玩家的playertype来调用不同的ui.lua(human/org)
之后是一堆
SetTile(32, 0, 0, 0)
SetTile(35, 1, 0, 0)
...
作用是HP for walls/ Wood Regeneration
最后是通过
unit = CreateUnit("unit-oil-patch", 15, {7, 5})
这个会据第一个参数来找到对应的type并创建出unit对象,然后刷新unit所处在地块的UnitFieldFlags用于寻路,
以及MapMarkUnitSight刷新视野, 视野的做法有点怪,他是根据角色视野来刷新地块MapField->Visible[属方]是否可见,
然后再从unit所在位置的地块的visible[]来刷新unit->visible[属方],刷新时判断
上次和今次变化,从而得知unit是不是从属方player视野中进出.
SetResourcesHeld(unit, 20000)
unit = CreateUnit("unit-gold-mine", 15, {66, 6})
SetResourcesHeld(unit, 35000)
...
来创建一些资源
d. Map.Init();这个只调用了InitFogOfWar()
e. PlayersInitAi()
遍历16方玩家,产生查询对应aitype信息(有aiscript函数)设置给PlayerAi对象,并将对象绑定给该玩家.
f. InitTriggers()
用于注册条件函数以及要执行的函数。当前调用SinglePlayerTriggers()脚本函数,只注册了胜利或失败条件函数及对应执行处理函数
g. InitPathfinder()
2. GameMainLoop中:
主要是分时段来执行ai处理函数等,具体不写了。。。
posted @
2011-06-24 16:40 flipcode 阅读(445) |
评论 (0) |
编辑 收藏
之前临时看了下mygui,发一下跟踪的信息,以备参考:
一。 创建每个widget, 用所得皮肤进行初始化,
一个皮肤可以由子皮肤以及子控件组合成。
1. 创建皮肤对应的一个贴图并创建皮肤下所有子皮肤(存入mSubSkinChildo数组中, 它们都是使用此相同贴图),并加到mSubSkinChild以及mDrawItems中。
2. 然后设置该皮肤对应的属性值。
3. 创建该皮肤所有子控件(存入widget中的mWidgetChildSkin数组中)
二。将所创建的控件加入到对应的layernode中:
LayerManager::getInstance().attachToLayerNode(_layer, widget);
其中会遍历widget中所有mDrawItems(子皮肤),加到对应的layernode中,
当前子皮肤(SubSkin)使用该widget中的mTexture来创建mRenderItem(在layernode中有映射表按textrue来归类, 其中文字放入mFirstRenderItems,其它放入mSecondRenderItems)
而mRenderItem中也有一个mDrawItems数组,用来存入SubSkin的. 同时mRenderItem中有mVertexBuffer,当渲染时,会遍历所有mDrawItems,将它们收集到mVertexBuffer中进行批次渲染.
三。渲染:
遍历所有mLayerNodes进行渲染
1. 遍历mFirstRenderItems和mSecondRenderItems中所有RenderItem进行渲染
在RenderItem中遍历mDrawItems,调用其doRender()方法,将顶点渲染到mVertexBuffer中.
2. 渲染mChildItems中所有
四。 关于文字的渲染:
simpletext是一个renderitem
simpletext从edittext中派生
edittext::updateRawData会使用mTextView生成贴图uv等数据
每个RenderItem提供一个vertext buf,供其中的数据进行填充批次渲染
文字的渲染由于是一次读入的(老外就是不考虑中文),如果中文修改范围直接用的话则加载时必定卡。。。
而且中文字多,一般不好全部一次存入贴图中,只能使用贴图缓存方式处理。
posted @
2011-06-24 15:47 flipcode 阅读(1067) |
评论 (0) |
编辑 收藏
2d游戏中可以做到局部更新,3d游戏中这种处理已经绝迹了,最近还是尝试弄了下,
3d游戏中界面的局部更新问题
要在3d游戏中使用界面系统的局部更新,需要先准备一块画布,然后界面局部更新时刷新到这块画布上,这样每帧只画画布
虽然之前有想过这样的方法,但一直没去弄过,最近弄了下,碰到的问题在于使用的带透明信息的文字渲染上, 如下:
最近有人再次讨论了这个问题,为了说明这个问题我又重新整理了下,新整理如下:
3d游戏中界面脏矩形碰到的alpha排序问题:
3d游戏中界面脏矩形碰到的alpha排序问题:
界面是一张半透明底图,上面画一些半透明的字,
这里测试我们假设只用一个颜色分量(值范围为0-255)
如下:
scene = 100; // 场景,
tex = 150; // 贴图
text = 200; // 文字
a1 = 0.2f; // 贴图alpha
a2 = 0.3f; // 文字alpha
下面对正常渲染方式和脏矩形渲染方式分别测试结果:
【法一】。正常顺序渲染方法:
dest = (scene*(1-a1)+tex*a1)*(1-a2)+text*a2
= (100*0.2+150*0.8)*0.3+200*0.7
=42+140
=182
【法二】。脏矩形的渲染到贴图方法:
目标贴图rt清为全黑0,alpha为1
1. 先将tex渲染到目标贴图
clr1 = rt*(1-a1)+tex*a1
= tex*a1
= 30
alpha = a1
= 0.2f
2. 然后再渲染文字:
clr2 = clr1*(1-a2)+text*a2
= 30*0.7f+200*0.3f
= 81
alpha = alpha * a2
= 0.2*0.3
= 0.6
3. 最后将其和场景混合:
dest = scene*(1-alpha) + clr2*alpha
=100*0.4 + 81*0.6
=40+48.6
=88.6
posted @
2011-06-24 11:51 flipcode 阅读(255) |
评论 (0) |
编辑 收藏
最近为公司写了个性能优化曲线工具, 可配置,如图:
查了下war3场景同屏面数在4000-10000面左右, 可以看到单机下war3稳定限帧在15到16毫秒(也即60帧左右), 以下是一个简陋版本载图:
同时发现war3的迷雾似乎4格一个16*16像素的动态图(树阴影也动态做到上面), 例如:64*64大小地图分成8*8个fog块,
下图是我载了些图手动还原迷雾大致如下:
另外三国的曲线(部分渲染消耗,每一格为1ms, 测试机器比较烂,是集成显卡)
另外show下山边为公司写的静态性能分析工具, 用在cpu的消耗测试还是比较有用的,当然渲染消耗由于涉汲runtime/driver的缓存以及gpu处理等原
因是测试不准的.
posted @
2011-06-24 09:09 flipcode 阅读(180) |
评论 (0) |
编辑 收藏
,另外难得今天有空又摆弄了下以前写的地形引擎,顺手载一下图:
posted @
2011-06-18 19:28 flipcode 阅读(181) |
评论 (0) |
编辑 收藏
一。世界分布:
map中最多有64*64个block(即block[4096])
每个block对应一个terrain(大小约为533*533)分成16*16个tile(即tile[256], 每个tile大小约为33*33)
最后每个tile分成8*8个CELL(大小为4*4左右),每个CELL中间附带一个点,用于
在渲染时,如果是在tilelod内则这个8*8个cell中间加一个点细分绘制,否则不用绘制这细分的三角形.
二。Tile渲染:
每个tile最多可存4层地表纹理,
当渲染tile时,看有几层地表就设置对应的不同层的shader,并赋与对应地表贴图以及对应一张alpha map进行渲染
求出地表base位置到角色位置距离,看是否超出tile的lod距离,超出则用粗格子,否则用细格子进行绘制。
posted @
2010-12-27 09:13 flipcode 阅读(268) |
评论 (0) |
编辑 收藏
小场景测试:反折射水,实时阴影,高光+泛光,splatting地表
posted @
2010-12-26 00:11 flipcode 阅读(147) |
评论 (0) |
编辑 收藏
男人撑过10秒minigame游戏...,周五晚上一时兴致几个小时弄的测试程序
地表刷:
posted @
2010-12-16 22:29 flipcode 阅读(193) |
评论 (0) |
编辑 收藏
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// UI的渲染:
// flipcode@msn.com
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
一。批次渲染:
1. 在界面上的3d模型渲染及特效需要每帧渲染到贴图上再当UI来画,否则将会打乱渲染状态
2. 控件及文字按渲染顺序生成z值,然后将不透明的按贴图打包,先批次画不透明的控件和文字,再关掉z write按排序画非透明控件和文字.
优化方案:
由于透明的控件和文字很可能没法批次画(除非它们顺序画时都在同一贴图上),所以约定所有控件和文字只用alpha test方式
而不能用alpha blend方式,也就是说控件和文字只能用colorkey(为了效率忍痛去掉类freetype用alpha blend产生的一些自然过渡的效果)
并且尽量让所有控件所用图片都作成一两张图上。(文字则是程序为每种字体创建大概两张贴图cache, 并先缓存一些最常用的字)
二。去掉UI重叠部份的渲染:
1. 合并所有控件矩形ui_rect为一个全局多边形集g_merge_rgn(并集)
2. 从上往下顺序将所有控件矩形ui_rect与g_merge_rgn分别作交集测试, 成功则将交集存回UI控件ui_render_rect_rgn,
并且如果控件为非透明(控件已在上述“批次渲染”约定为非透明但可有colorkey)时将全局g_merge_rgn减去该ui_render_rect_rgn交集
3. 从下往上顺序遍历所有所有控件并用控件自己的矩形ui_render_rect_rgn画出控件
三。脏矩形渲染:
有了上述的"去掉UI重叠部份的渲染", 这步就容易了,只要在渲染时判断一下该控件是否更新过, 如果更新过则将更新过的rect与该ui_render_rect_rgn交集出新的rgn来画.
四。关于渲染可能出现的边线问题:
一般是纹理在缩放过渡时使用linear采样方式而控件使用UV寻址贴图中小格子块产生的(可在作图时将格子块象素外扩一圈,或者程序将UV内缩一圈来处理)
五。最后提下,要先渲染UI,再渲染场景,这样来避免无效的ps, 另外UI固定部分在渲染场景时可用viewport去掉。
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// 关于汉字输入相关:
// flipcode@msn.com
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
一。创建dialog模式设备:
为了不用自己渲染输入法框,也只好牺牲点性能,使用这种非真正独占的模式的设备。
二。接收输入汉字
1。可以直接使用windows消息的WM_CHAR,汉字高位是大于127的(有符号char<0)自己处理判断组合一下即可。
2。也可以使用IME的来处理
三。汉字长度
汉字有等宽字和非等宽字(普遍),非等宽字计算长度比较麻烦,需从头遍历。。。
四。非unicode汉字的截断处理
这个也比较麻烦,需从头遍历,如果使用unicode就没这个问题
五。汉字的显示
需要贴图缓存,再批次显示
六。表情符号混显:
关于表符号混显问题主要有两点,一个是排版(具体处理就略过了),一个是表情动画处理
表情动画可以简单的使用cximage读取解开各帧再整合到一张纹理上,按帧播放显示。
七。输入法定位:
由于输入法的处理一般是在消息回调函数里得到目标wnd句柄,然后定位到这个wnd位置上,如果游戏中不使用windows控件的话,输入法没法自动定位到自定义的。只能靠用户自己拖动。有一个简单的处理是创建一个不用于显示的假控件在对应位置让输入法得以定位。。。(魔域这个网游真的很邪恶,里面全部使用mfc控件,只是渲染使用directx来接管。。。)
八。输入法充许与关闭:
估计很多人会碰到这个问题,就是只在输入框打开时才充许有输入法,如下处理
m_hImc = ImmAssociateContext(hWnd, NULL); 来关闭,再使用ImmAssociateContext(hWnd, m_hImc); 来打开
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/flipcode/archive/2009/06/22/4287894.aspx
posted @
2010-11-03 23:15 flipcode 阅读(250) |
评论 (0) |
编辑 收藏
hon的历史:
http://zh.wikipedia.org/wiki/S2_Games
S2 Games是一个专注开发电脑游戏的游戏开发机构,由Marc "Maliken" DeForest投资,设在加利福尼亚的
Rohnert Park。他们的第一作Savage: The Battle for Newerth于2003年夏天发行,是历史上第一个RTTS——
即时战略射击游戏。续作 Savage 2: A Tortured Soul,2008年1月16日首先放出Windows版本。最新作品
Heroes of Newerth是一个仿照魔兽争霸III著名场景DotA制作的游戏。
引擎:
Silverback
K2
大事记
2004,3个S2 Games成员离开并成立Offset Software
2006,S2 Games把与零售版本相同的Savage: The Battle for Newerth在自己网站上免费释放
2008,年初S2 Games发布Savage 2: A Tortured Soul;年末设立帐号制度,出现免费帐号
2009,beta测试Heroes of Newerth
2009,启动与Mod DB协作的活动
关于Offset Software
http://www.j2megame.org/index.php/content/view/1230/121.html
Intel收购游戏厂商Offset Software
2008-02-27
我们目前见到的画面惊人的游戏引擎中,除了Epic的“虚幻引擎3”,还有就是Crytek的“Cryengine 2”
,实际上还有一家公司也曾经宣布过自己有画面惊人的游戏引擎,并在当时引起了不小的争论。这家公司就是
Offset Software。目前,在Offset Software公司的官方主页上,已经正式公布了他们已被Intel收购的消息
。
2005年左右,Offset Software曾公布过他们独自研发的“Offset Engine”引擎,在当时不但光影效果惊
人,再加上支持图形化的使用界面、64位HDR光影特性以及其他先进技术,确实营造出了不错的效果。而且通
过“Offset Engine”非常直观化的操作界面,使用者不需要掌握复杂的程序语言,仅需鼠标就可以开启多种
特效,使得游戏开发的过程过程变得异常简便。
而《Project offset》则是他们近期开发的具有奇幻背景的FPS游戏,据悉Intel收购Offset Software极
有可能是为了强化自家的3D技术,以期提高将来Intel显卡的游戏性能。
关于《Project offset》:
http://pc.yezizhu.com/news/200903/8035_2.shtml
奇幻FPS《project offset》展示精彩物理效果发表时间:2009-03-28 作者:abao 来源:未知查看热点评论
Offset Software史诗式奇幻FPS新作《project offset》在此次GDC会展中公开了一段视频演示,名字命
为“Meteor”(流星),展示了精彩的物理效果。该作有可能将会是PC独占,因为已经被Intel收购用来展示
Larrabee,不过目前还未确认是否取消Xbox 360版本。
hon初步分析(flipcode@msn.com)
一。物件
1.纹理:
a. 一般是两层贴图:
第一层是物件的基本贴图(256*256),第二层各种物件总是相同的一个奇怪的缕空黑白图(256*256),
中间是个黑色形状图块(对应的alpha全白,其它全灰).
b. 另外有些是3层贴图:
第一层是物件的基本贴图(256*256),第二层各种物件总是相同的一个奇怪的缕空黑白图(256*256),
第3层是个team color图(黑白图,白色部分混上颜色)
c. 此外有些物件带光晕面片(用贴图*顶点色渲染)
例如: 塔边上有一个个发亮星星/光晕(就是一个个面片,然后用星状颜色图/中间发亮的黑白图来跟面片顶点
色相乘)
2. 面数:
建筑600左右面(一个dip画完,其它一些发光面片再另外按贴图一起画)
3. 渲染:
物件并不批次渲染,只是按贴图排序渲染。(但是看到物件上的发亮相同贴图的面片会合成一个批次,这可能是
美术直接作成一个mesh的)
另外hon的悬崖是直接使用地面网格做的,悬崖对应地表格子可以水平移动并同时拉高,贴图使用悬崖贴图,这样看起来也还可以。
好处是跟地表一致,渲染处理过渡自然,省面数。
二。角色:
1.纹理:
一般是两张纹理,一张是物体本色图,另一张是team color图(黑白图,白色部分混上颜色)
另外在高效果显示时,会有法线图。
2. 面数:
兵800左右面(一个dip画完)
英雄1200左右(一次dip画完, 包括手上武器)
3. 渲染:
物件并不批次渲染,只是按贴图排序渲染。
低效果时只是受漫射光,环境光,平行光影响, 如下:
clr=贴图颜色*顶点色*光照(光照=ambient+dot(N.L)*suncolor);
高效果时会用法线图进行光照运算,同时有高光计算.
另外高效果时似乎还有点光源支持以及一个云贴图,自遮挡阴影?没具体分析.
对于team color是这样的:
贴图颜色 = 原图色 * (teamcolor图*teamcolor)
即SetTexture( Texture0 = 原图色, Texture1 =teamcolor图); 然后只draw一次完成.
以上看来hon的角色非常简单,是只有一个带骨架的模型,不可换装.
三。阴影:
使用shadowmap动态阴影,在我机器上(ati hd3200集成显卡)比较消耗,打开时fps30-40, 关闭时60-70
四。地表:
1. 纹理:
地表贴图,最高时使用512*512,32bit,mip为9级
2. 渲染:
地表分批次渲染,每次最大不超过1089个顶点, 每批次对应两层纹理,通过顶点alpha混合过渡(顶点比较密)
五。界面:
1. 纹理:
血条的贴图由黑底,红条,黄条,绿条组成
2.渲染:
血条的渲染,先画黑底框,再画红条,然后画黄条,最后画绿条.当血渐渐少了,红黄绿3个条同时由右向左缩
小(红黄绿alpha渐少,红少得快,黄其次,红不变或少得慢), 黑框保持不缩放。
注:hon的这个血条并不批次渲染,而是每次渲染一个血条的一层.由底向上渲染,渲染完再换一个血条渲染.
渲染完所有血条之后,这才开始渲染普通界面。(alpah blend方式下使用贴图*顶点颜色渲染)
六。后期处理:
后期渲染,使用全屏泛光,类似nvglow,只是不指定物件alpha通道渲染,而是全屏泛光.
渲染顺序, 先物件,再地表,然后是后期处理
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/flipcode/archive/2010/04/06/5453714.aspx
posted @
2010-11-03 23:14 flipcode 阅读(413) |
评论 (0) |
编辑 收藏