锁定老帖子 主题:使用XWorker编写战斗模拟器
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-02-14
还是XWorker的介绍贴,XWorker是免费开源项目,下面是使用XWorker的数据对象技术开发的我们游戏项目的战斗模拟器,希望让大家了解XWorker中开发的方式。另外不建议目前用XWorker开发商业应用,后果自负,因为XWorker还不成熟,所以才希望有人能够加入XWorker的开发。
数据对象的使用说明: 主要是用于编写界面和数据统计,数据对象技术类似于信息化系统那种格式化的CUDI操作,只不过在XWorker数据对象主要用于一般编辑界面,即不限于数据库的操作,主要是对一般的表单、表格的等处理,如示例中的战斗数据的展示和统计等。
战斗模拟器的界面: 战斗模拟器的详细说明 1. 玩家和怪物界面 XWorker中的代码是: <Group name="playerGroup" text="玩家"> <GridData style="FILL_HORIZONTAL" name="playerGroupGridData"/> <FillLayout name="FillLayout"/> <DataObjectForm formType="edit" name="playerForm" dataObject="tools:dataobjects.PlayerThingDataObject"/> </Group> <Group name="monsterGroup" text="怪物"> <FillLayout name="monsterGroup"/> <GridData style="FILL_HORIZONTAL" name="monsterGroupGridData"/> <DataObjectForm formType="edit" name="monsterForm" dataObject="tools:dataobjects.Monster"/> </Group> 以上代码生成了如下界面: <ListDataObject label="Monster" listData="npcList" editCols="4" storeSortDir="ASC" name="Monster" dataClassName="Npc"> <attribute type="int" propertyPath="id" label="标识" queryEditor="false" viewEditor="false" gridEditor="false" name="id" editEditor="false" createEditor="false"/> <attribute propertyPath="name" label="名称" inputtype="label" name="name"/> <attribute type="int" propertyPath="level" label="等级" name="level"/> <attribute type="int" propertyPath="hpMax" label="气血上限" name="hpMax"/> <attribute type="int" propertyPath="mpMax" label="内息上限" name="mpMax"/> <attribute type="short" propertyPath="attackMin" label="最小攻击" name="minAttack"/> <attribute type="short" propertyPath="attackMax" label="最大攻击" name="maxAttack"/> <attribute type="float" propertyPath="hitRateAdd" label="命中率" name="hitRate"/> <attribute type="float" propertyPath="hitRateBase" label="基础命中率" name="hitRateBase"/> <attribute type="float" propertyPath="hitRateAdd" label="额外命中率" name="hitRateAdd"/> <attribute type="float" propertyPath="avoRate" label="躲闪率" name="avoRate"/> <attribute type="float" propertyPath="criRate" label="暴击率" name="criRate"/> <attribute type="float" propertyPath="destRate" label="破击率" name="destroyRate"/> <attribute type="float" propertyPath="harmReduceRate" label="伤害减免率" name="harmReduce"/> <attribute type="float" propertyPath="criHarmRate" label="暴击伤害率" name="criHarmRate"/> <attribute type="float" propertyPath="desReduceRate" label="破击减免率" name="desReduceRate"/> <attribute type="float" propertyPath="hpAbsorbRate" label="气血吸收率" name="hpAbsorbRate"/> <attribute type="float" propertyPath="damageReboundRate" label="伤害反弹率" name="damageReboundRate"/> <attribute type="int" propertyPath="speed" label="速度" name="speed"/> <attribute type="int" propertyPath="skill.id" label="技能" inputattrs="tools:battle.SkillSelector:/@shell" inputtype="openWindow" name="skill"/> <attribute type="short" propertyPath="defence" label="防御" name="defence"/> </ListDataObject>
2. 设置和读取表单数据 表单生成后,填充表单数据和获取表单数据的方法。 a. 设置表单的数据 以下是按钮的代码: <Composite name="buttonComposite"> <GridData horizontalAlignment="END" style="FILL_HORIZONTAL" name="buttonCompositeGridData"/> <RowLayout marginTop="0" name="buttonCompositeRowLayout"/> <Button name="selectPlayerBtn" text="选择角色"> <RowData name="RowData" width="80"/> <Listeners> <Listener name="selectPlayerBtnSelection"> <ShellDialog name="selectPlayer" shellPath="tools:battle.PlayerThingSelector:/@shell"> <Result condition="_return != null" name="ifOk"> <FormSetValues formName="playerForm" name="setPlayer" valueVariable="_return"/> </Result> </ShellDialog> </Listener> </Listeners> </Button> <Button name="selectMonsterBtn" text="选择怪物"> <RowData name="RowData" width="80"/> <Listeners> <Listener name="selectMonsterBtnSelection"> <ShellDialog name="selectMonster" shellPath="tools:battle.MonsterSelector:/@shell"> <Result condition="_return != null" name="ifOk"> <FormSetValues formName="monsterForm" name="setMonster" valueVariable="_return"/> <PropertySetter propertyName="monster" dataSource="actionContext.getScope(0)" name="setActionContext" value="_return"/> </Result> </ShellDialog> </Listener> </Listeners> </Button> <Button name="startBattleBtn" text="开始战斗"> <RowData name="RowData" width="80"/> <Listeners> <Listener name="startBattleBtnSelection"> <GroovyAction code="" name="startBattle"/> </Listener> </Listeners> </Button> <Button name="updatePlayerBtn" text="保存角色"> <RowData name="RowData" width="80"/> <Listeners> <Listener name="updatePlayerBtnSelection"> <EventExecutor exceptionMessage="更新角色失败。" name="executeEpdatePlayer" successMessage="更新角色成功。"> <actions name="actions"> <FormUpdateDataObject name="updatePlayer" formName="playerForm"/> </actions> </EventExecutor> </Listener> </Listeners> </Button> <Button name="createNewPlayerBtn" text="保存为新角色"> <RowData name="RowData" width="80"/> <Listeners> <Listener name="createNewPlayerBtnSelection"> <EventExecutor exceptionMessage="创建角色失败。" name="eventExecutor" successMessage="创建角色成功。"> <actions name="actions"> <FormCreateDataObject name="createPlayer" formName="playerForm"/> </actions> </EventExecutor> </Listener> </Listeners> </Button> </Composite>
对应的界面是: 我们使用选择怪物按钮来解释如何选择怪物并填充怪物表单,选择怪物的按钮的事件处理代码是: <Listeners> <Listener name="selectMonsterBtnSelection"> <ShellDialog name="selectMonster" shellPath="tools:battle.MonsterSelector:/@shell"> <Result condition="_return != null" name="ifOk"> <FormSetValues formName="monsterForm" name="setMonster" valueVariable="_return"/> <PropertySetter propertyName="monster" dataSource="actionContext.getScope(0)" name="setActionContext" value="_return"/> </Result> </ShellDialog> </Listener> </Listeners> 分解讲解: <ShellDialog name="selectMonster" shellPath="tools:battle.MonsterSelector:/@shell"> 打开选择怪物的窗口tools:battle.MonsterSelector:/@shell。 <Result condition="_return != null" name="ifOk"> 如果选择的怪物。 <FormSetValues formName="monsterForm" name="setMonster" valueVariable="_return"/> 把怪物数据填充到怪物表单。 <PropertySetter propertyName="monster" dataSource="actionContext.getScope(0)" name="setActionContext" value="_return"/> 把怪物数据设置到全局变量中,以备后用。
b. 获取表单数据的代码 def mvalues = monsterForm.doAction("getValues", actionContext); 以上是groovy的脚本代码,获取怪物表单中的编辑的数据。
3. 统计数据处理
统计的代码如下:
//计算玩家的统计信息 def attackStaticDObj = world.getThing("tools:battle.AttackInfoStatic"); //玩家统计 def playerAttackStatic = attackStaticDObj.doAction("query", actionContext, ["attackDetails": playerAttackDetails]).get(0); //怪物统计 def monsterAttackStatic = attackStaticDObj.doAction("query", actionContext, ["attackDetails": monsterAttackDetails]).get(0); playerAttackDetails和monsterAttackDetails是一次战斗的详细信息,是由游戏代码算出来的,attackStaticDObj是统计模块,做统计, attackStaticDObj.doAction("query", actionContext, ["attackDetails": playerAttackDetails]).get(0);是执行统计并算出结果。 其中统计的定义是tools:battle.AttackInfoStatic,它的代码如下: <StatisticsQueryDataObject dataObject="ResultDataObject" editCols="4" storeSortDir="ASC" name="ResultStat"> <attribute type="int" label="战斗次数" size="10" gridWidth="60" inputtype="label" aggregateExpression="*" name="totalCount" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="胜利次数" size="10" gridWidth="60" inputtype="label" aggregateExpression="result" name="winCount" queryFieldType="aggregate"/> <attribute type="float" aggregateFunction="avg" colspan="2" label="胜率" size="10" inputtype="label" aggregateExpression="result" name="winRate" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="总时间" size="10" inputtype="label" aggregateExpression="time" name="time" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="avg" label="平均战斗时间" size="10" inputtype="label" aggregateExpression="time" name="avgTime" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="avg" label="玩家平均攻击次数" size="10" inputtype="label" aggregateExpression="playerAttackCount" name="avgAttackCount" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="avg" label="怪物平均攻击次数" size="10" inputtype="label" aggregateExpression="monsterAttackCount" name="avgMonsterAttackCount" queryFieldType="aggregate"/> <attribute colspan="4" label="玩家统计数据" inputtype="label" name="playerData" queryFieldType="finalExpression" finalExpression=""""/> <attribute type="int" aggregateFunction="sum" label="攻击次数" size="10" inputtype="label" aggregateExpression="playerAttackCount" name="playerAttackCount" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="总伤害" size="10" inputtype="label" aggregateExpression="playerAttack" name="playerAttack" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="暴击次数" inputtype="label" aggregateExpression="playerCrickedCount" name="playerCrickedCount" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="破击次数" inputtype="label" aggregateExpression="playerDestroyedCount" name="playerDestroyedCount" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="命中次数" inputtype="label" aggregateExpression="playerHitCount" name="playerHitCount" queryFieldType="aggregate"/> <attribute type="int" label="平均战斗伤害" size="10" inputtype="label" name="avgPlayerBattleAttack" queryFieldType="finalExpression" finalExpression="playerAttack/totalCount"/> <attribute type="float" label="暴击率" inputtype="label" name="playerAvgCrickedCount" queryFieldType="finalExpression" finalExpression="playerCrickedCount/playerAttackCount"/> <attribute type="int" label="破击率" inputtype="label" name="playerAvgDestroyedCount" queryFieldType="finalExpression" finalExpression="playerDestroyedCount/playerAttackCount"/> <attribute type="float" label="命中率" inputtype="label" name="playerAvgHitRate" queryFieldType="finalExpression" finalExpression="playerHitCount/playerAttackCount"/> <attribute type="int" label="平均每次伤害" size="10" inputtype="label" name="playerAvgAttackDamage" queryFieldType="finalExpression" finalExpression="playerAttack/playerAttackCount"/> <attribute type="int" aggregateFunction="sum" label="内息消耗" size="10" inputtype="label" aggregateExpression="playerAttackerMpUsed" name="playerAttackerMpUsed" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="avg" label="平均战斗内息消耗" size="10" inputtype="label" aggregateExpression="playerAttackerMpUsed" name="avgPlayerAttackerMpUsed" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="气血消耗" size="10" inputtype="label" aggregateExpression="playerAttackerHpUsed" name="playerAttackerHpUsed" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="气血吸收" size="10" inputtype="label" aggregateExpression="playerHpAbsorb" name="playerHpAbsorb" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="内息吸收" size="10" inputtype="label" aggregateExpression="playerMpAbsorb" name="playerMpAbsorb" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="伤害反弹" size="10" inputtype="label" aggregateExpression="playerDamageRebound" name="playerDamageRebound" queryFieldType="aggregate"/> <attribute colspan="4" label="怪物统计数据" inputtype="label" name="monsterData" queryFieldType="finalExpression" finalExpression=""""/> <attribute type="int" aggregateFunction="sum" label="攻击次数" size="10" inputtype="label" aggregateExpression="monsterAttackCount" name="monsterAttackCount" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="总伤害" size="10" inputtype="label" aggregateExpression="monsterAttack" name="monsterAttack" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="暴击次数" inputtype="label" aggregateExpression="monsterCrickedCount" name="monsterCrickedCount" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="破击次数" inputtype="label" aggregateExpression="monsterDestroyedCount" name="monsterDestroyedCount" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="命中次数" inputtype="label" aggregateExpression="monsterHitCount" name="monsterHitCount" queryFieldType="aggregate"/> <attribute type="int" label="平均战斗伤害" size="10" inputtype="label" name="avgmonsterBattleAttack" queryFieldType="finalExpression" finalExpression="monsterAttack/totalCount"/> <attribute type="float" label="暴击率" inputtype="label" name="monsterAvgCrickedCount" queryFieldType="finalExpression" finalExpression="monsterCrickedCount/monsterAttackCount"/> <attribute type="int" label="破击率" inputtype="label" name="monsterAvgDestroyedCount" queryFieldType="finalExpression" finalExpression="monsterDestroyedCount/monsterAttackCount"/> <attribute type="float" label="命中率" inputtype="label" name="monsterAvgHitRate" queryFieldType="finalExpression" finalExpression="monsterHitCount/monsterAttackCount"/> <attribute type="int" label="平均每次伤害" size="10" inputtype="label" name="monsterAvgAttackDamage" queryFieldType="finalExpression" finalExpression="monsterAttack/monsterAttackCount"/> <attribute type="int" aggregateFunction="sum" label="内息消耗" size="10" inputtype="label" aggregateExpression="monsterAttackerMpUsed" name="monsterAttackerMpUsed" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="avg" label="平均战斗内息消耗" size="10" inputtype="label" aggregateExpression="monsterAttackerMpUsed" name="avgmonsterAttackerMpUsed" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="气血消耗" size="10" inputtype="label" aggregateExpression="monsterAttackerHpUsed" name="monsterAttackerHpUsed" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="气血吸收" size="10" inputtype="label" aggregateExpression="monsterHpAbsorb" name="monsterHpAbsorb" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="内息吸收" size="10" inputtype="label" aggregateExpression="monsterMpAbsorb" name="monsterMpAbsorb" queryFieldType="aggregate"/> <attribute type="int" aggregateFunction="sum" label="伤害反弹" size="10" inputtype="label" aggregateExpression="monsterDamageRebound" name="monsterDamageRebound" queryFieldType="aggregate"/> </StatisticsQueryDataObject> StatisticsQueryDataObject是一个分组和汇总模块,可以对List数据或数组等分组和汇总。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-02-14
以上是为了介绍XWorker特性,希望能够有人参与,不过基本上本轮的介绍(前面也有帖子)以失败告终了。
目前XWorker还有很多事情要做,主要是想法太多哈,不过今后会有更多的实用功能推出,到时候可能大家会更容易接受一些。 |
|
返回顶楼 | |
浏览 2017 次