找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 461|回复: 14

神迹0621闪退完美优化

[复制链接]
发表于 昨天 20:20 | 显示全部楼层 |阅读模式
游戏端:神迹0621,2月份更新的段
环境如下:
登陆器暴雨1.55,宽屏,16按键,帝落插件
回复

使用道具 举报

 楼主| 发表于 昨天 20:21 | 显示全部楼层
朋友练的气功,我玩的母骑,就老是发现刷图的时候经常性闪退,总所周知神迹优化不如忘越和沫沫,但总归不至于闪退吧
按理说一个游戏即使在卡,只要代码计算不进入死循环的话游戏不会闪退的,即使是1帧也不会闪退,那么就可以好好排查一下
开始找原因,而这个代码应该就存在气功和母骑会频繁触发里面
排除nut白色,排除技能,那应该就是特殊状态了(事实证明我是对的),气功会频繁附加感电等,母骑戴的有冰雪公主套和霸体套
那么就进入怪物ap里查看nut文件看看到底怎么回事
打开PVF的sqr/ui/ap/ap_monster.nut发现一堆乱码,不过代码看着还是比较清晰的,我在这给大伙解释一下让各位看的更清晰
逻辑是这样的,先判断怪物HP,随后判断目前附加的特殊状态(流血、中毒、闪电、燃烧、石化)
原代码通过 sq_IsValidActiveStatus 检查怪物是否处于异常状态,比如:
流血(ACTIVESTATUS_BLEEDING)
中毒(ACTIVESTATUS_POISON)
感电(ACTIVESTATUS_LIGHTNING)
燃烧(ACTIVESTATUS_BURN)
石化(ACTIVESTATUS_STONE)
如已有特殊状态,则调用applyActiveDamage 和 applyActiveDamage2函数(附加伤害用的)
逻辑中没有明确提到各个异常状态的具体伤害规则,而是统一调用了这些函数,可能由这些函数内部实现了具体的额外伤害计算
那么潜在问题就来了
所有异常状态都统一处理,缺乏针对不同状态(如流血、中毒、感电等)的独立逻辑,可能导致逻辑冲突或资源竞争。
没有明确的时间限制(如每种异常状态独立的触发频率),可能导致频繁调用 applyActiveDamage 和 applyActiveDamage2。
首先我想到的是单独给每个状态做调用和计时器处理,但实际完成后代码变多了一倍,这不是我想要的
如果必须保留原有的 applyActiveDamage 和 applyActiveDamage2 函数调用,同时优化异常状态的逻辑,那我还有一个方案
回复

使用道具 举报

 楼主| 发表于 昨天 20:22 | 显示全部楼层
分开处理每种异常状态的触发条件:
原代码是将所有异常状态统一处理,所以容易导致逻辑混乱。我的思路是可以单独检查每种状态并分别调用 applyActiveDamage 和 applyActiveDamage2。
优化时间间隔逻辑:
每种状态有独立的时间间隔判断,避免资源重复调用导致性能问题。
保留原有函数调用方式:
依旧通过 applyActiveDamage 和 applyActiveDamage2 处理伤害,只在逻辑层面改进判断和调用条件。
这样就测试后虽然补卡掉了,但是依旧没有达到我想要的帧率提升
没关系,再继续优化就是了
接下来的思路其实就很清晰了
回复

使用道具 举报

 楼主| 发表于 昨天 20:22 | 显示全部楼层
applyActiveDamage 和 applyActiveDamage2 是共用的,因此可以将状态逻辑重新合并,只保留关键的时间判断
有了这个思路重新了代码后,进游戏进行测试,ok,完美解决,虽然帧率没有提升多了(大概比之前最低值多个3-5帧),但刷副本的时候再也没有出现过一次闪退了。我用了一个召唤,一个母骑,一个气功进行测试,测试了10张图,即使帧率都降到1帧了,即使游戏已经卡死未响应了,过几秒就会恢复正常,此时异常状态导致闪退的问题已彻底解决。
回复

使用道具 举报

 楼主| 发表于 昨天 20:23 | 显示全部楼层
