mota-js/docs/personalization.md
2017-12-10 20:00:01 +08:00

14 KiB
Raw Blame History

个性化

有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。

自定义素材

所有素材的图片都在images目录下。

animates.png 为所有动画效果。主要是星空熔岩,开门,毒网,传送门之类的效果。为四帧。

enemys.png 为所有怪物的图片。地图生成器中对应的数字从上至下依次是会从201开始计算绿色史莱姆为201小蝙蝠为205依次类推。请注意动画效果为两帧一般是原始四帧中的1和3。四帧中12相同34相同因此只取1和3即可

heros.png为勇士行走图。这里是4*3的,你也可以用4*4的,不过需要一些修改,之后会提到。

items.png 为所有道具的图标。

npcs.png 为所有NPC的图标也是两帧。

terrains.png 为所有地形的图标。

系统会读取icon.js文件并获取每个ID对应的图标所在的位置。

地图生成器使用自定义素材

地图生成器可以将数字和图标一一对应,从数字生成图标或从图标生成数字。

在使用自定义素材后,我们可以使用地图生成器来识别新的素材。打开同目录下的meaning.txt,按照已有的方式来增加或编辑内容即可。

第一列是地图生成器中的数字,第二列是它所在的文件名,第三列是坐标。 地图含义

使用自定义地形(路面、墙壁等)

你需要自行P一张图里面是你需要的地形素材。然后将其覆盖terrains.png文件,请注意所有元件的位置需要完全相同对应。

岩浆、星空、传送门、箭头、门的开启动画、暗墙的开启动画在animates.png中,可能也需要对应进行修改。

请打开items.js中,对比素材的位置。

另外需要注意的一点是,本样板不支持Autotile,换句话说野外地图(草地等)这种自然风可能不会太适合。

使用自定义道具图标

如果你觉得已有的道具图标不够,想自己添加图标也是可以的。

如果items.png中不存在你需要的图标则可以自己P一张图将你需要的图标覆盖到某个用不到的图标上。或者也可以接着后面向下拉伸。

所有道具必须是32x32像素。 P图完毕后可以在地图生成器中加入对应的数字和图标的对应关系。

要在系统中启用你的图标你需要自己指定一个道具的ID不能和任何已有的重名然后进行如下操作

  • items.js中道具的定义列表中编辑,修改你的自定义道具的名称,类型,说明文字等。
    • 即捡即用类道具的cls为items消耗类道具的cls为tools永久类道具的cls为constants。
  • icon.js找到items一栏往里面添加你的图标位置。
  • maps.js中,找到对应位置,往里面添加自己的数字和道具的一一对应关系。(该数字可任意指定,不能和已有的冲突),类似下面这样
if (id == 60) tmp.event = {'cls': 'items', 'id': 'curseWine'} // 解咒药水
if (id == 61) tmp.event = {'cls': 'items', 'id': 'superWine'} // 万能药水
if (id == 62) tmp.event = {'cls': 'items', 'id': 'knife'} // 屠龙匕首
if (id == 63) tmp.event = {'cls': 'items', 'id': 'moneyPocket'} // 金钱袋
if (id == 64) tmp.event = {'cls': 'items', 'id': 'shoes'} // 绿鞋
if (id == 65) tmp.event = {'cls': 'items', 'id': 'hammer'} // 圣锤

有关如何自行实现一个道具的效果,参见自定义道具效果

使用自定义怪物图标

如果你觉得已有的怪物图标不够,也可以自行向后添加你需要的怪物。

enemys.js直接向后P图并将你需要的怪物的两帧动画放到正确的位置注意普通四帧动画的1和3帧

P图完毕后可以在地图生成器中加入对应的数字和图标的对应关系。

要在系统中启用你的图标你需要自己指定一个怪物的ID不能和任何已有的重名然后进行如下操作

  1. enemys.js中,向怪物的定义列表中,添加一个怪物。
  2. icon.js找到enemys一栏往里面添加你的图标位置。
  3. maps.js中,找到对应位置,往里面添加自己的数字和怪物的一一对应关系。一般对于怪物而言,对应的数字就是200+位置。

有关如何自行实现一个怪物的特殊属性或伤害计算公式,参见怪物的特殊属性

使用自定义NPC图标

同上你也可以自定义NPC图标。只需要将你NPC的两帧动画接到npcs.js中即可。

P图完毕后可以在地图生成器中加入对应的数字和图标的对应关系。

要在系统中启用你的图标你需要自己指定一个NPC的ID不能和任何已有的重名然后进行如下操作

  1. icon.js找到npcs一栏往里面添加你的图标位置。
  2. maps.js找到对应位置往里面添加自己的数字和NPC的一一对应关系。
