posts - 72,  comments - 4,  trackbacks - 0


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 on 2011-06-24 16:40 flipcode 阅读(433) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理