这里附上代码,动手能力强的就直接手动优化吧,没有动手能力的这里也附上傻瓜式一键导入包
function onSetHp_appendage_monster(appendage, hp, attacker) {
if (!appendage) return hp;
local parentObj = appendage.getParent();
local currentHp = hp;
if (!parentObj) return currentHp;
// 如果设置的血量小于 0,可能触发死亡相关逻辑(例如播放声音)
if (hp < 0) {
try {
local object = sq_GetCNRDObjectToActiveObject(parentObj);
if (object) {
local objectIndex = object.getCollisionObjectIndex();
soundList(object, objectIndex);
}
} catch (ex) {
// 捕获异常,防止程序崩溃
}
return hp;
}
// 如果全局变量禁用伤害处理,直接返回
if (ENABLE_DAMAGE_ACTIVE == 0) return hp;
// 计算新造成的伤害
local newHpDamage = parentObj.getHp() - hp;
if (newHpDamage <= 0) return currentHp;
// 检查是否有额外伤害,并更新当前血量
local addHpDamage = appendage.getVar("addHpDamage").getInt(0);
if (addHpDamage > 0) {
currentHp -= addHpDamage;
appendage.getVar("addHpDamage").setInt(0, 0);
return currentHp;
}
// 检查伤害值是否与存储值一致
local hpDamage = appendage.getVar("newHpDamage").getInt(0);
if (newHpDamage == hpDamage) return currentHp;
// 如果攻击者与目标在同一队伍,不处理伤害
if (attacker && (parentObj.getTeam() == attacker.getTeam())) return currentHp;
// 获取目标位置坐标
local x = parentObj.getXPos();
local y = parentObj.getYPos();
local z = parentObj.getObjectHeight() / 2 + CRI_UPPER_HEIGHT;
// 处理特殊技能伤害逻辑
if (SPECIAL_SKILL_FLAG == 1) {
local currTime = appendage.getTimer().Get();
if (currTime - appendage.getVar("atkTimeS").getInt(0) > 500) {
NOMAL_ATTACK_FLAG = 1;
appendage.getVar("atkTimeS").setInt(0, currTime);
currentHp -= applySpecialSkillDamage(appendage, newHpDamage, x, y, z);
}
return currentHp;
}
// **优化的异常状态处理逻辑(合并版)**
local currTime = appendage.getTimer().Get();
local triggered = false;
// 处理感电状态
if (sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_LIGHTNING) &&
currTime - appendage.getVar("lightningTime").getInt(0) > 3000) {
appendage.getVar("lightningTime").setInt(0, currTime);
triggered = true; // 标记感电状态触发
}
// 处理流血状态
if (sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_BLEEDING) &&
currTime - appendage.getVar("bleedingTime").getInt(0) > 1000) {
appendage.getVar("bleedingTime").setInt(0, currTime);
triggered = true; // 标记流血状态触发
}
// 处理中毒状态
if (sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_POISON) &&
currTime - appendage.getVar("poisonTime").getInt(0) > 1500) {
appendage.getVar("poisonTime").setInt(0, currTime);
triggered = true; // 标记中毒状态触发
}
// 处理燃烧状态
if (sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_BURN) &&
currTime - appendage.getVar("burnTime").getInt(0) > 2000) {
appendage.getVar("burnTime").setInt(0, currTime);
triggered = true; // 标记燃烧状态触发
}
// 处理石化状态
if (sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_STONE) &&
currTime - appendage.getVar("stoneTime").getInt(0) > 2500) {
appendage.getVar("stoneTime").setInt(0, currTime);
triggered = true; // 标记石化状态触发
}
// 如果任何异常状态被触发,调用额外伤害函数
if (triggered) {
applyActiveDamage(appendage, newHpDamage, x, y, z);
currentHp -= applyActiveDamage2(newHpDamage);
}
// 检查血量是否低于 1
if (currentHp < 1) currentHp = -1;
return currentHp;
}
如果因为dll和登陆器、服务端、dp插件fr插件的问题导致的闪退,还请自行辨别,判断不了不要上来就说没效果
Base64解码:
aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMURIb2ozTHpoQmRqdlM2UEw3VTdGU1E/cHdkPWY4Z2U=
回复

使用道具 举报

2003

主题

1万

回帖

5万

积分

出神入化

积分
56450
发表于 昨天 20:23 | 显示全部楼层
顶一下

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

1370

主题

1万

回帖

4万

积分

登峰造极

积分
43736
发表于 昨天 20:24 | 显示全部楼层
虽然看不懂倒是先+3
回复

使用道具 举报

1983

主题

1万

回帖

5万

积分

出神入化

积分
55704
发表于 昨天 20:25 | 显示全部楼层
我发现闪退还有就是和某个字体有关不知道是不是 女毒王是最明显 只要红字异常必闪退
回复

使用道具 举报

1992

主题

1万

回帖

5万

积分

出神入化

积分
56457
发表于 昨天 20:25 | 显示全部楼层
虽然看不懂,但大佬牛逼

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

 楼主| 发表于 昨天 20:25 | 显示全部楼层
支持大佬,学习研究一下
回复

使用道具 举报

1386

主题

1万

回帖

4万

积分

登峰造极

积分
43734
发表于 昨天 20:26 | 显示全部楼层
好厉害
回复

使用道具 举报

1827

主题

1万

回帖

5万

积分

管理员

积分
52026
发表于 昨天 20:26 | 显示全部楼层
牛逼啊
回复

使用道具 举报

1923

主题

1万

回帖

5万

积分

出神入化

积分
56031
发表于 昨天 20:26 | 显示全部楼层
回复

使用道具 举报

1972

主题

1万

回帖

5万

积分

出神入化

积分
56797
发表于 昨天 20:27 | 显示全部楼层
大佬有白字过多卡顿的解决方法吗
回复

使用道具 举报

1972

主题

1万

回帖

5万

积分

出神入化

积分
56797
发表于 昨天 20:27 | 显示全部楼层
牛批!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表