// 121-150 NPC
    if (id == 121) tmp.event = {'cls': 'npcs', 'id': 'man'};
    if (id == 122) tmp.event = {'cls': 'npcs', 'id': 'woman'};
    if (id == 123) tmp.event = {'cls': 'npcs', 'id': 'thief'};
    if (id == 124) tmp.event = {'cls': 'npcs', 'id': 'fairy'};
    if (id == 125) tmp.event = {'cls': 'npcs', 'id': 'magician'};
    if (id == 126) tmp.event = {'cls': 'npcs', 'id': 'womanMagician'};

使用自定义勇士图标

我们同样可以使用自定义的勇士图标,比如小可绒之类。

拿一个勇士的行走图覆盖hero.png即可。

请注意:勇士必须是32x32像素,不能使用超过32x32的图片。

覆盖了hero.png后,我们需要在icons.js中编辑图标的位置信息。

'heros': {
  'hero1': {
    'down': {'loc': 0, 'stop': 0, 'leftFoot': 1, 'rightFoot': 2},
    'left': {'loc': 1, 'stop': 0, 'leftFoot': 1, 'rightFoot': 2},
    'right': {'loc': 2, 'stop': 0, 'leftFoot': 1, 'rightFoot': 2},
    'up': {'loc': 3, 'stop': 0, 'leftFoot': 1, 'rightFoot': 2}
  }
},

hero1为勇士IDdata.js中的ID对应一般不修改。

接着down/left/right/up是勇士四个朝向每个朝向中的loc表示是在hero.png中的第几行后面的stopleftFoorrightFoot分别是停止图左脚行走图和右脚行走图在该行的第几列就行。

我们只需要覆盖图片后编辑这里即可。即使是4x4的行走图,也是没问题的(需要指定左脚和右脚所在的第几列)。

通过上述这几种方式,我们可以修改素材图片(使用自定义素材),指定数字并放入地图生成器中,然后在系统中进行启用。

!> 请注意:强制要求所有素材都必须是32x32的,不然可能会造成不可预料的后果。

自定义道具效果

本节中将继续介绍如何自己编辑一个道具的效果。

道具效果的具体实现都在items.js中。

即捡即用类道具cls: items

对于即捡即用类道具,如宝石、血瓶、剑盾等,我们可以简单地修改data.js中的value一栏即可。

如果你有更高级的需求(例如每个区域的效果不同),则需要编辑items.js文件。具体方式是:

  1. 找到getItemEffect函数;所有即捡即用类道具的效果都在这里实现。
  2. 算道具效果系数,或应该增加的值。
  3. 修改同样修改下面的getItemEffectTip函数,使提示文字相应变动。
items.prototype.getItemEffect = function(itemId, itemNum) {
    var itemCls = core.material.items[itemId].cls;
    // 消耗品
    if (itemCls === 'items') {
        if (itemId === 'redJewel') core.status.hero.atk += core.values.redJewel;
        if (itemId === 'blueJewel') core.status.hero.def += core.values.blueJewel;
        if (itemId === 'greenJewel') core.status.hero.mdef += core.values.greenJewel;
        if (itemId == 'yellowJewel') { // 黄宝石属性:需自己定义
            core.status.hero.hp+=1000;
            core.status.hero.atk+=6;
            core.status.hero.def+=6;
            core.status.hero.mdef+=10;
        }
        if (itemId === 'redPotion') core.status.hero.hp += core.values.redPotion;
        if (itemId === 'bluePotion') core.status.hero.hp += core.values.bluePotion;
        if (itemId === 'yellowPotion') core.status.hero.hp += core.values.yellowPotion;
        if (itemId === 'greenPotion') core.status.hero.hp += core.values.greenPotion;
        if (itemId === 'sword1') core.status.hero.atk += core.values.sword1;
        if (itemId === 'sword2') core.status.hero.atk += core.values.sword2;
        if (itemId == 'sword3') core.status.hero.atk += core.values.sword3;
        if (itemId == 'sword4') core.status.hero.atk += core.values.sword4;
        if (itemId === 'sword5') core.status.hero.atk += core.values.sword5;
        if (itemId === 'shield1') core.status.hero.def += core.values.shield1;
        if (itemId === 'shield2') core.status.hero.def += core.values.shield2;
        if (itemId === 'shield3') core.status.hero.def += core.values.shield3;
        if (itemId === 'shield4') core.status.hero.def += core.values.shield4;
        if (itemId === 'shield5') core.status.hero.def += core.values.shield5;
        if (itemId === 'bigKey') { // 只有是钥匙盒才会执行这一步
            core.status.hero.items.keys.yellowKey++;
            core.status.hero.items.keys.blueKey++;
            core.status.hero.items.keys.redKey++;
        }
        if (itemId == 'superPotion') core.status.hero.hp *= 2;
        if (itemId == 'moneyPocket') core.status.hero.money += core.values.moneyPocket;
    }
    else {
        core.addItem(itemId, itemNum);
    }
}

