diff --git a/_server/comment.js b/_server/comment.js index a259a8c9..66a28004 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -1,4 +1,4 @@ -comment_c456ea59_6018_45ef_8bcc_211a24c627dc = +var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_leaf": false, "_type": "object", @@ -256,6 +256,15 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_type": "textarea", "_range": "thiseval==null||(thiseval instanceof Array)", "_data": "该图块的不可入方向\n可以在这里定义不能从哪个方向访问该图块,可以达到悬崖之类的效果\n例如 [\"down\", \"right\"] 代表不能从下或右访问此图块\n此值对背景层、事件层、前景层上的图块均有效" + }, + "faceIds": { + "_leaf": true, + "_type": "textarea", + "_data": + "行走图朝向,仅对NPC有效。可以在这里定义同一个NPC的多个朝向行走图。\n" + + "比如 {\"up\":\"N333\",\"down\":\"N334\",\"left\":\"N335\",\"right\":\"N336\"} " + + "就将该素材的上下左右朝向分别绑定到N333,N334,N335和N336四个图块。\n" + + "在勇士撞上NPC时,或NPC在移动时,会自动选择最合适的朝向图块(如果存在定义)来进行绘制。" } } }, diff --git a/_server/data.comment.js b/_server/data.comment.js index 24537bd3..d2493711 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -1,4 +1,4 @@ -data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = +var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_leaf": false, "_type": "object", diff --git a/_server/functions.comment.js b/_server/functions.comment.js index 9bd96f61..d7fb4499 100644 --- a/_server/functions.comment.js +++ b/_server/functions.comment.js @@ -1,4 +1,4 @@ -functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = +var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_leaf": false, "_type": "object", diff --git a/_server/maps.comment.js b/_server/maps.comment.js index ddf8e8e6..be2e8db8 100644 --- a/_server/maps.comment.js +++ b/_server/maps.comment.js @@ -1,4 +1,4 @@ -maps_comment_90f36752_8815_4be8_b32b_d7fad1d0542e = +var maps_comment_90f36752_8815_4be8_b32b_d7fad1d0542e = { ////////////////////////// 地形部分 ////////////////////////// diff --git a/docs/api.md b/docs/api.md index 17d3b1df..c7efe632 100644 --- a/docs/api.md +++ b/docs/api.md @@ -439,6 +439,10 @@ loader.js将主要用来进行资源的加载,比如加载音乐、图片、 maps.js主要用来进行地图相关的的操作。包括绘制地图,获取地图上的点等等。 +core.maps.getNumberById(id) +根据ID来获得对应的数字。如果该ID不存在对应的数字则返回0。 + + core.maps.canMoveHero(x,y,direction,floorId) 判断能否前往某个方向。x,y为坐标,可忽略为当前点;direction为方向,可忽略为当前方向。 floorId为楼层ID,可忽略为当前楼层。 diff --git a/docs/element.md b/docs/element.md index 1d9becba..d636a269 100644 --- a/docs/element.md +++ b/docs/element.md @@ -236,6 +236,49 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数 如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。 +## 怪物和NPC的朝向问题 + +从V2.5.2开始,对于人形怪物和NPC的朝向问题已经有着比较好的解决方式。 + +首先明确一点的是,和RM不同,H5中即使是对同一个怪物/NPC的不同朝向,也需要分别将其各个朝向素材追加对应的图片上,并进行注册。 + +### 怪物的朝向问题 + +对于同一个怪物的不同朝向,需要对每个朝向创建一个怪物(属性完全相同),这样就可以在地图上绘制不同朝向的怪物。 + +但是这样会存在一个问题,就是怪物手册中怪物的每个朝向都会显示成一个单独的怪物。 + +为了避免这种情况的发生,在怪物的属性中存在一个`displayIdInBook`项,**我们可以指定该项来控制每个怪物在怪物手册中中显示成的怪物。** + +举个例子,假设我现在有个怪物,其向下的行走图ID是`E300`,其向左的行走图ID是`E301`,向右的行走图ID是`E302`。分别对这几个怪物填写完全相同的怪物属性。 + +如果我在地图上同时绘制向下、向左和向右的该怪物,则确实能在地图上显示出来不同的朝向,但是在怪物手册中会同时显示这三种类型的怪物,观感较差。 + +我们可以给`E301`和`E302`怪物属性中的`displayIdInBook`项填写为`"E300"`。 + +这样的话,在怪物手册中,所有的E301和E302均会被视为E300并进行合并。即使只有一只朝向左的怪物(E301),怪物手册仍然会按E300进行显示。 + +从而完美解决了同种怪物不同朝向在怪物手册的显示问题。 + +### NPC的朝向问题 + +和怪物不同的是,NPC朝向问题更复杂一点。 + +在NPC的图块属性中,存在一个`faceIds`的项目,可以用其来绑定一个图块所对应的其他朝向的图块ID。 + +举个例子,假设我存在一个NPC,其向上的图块ID是N333,向下的图块ID是N334,向左的图块ID是N335,不存在向右的图块ID。 + +则可以在这几个图块属性中的`faceIds`中写:`{"up": "N333", "down": "N334", "left": "N335"}`。 + +当勇士从左边撞上此怪物后,将从该图块的图块属性中的faceIds中寻求`left`所对应的ID。 +如果存在定义(如N335),则会在触发对话事件前改变当前图块为N335,看起来就是在对话前进行了转向,面向勇士。 + +!> 请注意,在对话结束后朝向不会切换回来,因此如果有必要切换朝向请在事件结束前调用转变图块事件。 + +同理,使用移动事件让NPC在行走时,不同朝向的行走会自动调用`faceIds`中不同朝向的ID所对应的行走图,看起来就是在行走时也可以不断转向了。 + +从而,完美解决了NPC的朝向问题(碰触时面向勇士、行走时改变朝向)。 + ## 路障,楼梯,传送门 血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在 `data.js` 的values内定义。 diff --git a/libs/events.js b/libs/events.js index f8f105aa..f4349b4b 100644 --- a/libs/events.js +++ b/libs/events.js @@ -60,7 +60,18 @@ events.prototype.init = function () { callback(); }, 'action': function (data, core, callback) { - core.events.insertAction(data.event.data, data.x, data.y, callback); + var ev = core.clone(data.event.data), ex = data.x, ey = data.y; + // 检查是否需要改变朝向 + if (ex == core.nextX() && ey == core.nextY()) { + var dir = {"up":"down","down":"up","left":"right","right":"left"}[core.getHeroLoc('direction')]; + var id = data.event.id, toId = (data.event.faceIds||{})[dir]; + if (core.isset(toId) && id!=toId) { + var number = core.maps.getNumberById(toId); + if (number>0) + core.setBlock(number, ex, ey); + } + } + core.events.insertAction(ev, ex, ey, callback); } } } diff --git a/libs/maps.js b/libs/maps.js index b8067506..1c2a18c5 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -49,6 +49,24 @@ maps.prototype.loadFloor = function (floorId, map) { return content; } +////// 从ID获得数字 ////// +maps.prototype.getNumberById = function (id) { + for (var number in this.blocksInfo) { + if ((this.blocksInfo[number]||{}).id == id) + return parseInt(number)||0; + } + // tilesets + if (/^X\d+$/.test(id)) { + var info = core.icons.getTilesetOffset(id); + if (info!=null) return parseInt(id.substring(1)); + } + return parseInt(id.substring(1)); + // 特殊ID + if (id == 'none') return 0; + if (id == 'airwall') return 17; + return 0; +} + ////// 数字和ID的对应关系 ////// maps.prototype.initBlock = function (x, y, id) { var disable=null; @@ -741,6 +759,7 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { block=block.block; var image, bx, by, height = block.event.height || 32; + var faceIds = {}; if (block.event.cls == 'tileset') { var offset = core.icons.getTilesetOffset(block.event.id); if (offset==null) { @@ -765,6 +784,7 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { image = core.material.images[block.event.cls]; bx = 0; by = core.material.icons[block.event.cls][block.event.id]; + faceIds = block.event.faceIds||{}; } var opacityVal = 1; @@ -835,9 +855,20 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { } else { // 移动中 + var direction = moveSteps[0]; + if (step == 0) { + // 根据faceIds修改朝向 + var currid = faceIds[direction]; + if (core.isset(currid)) { + var tby = core.material.icons[block.event.cls][currid]; + if (core.isset(tby)) + by = tby; + } + } + step++; - nowX+=scan[moveSteps[0]].x*2; - nowY+=scan[moveSteps[0]].y*2; + nowX+=scan[direction].x*2; + nowY+=scan[direction].y*2; core.clearMap('route', nowX-32, nowY-32, 96, 96); // 绘制 core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, nowX, nowY-height+32, 32, height);