《小冰游戏战斗逻辑详解》原来你也玩。。。

源码

战斗算法

function battleWithMinster(userInfo, monster) {
  return new Promise((resolve, reject) => {
    let uatk = (userInfo.lv * 10 + (userInfo.equip.arms ? userInfo.equip.arms.atk : 0)) * (userInfo.equip.fire ? userInfo.equip.fire.atk + 1 : 1);
    if (userInfo.sect == "云岚宗" && userInfo.bigMap == "魔兽山脉") {
      uatk = parseInt(uatk * 1.2);
    }
    if (checkUserBag(userInfo, "轩辕剑", 1) && monster.lv - userInfo.lv < 20) {
      uatk = 99999;
      SendMsgToUser(userInfo.name, "触发神器[轩辕剑],本次战斗必定胜利!");
    }
    let udef = userInfo.lv * 10 + (userInfo.equip.armor ? userInfo.equip.armor.def : 0);
    let uhp = userInfo.hp;
    let matk = monster.atk;
    let mdef = monster.def;
    let mhp = monster.hp;
    let round = 0;
    let isWin = false;
    let battleMsg = `一一一${userInfo.name} PK ${monster.name}一一一`;
    do {
      round++;
      let hxyj = Math.random() * 100 > 70;
      uhp = uhp - (matk > udef ? matk - udef : 0);
      if (hxyj) {
        mhp = mhp - (uatk > mdef ? uatk * 2 - mdef : 0);
      } else {
        mhp = mhp - (uatk > mdef ? uatk - mdef : 0);
      }
      battleMsg += `<br>round${round}:${userInfo.name}发动攻击,造成${hxyj ? uatk * 2 : uatk}点伤害!${monster.name}HP:${mhp}`;
      battleMsg += `<br>${monster.name}发动攻击,造成${matk}点伤害!${userInfo.name}HP:${uhp}`;
    } while (uhp > 0 && mhp > 0);
    isWin = uhp > 0 ? true : false;
    // console.log(battleMsg)
    let cb = {
      isWin: isWin,
      battleMsg: battleMsg,
    };
    resolve(cb);
  });
}

怪物的攻击力算法

if (this.lv - userInfo.lv > 20) {
        this.atk = 9999999;
    } else if (this.lv - userInfo.lv > 15) {
        this.atk = parseInt(this.lv * 20 + 100 * Math.random() * 28 + 4);
    } else if (this.lv - userInfo.lv > 10) {
        this.atk = parseInt(this.lv * 12 + 50 * Math.random() * 21 + 3);
    } else if (this.lv - userInfo.lv > 7) {
        this.atk = parseInt(this.lv * 8 + 20 * Math.random() * 14 + 2);
    } else if (this.lv - userInfo.lv > 3) {
        this.atk = parseInt(this.lv * 7 + 10 * Math.random() * 7 + 1);
    } else {
        this.atk = parseInt(this.lv * 7);
    }

战斗代码分析

以下是小冰战斗代码的详细分析,该函数接受两个参数:

  1. userInfo:包含用户信息的对象,如等级(lv)、装备(equip)、宗门(sect)、所在地图(bigMap)等。
  2. monster:包含怪物信息的对象,如攻击力(atk)、防御力(def)、生命值(hp)等。

用户攻击力计算

let uatk = (userInfo.lv * 10 + (userInfo.equip.arms ? userInfo.equip.arms.atk : 0)) * (userInfo.equip.fire ? userInfo.equip.fire.atk + 1 : 1);

这里计算了用户的攻击力(uatk),它基于用户等级、所持武器的攻击力以及火器的加成。如果用户所属宗门为“云岚宗”且所在地图为“魔兽山脉”,攻击力还会额外提升20%。

轩辕剑效果检查

if (checkUserBag(userInfo, "轩辕剑", 1)) {
    uatk = 99999;
    SendMsgToUser(userInfo.name, "触发神器[轩辕剑],本次战斗(20级内)必定胜利!");
}

如果用户背包中有“轩辕剑”,并且数量至少为1,则攻击力设定为99999,确保战斗胜利。SendMsgToUser函数用于向用户发送消息。

防御力和生命值初始化

let udef = userInfo.lv * 10 + (userInfo.equip.armor ? userInfo.equip.armor.def : 0);
let uhp = userInfo.hp;
let matk = monster.atk;
let mdef = monster.def;
let mhp = monster.hp;

初始化用户的防御力(udef)、生命值(uhp),以及怪物的攻击力(matk)、防御力(mdef)、生命值(mhp)。

战斗循环逻辑分析

变量初始化

  • round:初始化回合数为0。
  • isWin:初始化胜负标志为false
  • battleMsg:初始化战斗信息字符串,包含用户和怪物的名字。

主循环

do {
    round++;
    let hxyj = Math.random() * 100 > 70;
    uhp = uhp - (matk > udef ? matk - udef : 0);
    if (hxyj) {
        mhp = mhp - (uatk > mdef ? uatk * 2 - mdef : 0);
    } else {
        mhp = mhp - (uatk > mdef ? uatk - mdef : 0);
    }
    // 更新战斗信息
} while (uhp > 0 && mhp > 0);
单轮战斗流程
  1. 回合递增round++,记录当前战斗回合数。
  2. 会心一击判定hxyj = Math.random() * 100 > 70,这是一个随机数生成,若生成的随机数大于70,则认为是会心一击,会心一击有30%的概率发生。
  3. 用户受伤害:用户的生命值uhp根据怪物的攻击力matk和用户的防御力udef减少。如果matk大于udef,则实际受到的伤害为两者之差;否则,伤害为0。
  4. 怪物受伤害:根据hxyj的真假决定怪物是否遭受双倍伤害。如果hxyj为真(会心一击),则伤害为uatk * 2减去怪物的防御力mdef;否则,伤害为uatk减去mdef。同样,如果用户攻击力超过怪物防御力,则实际伤害为差值;否则,伤害为0。

总结

从战斗流程中看出,

用户的攻击力(uatk)、防御力(udef)、生命值(uhp),

怪物的攻击力(matk)、防御力(mdef)、生命值(mhp),

这六个值都关乎到你是否能打败怪物历练成功,而不是我们原先设想的简单的攻击力比较;

暂时我还没有怪物的防御力、生命值算法(此处艾特天道 @Yui ),后续拿到了继续更新!

最后的总结就是,大家都是一群高攻低防的脆皮刺客,就不用想着越15级了,老老实实去炼药打工吧!!

最后说一句,轩辕剑真香啊!

7B04C8B695DBA660DD9520C4005753FC.gif

新增数值计算

看此贴 《小冰游戏战斗数值计算》