!> 请注意这里core.status.thisMap.name获取的是当前层中你在剧本文件里写的name那一项即状态栏中的层数显示。然后可以通过几个简单的if来判断应该增加的值。

消耗类道具cls: tools永久类道具cls: constants

如果要自己实现消耗类道具或永久类道具的使用效果,则需修改items.js中的canUseItem和useItem两个函数。 具体过程比较复杂需要一定的JS能力在这里就不多说了有需求可以找艾之葵进行了解。 但值得一提的是,我们可以使用core.hasItem(name) 来判断是否某个道具是否存在。例如下面是passNet通过路障处理的一部分

/****** 经过路障 ******/
events.prototype.passNet = function (data) {
    // 有鞋子
    if (core.hasItem('shoes')) return;
    if (data.event.id=='lavaNet') { // 血网
        core.status.hero.hp -= core.values.lavaDamage;
        if (core.status.hero.hp<=0) {
            core.status.hero.hp=0;
            core.updateStatusBar();
            core.events.lose('lava');
            return;
        }
        core.drawTip('经过血网,生命-'+core.values.lavaDamage);
    }
    if (data.event.id=='poisonNet') { // 毒网
        if (core.hasFlag('poison')) return;
        core.setFlag('poison', true);
    }
    if (data.event.id=='weakNet') { // 衰网
        if (core.hasFlag('weak')) return;
        core.setFlag('weak', true);
        core.status.hero.atk-=core.values.weakValue;
        core.status.hero.def-=core.values.weakValue;
    }
    if (data.event.id=='curseNet') { // 咒网
        if (core.hasFlag('curse')) return;
        core.setFlag('curse', true);
    }
    core.updateStatusBar();
}

我们进行了一个简单的判断,如果拥有绿鞋,则不进行任何路障的处理。

实战!拿到神圣盾后免疫吸血、领域、夹击效果

  1. 在getItemEffect中修改拿到神圣盾时的效果标记一个自定义Flag。
  2. 免疫吸血效果:在enemys.js的getDamage函数中找到extra_damage并编辑成如果存在神圣盾标记额外伤害为0。
  3. 免疫领域、夹击效果:在events.js找到checkBlock函数并编辑成如果有神圣盾标记则直接返回。
  4. 如果有更高的需求,例如想让吸血效果变成一半(如异空间),则还是在上面这些地方进行对应的修改即可。

自定义怪物属性

如果你对现有的怪物不满意,想自行添加怪物属性(例如让怪物拥有双属性乃至更多属性),也是可以的。具体参见enemys.js文件。

你需自己指定一个special数字修改getSpecialText函数。

如果要修改伤害计算公式请修改下面的calDamage函数。请注意如果无法战斗该函数必须返回999999999

因此无敌属性可以这样设置:

if (hero_atk <= mon_def) return 999999999; // 不可战斗时请直接返回999999999

对于吸血怪的额外伤害计算在getDamage中的extra_damage中。

对于毒衰弱怪物的战斗后结算在events.js中的afterBattle函数中。

对于领域、夹击怪物的检查在events.js中的checkBlock函数中。

getCritical, getCriticalDamagegetDefDamage三个函数依次计算的是该怪物的临界值、临界减伤和1防减伤。也可以适当进行修改。

自定义地图

遗憾的是所有地图数据必须在剧本的map中指定换句话说我们无法在游戏进行中动态修改地图比如为简单难度增加一个血瓶。

幸运的是,我们可以采用如下方式进行难度分歧,为用户简单难度下增加额外的血瓶或宝石。

"firstArrive": [ // 第一次到该楼层触发的事件
  {"type": "if", "condition": "flag:hard!=3", // 判断是否困难难度
    "true": [ // 不为困难,则为普通或简单难度
      {"type": "show", "loc": [3, 6]} // 显示血瓶
      {"type": "if", "condition": "flag:hard==1", // 判断是否是简单难度
        "true": [
          {"type": "show", "loc": [3, 7]} // 简单难度则显示宝石
        ],
        "false": [] // 普通难度则只显示血瓶
      },
    ],
    "false": [] // 困难难度,不进行任何操作
  },
],
"events": {
  "3, 6": {"enable": false} // 比如[3, 6]点是一个血瓶,初始不可见
  "3, 7": {"enable": false} // 比如[3, 7]点是一个宝石,初始不可见
}

如上所示,我们在地图上设置一个额外的血瓶和宝石,并初始时设为禁用状态。

当第一次到达该楼层时,进行一次判断;如果不为困难难度,则将血瓶显示出来;再判断是否为简单难度,如果是则再把宝石显示出来。

通过对flag:hard进行判断的方式,我们也可以达成“对于不同的难度有着不同的地图效果”。