这两天在玩《万国觉醒》,看了下战报,每一回合伤害,技能,buf明细都写的很详尽,如果自己去实现,该怎么做呢?
战报如下:
想想,只要有个记录战斗明细的对象+模板引擎,一整合,需要的结果就出来了,就拿接口很丰富的freemarker练手。
好,我们先来学习下这个模板引擎的基础知识。
一、FreeMarker 是什么?
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。
二、使用步骤
1.引入库
implementation group: 'org.freemarker', name: 'freemarker', version: '2.3.31';
2.使用
1.数字格式化(金额格式化)
${num?string('0.00')} 如果小数点后不足两位,用 0 代替 ${num?string('#.##')} 如果小数点后多余两位,就只保留两位,否则输出实际值 输出为:1239765.46 ${num?string(',###.00')} 输出为:1,239,765.46 整数部分每三位用 , 分割,并且保证小数点后保留两位,不足用 0 代替 ${num?string(',###.##')} 输出为:1,239,765.46 整数部分每三位用 , 分割,并且小数点后多余两位就只保留两位,不足两位就取实际位数,可以不不包含小数点 ${num?string('000.00')} 输出为:012.70 整数部分如果不足三位(000),前面用0补齐,否则取实际的整数位 ${num?string('###.00')} 等价于 ${num?string('#.00')} 输出为:12.70 整数取实际的位数
2.时间字段格式化
时间:${(startTime?string("MM/dd HH:mm"))!}-${(endTime?string("MM/dd HH:mm"))!}
生成后就展现如下:
时间:06/09/ 10:18-06/09/ 10:18
3.千分位去除
${total?c}
4.如何使用枚举
java 字段 为 private PhaseEnum phase;
public enum PhaseEnum { /** * 未处理 */ UN_RESOLVED(0, "未处理"), /** * 处理中 */ PROCESSING(1, "处理中"), /** * 已处理 */ RESOLVED(2, "已处理"), /** * 忽略 */ OMIT(3, "忽略"), ; private final int id; private final String message; PhaseEnum(int id, String message) { this.id = id; this.message = message; } public int getId() { return id; } public String getMessage() { return message; } }
使用
${phase.message} <#if phase == "UN_RESOLVED">[领取]<#else>[查看]</#if> ${phase}
结果为:
未处理 [领取] UN_RESOLVED
5.if else
<#if (winner?exists)> [${winner.mainHero.name}](${winner.total?c})的部队正高举武器,欢庆胜利! <#else> 双方均全军覆没! </#if>
6.switch case
只能用字符串或者数字为值
7.基本运算
战斗结果:${(round.one.after-round.one.before)?c}
8.声明变量
<#assign name="张三"/>
9.比较大小
<#if (operation.one.loss>0)> </#if>
10.获取列表大小
${one.array?size}
如果加在if条件
<#if (one.array?size>0)> <#list one.array as buff> ${buff.desc} </#list> <#elseif (one.array?size>10)> //.... <#else> 无临时增益 </#if>
11.断字符串是否相等
<#if (appVersion=="0.0.0.0")> </#if>
12.特殊字符用noparse转义
比如 < 符号
<#noparse><</#noparse>
如果程序运行在标准时区,如何让freemarker 显示东八区时区的时间
在文件头加上
<#setting time_zone="Asia/Shanghai">
13.转义字符有哪些?
转义序列 | 含义 |
\ " | 引号 (u0022) |
\ ’ | 单引号(又称为撇号) (u0027) |
\ { | 起始花括号:{ |
\ \ | 反斜杠 (u005C) |
\n | 换行符 (u000A) |
\r | 回车 (u000D) |
\t | 水平制表符(又称为tab) (u0009) |
\b | 退格 (u0008) |
\f | 换页 (u000C) |
\l | 小于号:< |
\g | 大于号:> |
\a | &符:& |
\xCode | 字符的16进制 Unicode 码 (UCS 码) |
14.字符串填充,适合用于建文本表格
left_pad,right_pad
id | command name |average size | max size | total size |invoke time -------------------------------------------------------------------------------------------------------------------------------- <#list array as command> ${command.code?c?right_pad(10)}${command.name?right_pad(40)}${command.avgSize?c?right_pad(20)} ${command.maxSize?c?right_pad(20)}${command.totalSize?c?right_pad(20)}${command.invokeTimes?c?right_pad(20)} </#list>
获得的结果如下:
id | command name |average size | max size | total size |invoke time -------------------------------------------------------------------------------------------------------------------------------- 6 EntityNtfMsg 123 918 21913 178 120 Player_UpdateView_C2S 41 42 1760 42 121 Player_UpdateView_S2C 0 0 0 42 42 Player_ChangeArmyAction_C2S 24 24 48 2 43 Player_ChangeArmyAction_S2C 0 0 0 2 126 Player_SearchWalkPath_C2S 20 20 40 2 127 Player_SearchWalkPath_S2C 37 52 74 2 7 Login_C2S_Msg 44 44 44 1 8 Login_S2C_Msg 23 23 23 1 11 KeepAlive_C2S_Msg 0 0 0 1 12 KeepAlive_S2C_Msg 7 7 7 1 32 Player_GetDebugCommandList_C2S 2 2 2 1 33 Player_GetDebugCommandList_S2C 635 635 635 1 55 Player_ChangeMap_S2C 5 5 5 1 150 Player_SearchMonster_C2S 2 2 2 1 151 Player_SearchMonster_S2C 12 12 12 1
15.对LocalDateTime 的支持
implementation group: 'no.api.freemarker', name: 'freemarker-java8', version: '2.1.0';
添加对对于JDK8的支持配置类
Configuration config = new Configuration(Configuration.VERSION_2_3_31); config.setObjectWrapper(new Java8ObjectWrapper(Configuration.VERSION_2_3_31));
使用
${startTime.format('yyyy-MM-dd HH:mm:ss')}
要对时区进行设置的话,就要做如下的处理:
<#setting time_zone="Asia/Shanghai"> **统计日期**:<font color='comment'>${startTime.toZonedDateTime(time_zone).format('yyyy-MM-dd HH:mm:ss')} - ${endTime.toZonedDateTime(time_zone).format('yyyy-MM-dd HH:mm:ss')} </font>
综合使用
战斗日志 时间:${(startTime?string("MM/dd HH:mm:ss"))!}-${(endTime?string("MM/dd HH:mm:ss"))!} 地点:X:${x?c} Y:${y?c} 战斗简介 ${one.name}[${one.mainHero.name}]和${other.name}[${other.mainHero.name}]在野外发生了遭遇战! 我方阵容 ${one.name} [${one.mainHero.name}]等级${one.mainHero.level} <#if (one.deputyHero?exists)>&[${one.deputyHero.name}]等级${one.deputyHero.level}</#if>兵力:${one.total?c} <#if (one.array?size>0)> <#list one.array as buff> ${buff.desc} </#list> <#else> 无临时增益 </#if> 敌方阵容 ${other.name} [${other.mainHero.name}]等级${other.mainHero.level} <#if (other.deputyHero?exists)>&[${other.deputyHero.name}]等级${other.deputyHero.level}</#if>兵力:${other.total?c} <#if (other.array?size>0)> <#list other.array as buff> ${buff.desc} </#list> <#else> 无临时增益 </#if> <#list array as round> 第${round.id}回合 <#if (round.one?exists)&&(round.other?exists)> [我方]兵力:${round.one.before?c},战斗结果:${(round.one.after-round.one.before)?c} [敌方]兵力:${round.other.before?c},战斗结果:${(round.other.after-round.other.before)?c} <#list round.one.array as buff> [${round.one.name}](${round.one.before?c})由于[${buff.name}]效果${buff.desc},${buff.message} </#list> <#list round.other.array as buff> [${round.other.name}](${round.other.before?c})由于[${buff.name}]效果${buff.desc},${buff.message} </#list> <#list round.array as operation> <#if (operation.one?exists)> <#if (operation.one.skillVO?exists)> [${operation.one.attacker.name}](${operation.one.total?c}) 发动了[${operation.one.skillVO.skillName}]! <#if (operation.one.loss>0)> [${operation.one.defencer.name}]损失了${operation.one.loss?c}兵力 </#if> <#list operation.one.skillVO.array as buff> <#if (operation.one.id==buff.sourceId)> [${operation.one.attacker.name}]的部队获得了${buff.name}效果加成,${buff.message} <#else> [${operation.one.defencer.name}]的部队获得了${buff.name}效果加成,${buff.message} </#if> </#list> <#else> <#if (operation.one.loss>0)> [${operation.one.attacker.name}](${operation.one.total?c})对[${operation.one.defencer.name}]发起了普通攻击,[${operation.one.defencer.name}]损失了${operation.one.loss?c}兵力 </#if> </#if> </#if> <#if (operation.other?exists)> <#if (operation.other.loss>0)> [${operation.other.attacker.name}]发动反击,[${operation.other.defencer.name}]损失了${operation.other.loss?c}兵力 </#if> </#if> </#list> <#else> 本回合交战双方都没有发生战斗! </#if> ------------------------------------------------------------------------------ </#list> 战斗结束 <#switch endType.name()> <#case "BOT_END"> <#if (winner?exists)> [${winner.mainHero.name}](${winner.total?c})的部队正高举武器,欢庆胜利! <#else> 双方均全军覆没! </#if> <#break> <#case "BOT_OUT_OF_ROUND"> 由于一方撤退,两军不再交战! <#break> <#case "BOT_OUT_OF_HIDDEN"> 由于一方隐藏,两军不再交战! <#break> <#default> 战斗结束! </#switch>
整合后的文字战报如下:
战斗日志 时间:06/10 11:51:44-06/10 11:52:35 地点:X:13478 Y:12852 战斗简介 玩家名[项羽]和玩家名[谭雅]在野外发生了遭遇战! 我方阵容 玩家名 [项羽]等级1 兵力:2294 敌方阵容 玩家名 [谭雅]等级1 兵力:7000 第1回合 [我方]兵力:2294,战斗结果:-48 [敌方]兵力:7000,战斗结果:-85 [项羽](2294)对[谭雅]发起了普通攻击,[谭雅]损失了42兵力 [谭雅]发动反击,[项羽]损失了24兵力 [谭雅](7000)对[项羽]发起了普通攻击,[项羽]损失了24兵力 [项羽]发动反击,[谭雅]损失了43兵力 ------------------------------------------------------------------------------ 第2回合 [我方]兵力:2246,战斗结果:-48 [敌方]兵力:6915,战斗结果:-86 [项羽](2246)对[谭雅]发起了普通攻击,[谭雅]损失了44兵力 [谭雅]发动反击,[项羽]损失了24兵力 [谭雅](6915)对[项羽]发起了普通攻击,[项羽]损失了24兵力 [项羽]发动反击,[谭雅]损失了42兵力 ------------------------------------------------------------------------------ 第3回合 [我方]兵力:2198,战斗结果:-48 [敌方]兵力:6829,战斗结果:-84 [项羽](2198)对[谭雅]发起了普通攻击,[谭雅]损失了42兵力 [谭雅]发动反击,[项羽]损失了24兵力 [谭雅](6829)对[项羽]发起了普通攻击,[项羽]损失了24兵力 [项羽]发动反击,[谭雅]损失了42兵力 ------------------------------------------------------------------------------ 第4回合 [我方]兵力:2150,战斗结果:-48 [敌方]兵力:6745,战斗结果:-84 [项羽](2150)对[谭雅]发起了普通攻击,[谭雅]损失了42兵力 [谭雅]发动反击,[项羽]损失了24兵力 [谭雅](6745)对[项羽]发起了普通攻击,[项羽]损失了24兵力 [项羽]发动反击,[谭雅]损失了42兵力 ------------------------------------------------------------------------------ 第5回合 [我方]兵力:2102,战斗结果:-48 [敌方]兵力:6661,战斗结果:-82 [项羽](2102)对[谭雅]发起了普通攻击,[谭雅]损失了42兵力 [谭雅]发动反击,[项羽]损失了24兵力 [谭雅](6661)对[项羽]发起了普通攻击,[项羽]损失了24兵力 [项羽]发动反击,[谭雅]损失了40兵力 ------------------------------------------------------------------------------ 第6回合 [我方]兵力:2054,战斗结果:-47 [敌方]兵力:6579,战斗结果:-83 [项羽](2054)对[谭雅]发起了普通攻击,[谭雅]损失了42兵力 [谭雅]发动反击,[项羽]损失了23兵力 [谭雅](6579)对[项羽]发起了普通攻击,[项羽]损失了24兵力 [项羽]发动反击,[谭雅]损失了41兵力 ------------------------------------------------------------------------------ 第7回合 [我方]兵力:2007,战斗结果:-47 [敌方]兵力:6496,战斗结果:-81 [项羽](2007)对[谭雅]发起了普通攻击,[谭雅]损失了40兵力 [谭雅]发动反击,[项羽]损失了23兵力 [谭雅](6496)对[项羽]发起了普通攻击,[项羽]损失了24兵力 [项羽]发动反击,[谭雅]损失了41兵力 ------------------------------------------------------------------------------ 第8回合 [我方]兵力:1960,战斗结果:-46 [敌方]兵力:6415,战斗结果:-81 [项羽](1960)对[谭雅]发起了普通攻击,[谭雅]损失了40兵力 [谭雅]发动反击,[项羽]损失了23兵力 [谭雅](6415)对[项羽]发起了普通攻击,[项羽]损失了23兵力 [项羽]发动反击,[谭雅]损失了41兵力 ------------------------------------------------------------------------------ 第9回合 [我方]兵力:1914,战斗结果:-47 [敌方]兵力:6334,战斗结果:-78 [项羽](1914)对[谭雅]发起了普通攻击,[谭雅]损失了39兵力 [谭雅]发动反击,[项羽]损失了24兵力 [谭雅](6334)对[项羽]发起了普通攻击,[项羽]损失了23兵力 [项羽]发动反击,[谭雅]损失了39兵力 ------------------------------------------------------------------------------ 第10回合 [我方]兵力:1867,战斗结果:-46 [敌方]兵力:6256,战斗结果:-79 [项羽](1867)对[谭雅]发起了普通攻击,[谭雅]损失了39兵力 [谭雅]发动反击,[项羽]损失了23兵力 [谭雅](6256)对[项羽]发起了普通攻击,[项羽]损失了23兵力 [项羽]发动反击,[谭雅]损失了40兵力 ..... ..... ------------------------------------------------------------------------------ 第52回合 [我方]兵力:18,战斗结果:-18 [敌方]兵力:3891,战斗结果:-3 [项羽](18)由于[万箭齐发]效果全军攻击力增强10%,剩余4回合 [谭雅](3891)由于[万箭齐发]效果全军攻击力增强10%,剩余4回合 [项羽](18)对[谭雅]发起了普通攻击,[谭雅]损失了3兵力 [谭雅]发动反击,[项羽]损失了18兵力 ------------------------------------------------------------------------------ 战斗结束 [谭雅](3888)的部队正高举武器,欢庆胜利!
总结
以上都是制作游戏战报的过程中的一些总结,大家也可以用其他模板引擎去做实现。
参考链接: