From fb069ff78fec4885c602ec098425a43d5267aa68 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 26 Sep 2018 11:31:53 +0800 Subject: [PATCH 01/10] Sync SL Panel --- libs/ui.js | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 65c107b6..3a76ed11 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1918,20 +1918,32 @@ ui.prototype.drawSLPanel = function(index, refresh) { if (!core.isset(core.status.event.ui)) core.status.event.ui = []; - core.clearMap('ui'); - core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, 416, 416, '#000000'); - core.setAlpha('ui', 1); - core.canvas.ui.textAlign = 'center'; - var u=416/6, size=118; var strokeColor = '#FFD700'; if (core.status.event.selection) strokeColor = '#FF6A6A'; - var name=core.status.event.id=='save'?"存档":core.status.event.id=='load'?"读档":core.status.event.id=='replayLoad'?"回放":""; + var drawBg = function() { + core.clearMap('ui'); + core.setAlpha('ui', 0.85); + core.fillRect('ui', 0, 0, 416, 416, '#000000'); + core.setAlpha('ui', 1); + + core.ui.drawPagination(page+1, max_page, 12); + core.canvas.ui.textAlign = 'center'; + // 退出 + core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px Verdana'); + + if (core.status.event.selection) + core.setFillStyle('ui', '#FF6A6A'); + if (core.status.event.id=='save') + core.fillText('ui', '删除模式', 48, 403); + else + core.fillText('ui', '输入编号', 48, 403); + } var draw = function (data, i) { + var name=core.status.event.id=='save'?"存档":core.status.event.id=='load'?"读档":core.status.event.id=='replayLoad'?"回放":""; core.status.event.ui[i] = data; var id=5*page+i; if (i<3) { @@ -1972,6 +1984,7 @@ ui.prototype.drawSLPanel = function(index, refresh) { } function drawAll() { + drawBg(); for (var i=0;i<6;i++) draw(core.status.event.ui[i], i); } @@ -1980,18 +1993,6 @@ ui.prototype.drawSLPanel = function(index, refresh) { loadSave(0, drawAll); } else drawAll(); - - this.drawPagination(page+1, max_page, 12); - core.canvas.ui.textAlign = 'center'; - // 退出 - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px Verdana'); - - if (core.status.event.selection) - core.setFillStyle('ui', '#FF6A6A'); - if (core.status.event.id=='save') - core.fillText('ui', '删除模式', 48, 403); - else - core.fillText('ui', '输入编号', 48, 403); } ////// 绘制一个缩略图 ////// From 1b80adcaf19e3cdb53fe0c613cf5b2d2593ecb27 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Wed, 26 Sep 2018 19:58:39 +0800 Subject: [PATCH 02/10] Add support for Tilesets --- docs/personalization.md | 29 ++++++++ docs/start.md | 10 +++ index.html | 2 +- libs/core.js | 2 +- libs/events.js | 16 +++- libs/icons.js | 30 ++++++++ libs/loader.js | 25 +++++-- libs/maps.js | 160 +++++++++++++++++++++++++++++++++------- libs/ui.js | 6 ++ main.js | 4 +- project/data.js | 1 + 11 files changed, 246 insertions(+), 39 deletions(-) diff --git a/docs/personalization.md b/docs/personalization.md index db2c17c2..bf4a377e 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -233,6 +233,35 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和 因此,在你修改了icons.js和maps.js两个文件,也就是将素材添加到游戏后,地图生成器的对应关系也将同步更新。 +### 额外素材 + +从V2.4.2开始,HTML5魔塔样板开始支持额外素材。 + +具体而言,通过上面的“素材导入”的方式,确实可以有效地添加素材到游戏。但是,如果想增加大量自定义素材,需要通过便捷PS工具将这些素材全部导入到 +`terrains.png`中,并且全部是单列,极度不友好。这也导致了野外风的制作相对变得很困难,增加了大量素材处理的工作量。 + +额外素材就是为了解决这个问题而被提出。 + +所谓`额外素材`,即用户可以自定导入任意张素材图片,无需PS,无需注册,即可直接在游戏中使用。这一点已经十分向RM靠拢了。 + +要使用额外素材,请将你需要的素材图片放在`images`目录下,并在`全塔属性`的`tilesets`中定义图片名。 + +**该素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)。** + +```js +"tilesets": ["1.png", "2.png"] // 导入两个额外素材,文件名分别是1.png和2.png +``` + +刷新后,系统会自动加载该素材并添加到素材区。 + +额外素材无需导入,无需注册。在`tilesets`中定义了图片后,即可直接使用绘图,无需再注册其数字和ID。其ID、索引和数字均为系统自动分配,且不允许修改。 + +请注意,额外素材的ID、索引和数字,与该图片在tilesets数组中的index及该素材在图片上的位置都有关系。 + +!> **因此如果对`tilesets`数组随意删除或修改顺序,可能会导致所有额外素材全部发生变化!这点请务必注意!!!** + +除此之外,额外素材在游戏中的使用和正式素材都是一致的,也能在前景或背景图层绘制。 + ## 自定义道具效果 本节中将继续介绍如何自己编辑一个道具的效果。 diff --git a/docs/start.md b/docs/start.md index a9bad3e5..f819c427 100644 --- a/docs/start.md +++ b/docs/start.md @@ -178,6 +178,16 @@ 素材注册完毕后,即可在游戏中正常使用,也可以被地图生成器所识别(需要重开地图生成器)。 +### 额外素材 + +从2.4.2开始,H5魔塔样板支持额外素材,你可以导入任意个类似RM中的tilesets文件,且无需注册即可使用。 + +要使用额外素材,请在`全塔属性`中的`tilesets`项,添加额外素材的图片名称,刷新后即可在地图编辑器中使用。 + +额外素材不可注册,其数字、ID和索引都是和该图块在图片上的位置相关,不可编辑。 + +有关额外素材的更多说明参见[额外素材](personalization#额外素材) + ## 控制台调试 HTML5的塔都是可以进行控制台调试的。 diff --git a/index.html b/index.html index 56128d9d..7710ce4e 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ - + HTML5魔塔 diff --git a/libs/core.js b/libs/core.js index f3bab34c..e049fe92 100644 --- a/libs/core.js +++ b/libs/core.js @@ -191,7 +191,6 @@ core.prototype.init = function (coreData, callback) { document.title = core.firstData.title + " - HTML5魔塔"; document.getElementById("startLogo").innerHTML = core.firstData.title; core.material.items = core.clone(core.items.getItems()); - core.initStatus.maps = core.maps.initMaps(core.floorIds); core.material.enemys = core.clone(core.enemys.getEnemys()); core.material.icons = core.icons.getIcons(); core.material.events = core.events.getEvents(); @@ -299,6 +298,7 @@ core.prototype.init = function (coreData, callback) { console.log(core.material); // 设置勇士高度 core.material.icons.hero.height = core.material.images.hero.height/4; + core.initStatus.maps = core.maps.initMaps(core.floorIds); core.setRequestAnimationFrame(); core.showStartAnimate(); diff --git a/libs/events.js b/libs/events.js index 357bb26a..0dfa58c4 100644 --- a/libs/events.js +++ b/libs/events.js @@ -373,14 +373,14 @@ events.prototype.doAction = function() { if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { core.animateBlock(data.loc,'show', data.time, function () { data.loc.forEach(function (t) { - core.showBlock(t[0],t[1],data.floorId) + core.showBlock(t[0],t[1],data.floorId); }) core.events.doAction(); }); } else { data.loc.forEach(function (t) { - core.showBlock(t[0],t[1],data.floorId) + core.showBlock(t[0],t[1],data.floorId); }) this.doAction(); } @@ -392,14 +392,22 @@ events.prototype.doAction = function() { && (typeof data.loc[1] == 'number' || typeof data.loc[1] == 'string')) data.loc = [[core.calValue(data.loc[0]), core.calValue(data.loc[1])]]; data.loc.forEach(function (t) { - core.removeBlock(t[0],t[1],data.floorId); + core.maps.eraseBlock(t[0],t[1],data.floorId); }) if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { core.animateBlock(data.loc,'hide',data.time, function () { + data.loc.forEach(function (t) { + core.removeBlock(t[0],t[1],data.floorId) + }) core.events.doAction(); }); } - else this.doAction(); + else { + data.loc.forEach(function (t) { + core.removeBlock(t[0],t[1],data.floorId) + }) + this.doAction(); + } break; case "setBlock": // 设置某图块 { diff --git a/libs/icons.js b/libs/icons.js index f1a557a1..149c1361 100644 --- a/libs/icons.js +++ b/libs/icons.js @@ -5,8 +5,38 @@ function icons() { icons.prototype.init = function () { this.icons = icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1; //delete(icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1); + + // tileset的起点 + this.tilesetStartOffset = 10000; } icons.prototype.getIcons = function () { return this.icons; +} + +////// 根据图块数字或ID获得所在的tileset和坐标信息 ////// +icons.prototype.getTilesetOffset = function (id) { + + if (typeof id == 'string') { + // Tileset的ID必须是 X+数字 的形式 + if (!/^X\d+$/.test(id)) return null; + id = parseInt(id.substring(1)); + } + else if (typeof id != 'number') { + return null; + } + + core.tilesets = core.tilesets || []; + var startOffset = this.tilesetStartOffset; + for (var i in core.tilesets) { + var imgName = core.tilesets[i]; + var img = core.material.images.tilesets[imgName]; + var width = Math.floor(img.width/32), height = Math.floor(img.height/32); + if (id>=startOffset && id32) { core.canvas.event2.clearRect(block.x * 32 + dx, block.y * 32 + 32 - height + dy, 32, height-32) - core.canvas.event2.drawImage(blockImage, animate * 32, blockIcon * height, 32, height-32, block.x * 32 + dx, block.y*32 + 32 - height + dy, 32, height-32); + core.canvas.event2.drawImage(image, x * 32, y * height, 32, height-32, block.x * 32 + dx, block.y*32 + 32 - height + dy, 32, height-32); } } @@ -379,6 +399,12 @@ maps.prototype.drawBgFgMap = function (floorId, canvas, name) { var id = block.event.id, cls = block.event.cls; if (cls == 'autotile') core.drawAutotile(canvas, arr, block, 32, 0, 0); + else if (cls == 'tileset') { + var offset = core.icons.getTilesetOffset(id); + if (offset!=null) { + canvas.drawImage(core.material.images.tilesets[offset.image], 32*offset.x, 32*offset.y, 32, 32, 32*block.x, 32*block.y, 32, 32); + } + } else canvas.drawImage(core.material.images[cls], 0, core.material.icons[cls][id] * 32, 32, 32, x * 32, y * 32, 32, 32); } @@ -390,6 +416,7 @@ maps.prototype.drawBgFgMap = function (floorId, canvas, name) { ////// 绘制某张地图 ////// maps.prototype.drawMap = function (mapName, callback) { + mapName = mapName || core.status.floorId; core.clearMap('all'); core.removeGlobalAnimate(null, null, true); var drawBg = function(){ @@ -465,11 +492,9 @@ maps.prototype.drawMap = function (mapName, callback) { if (block.event.cls == 'autotile') { core.drawAutotile(core.canvas.event, mapArray, block, 32, 0, 0); } - else { - if (block.event.id!='none') { - core.drawBlock(block); - core.addGlobalAnimate(block); - } + else if (block.event.id!='none') { + core.drawBlock(block); + core.addGlobalAnimate(block); } } } @@ -675,13 +700,32 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { core.setAlpha('ui', 1.0); block=block.block; - var blockIcon = core.material.icons[block.event.cls][block.event.id]; - var blockImage = core.material.images[block.event.cls]; - var height = block.event.height || 32; + + var image, bx, by, height = block.event.height || 32; + if (block.event.cls == 'tileset') { + var offset = core.icons.getTilesetOffset(block.event.id); + if (offset==null) { + if (core.isset(callback)) callback(); + return; + } + bx = offset.x; + by = offset.y; + image = core.material.images.tilesets[offset.image]; + } + // 不支持autotile + else if (block.event.cls == 'autotile') { + if (core.isset(callback)) callback(); + return; + } + else { + image = core.material.images[block.event.cls]; + bx = 0; + by = core.material.icons[block.event.cls][block.event.id]; + } var opacityVal = 1; core.setOpacity('route', opacityVal); - core.canvas.route.drawImage(blockImage, 0, blockIcon * height, 32, height, block.x * 32, block.y * 32 +32 - height, 32, height); + core.canvas.route.drawImage(image, bx * 32, by * height, 32, height, block.x * 32, block.y * 32 +32 - height, 32, height); // 要运行的轨迹:将steps展开 var moveSteps=[]; @@ -721,6 +765,9 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { animateTime = 0; if (animateCurrent>=animateValue) animateCurrent=0; } + if (block.event.cls=='tileset') { + animateCurrent = bx; + } // 已经移动完毕,消失 if (moveSteps.length==0) { @@ -728,7 +775,7 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { else opacityVal -= 0.06; core.setOpacity('route', opacityVal); core.clearMap('route', nowX, nowY-height+32, 32, height); - core.canvas.route.drawImage(blockImage, animateCurrent * 32, blockIcon * height, 32, height, nowX, nowY-height+32, 32, height); + core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, nowX, nowY-height+32, 32, height); if (opacityVal<=0) { clearInterval(animate); core.clearMap('route'); @@ -749,7 +796,7 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { nowY+=scan[moveSteps[0]].y*2; core.clearMap('route', nowX-32, nowY-32, 96, 96); // 绘制 - core.canvas.route.drawImage(blockImage, animateCurrent * 32, blockIcon * height, 32, height, nowX, nowY-height+32, 32, height); + core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, nowX, nowY-height+32, 32, height); if (step==16) { // 该移动完毕,继续 step=0; @@ -778,13 +825,31 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) { core.setAlpha('ui', 1.0); block=block.block; - var blockIcon = core.material.icons[block.event.cls][block.event.id]; - var blockImage = core.material.images[block.event.cls]; - var height = block.event.height || 32; + var image, bx, by, height = block.event.height || 32; + if (block.event.cls == 'tileset') { + var offset = core.icons.getTilesetOffset(block.event.id); + if (offset==null) { + if (core.isset(callback)) callback(); + return; + } + bx = offset.x; + by = offset.y; + image = core.material.images.tilesets[offset.image]; + } + // 不支持autotile + else if (block.event.cls == 'autotile') { + if (core.isset(callback)) callback(); + return; + } + else { + image = core.material.images[block.event.cls]; + bx = 0; + by = core.material.icons[block.event.cls][block.event.id]; + } var opacityVal = 1; core.setOpacity('route', opacityVal); - core.canvas.route.drawImage(blockImage, 0, blockIcon * height, 32, height, block.x * 32, block.y * 32 +32 - height, 32, height); + core.canvas.route.drawImage(image, bx*32, by * height, 32, height, block.x * 32, block.y * 32 +32 - height, 32, height); core.playSound('jump.mp3'); @@ -823,18 +888,21 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) { animateTime = 0; if (animateCurrent >= animateValue) animateCurrent = 0; } + if (block.event.cls=='tileset') { + animateCurrent = bx; + } if (jump_count>0) { core.clearMap('route', drawX(), drawY()-height+32, 32, height); updateJump(); - core.canvas.route.drawImage(blockImage, animateCurrent * 32, blockIcon * height, 32, height, drawX(), drawY()-height+32, 32, height); + core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, drawX(), drawY()-height+32, 32, height); } else { if (keep) opacityVal=0; else opacityVal -= 0.06; core.setOpacity('route', opacityVal); core.clearMap('route', drawX(), drawY()-height+32, 32, height); - core.canvas.route.drawImage(blockImage, animateCurrent * 32, blockIcon * height, 32, height, drawX(), drawY()-height+32, 32, height); + core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, drawX(), drawY()-height+32, 32, height); if (opacityVal<=0) { clearInterval(animate); core.clearMap('route'); @@ -865,10 +933,29 @@ maps.prototype.animateBlock = function (loc,type,time,callback) { var block = core.getBlock(t[0],t[1],null,true); if (block==null) return; block=block.block; + var image, bx, by, height = block.event.height || 32; + if (block.event.cls == 'tileset') { + var offset = core.icons.getTilesetOffset(block.event.id); + if (offset==null) { + if (core.isset(callback)) callback(); + return; + } + bx = offset.x; + by = offset.y; + image = core.material.images.tilesets[offset.image]; + } + // 不支持autotile + else if (block.event.cls == 'autotile') { + return; + } + else { + image = core.material.images[block.event.cls]; + bx = 0; + by = core.material.icons[block.event.cls][block.event.id]; + } list.push({ - 'x': t[0], 'y': t[1], 'height': block.event.height||32, - 'blockIcon': core.material.icons[block.event.cls][block.event.id], - 'blockImage': core.material.images[block.event.cls] + 'x': t[0], 'y': t[1], 'height': height, + 'bx': bx, 'by': by, 'image': image }) }) @@ -880,7 +967,7 @@ maps.prototype.animateBlock = function (loc,type,time,callback) { core.status.replay.animate=true; var draw = function () { list.forEach(function (t) { - core.canvas.route.drawImage(t.blockImage, 0, t.blockIcon*t.height, 32, t.height, t.x*32, t.y*32+32-t.height, 32, t.height); + core.canvas.route.drawImage(t.image, t.bx*32, t.by*t.height, 32, t.height, t.x*32, t.y*32+32-t.height, 32, t.height); }) } @@ -923,6 +1010,27 @@ maps.prototype.showBlock = function(x, y, floodId) { } } +////// 只隐藏但不删除某块 ////// +maps.prototype.eraseBlock = function (x, y, floorId) { + floorId = floorId || core.status.floorId; + + var block = core.getBlock(x,y,floorId,true); + if (block==null) return; // 不存在 + + // 删除动画,清除地图 + if (floorId==core.status.floorId) { + core.removeGlobalAnimate(x, y); + core.canvas.event.clearRect(x * 32, y * 32, 32, 32); + var height = 32; + if (core.isset(block.block.event)) height=block.block.event.height||32; + if (height>32) + core.canvas.event2.clearRect(x * 32, y * 32 +32-height, 32, height-32); + } + + block.disable = true; + core.updateStatusBar(); +} + ////// 将某个块从启用变成禁用状态 ////// maps.prototype.removeBlock = function (x, y, floorId) { floorId = floorId || core.status.floorId; diff --git a/libs/ui.js b/libs/ui.js index 3a76ed11..eb6be6d8 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2039,6 +2039,12 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente if (block.event.cls == 'autotile') { core.drawAutotile(tempCanvas, mapArray, block, 32, 0, 0); } + else if (block.event.cls == 'tileset') { + var offset = core.icons.getTilesetOffset(block.event.id); + if (offset!=null) { + tempCanvas.drawImage(core.material.images.tilesets[offset.image], 32*offset.x, 32*offset.y, 32, 32, 32*block.x, 32*block.y, 32, 32); + } + } else { if (block.event.id!='none') { var blockIcon = core.material.icons[block.event.cls][block.event.id]; diff --git a/main.js b/main.js index b5720c43..37534975 100644 --- a/main.js +++ b/main.js @@ -67,7 +67,7 @@ function main() { 'loader', 'control', 'utils', 'items', 'icons', 'maps', 'enemys', 'events', 'actions', 'data', 'ui', 'core' ]; this.pureData = [ - "data","enemys","icons","maps","items","functions" + 'data', 'enemys', 'icons', 'maps', 'items', 'functions' ]; this.materials = [ 'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains', 'enemy48', 'npc48' @@ -182,7 +182,7 @@ main.prototype.init = function (mode, callback) { main.loaderFloors(function() { var coreData = {}; - ["dom", "statusBar", "canvas", "images", "materials", + ["dom", "statusBar", "canvas", "images", "tilesets", "materials", "animates", "bgms", "sounds", "floorIds", "floors"].forEach(function (t) { coreData[t] = main[t]; }) diff --git a/project/data.js b/project/data.js index 8ddfa7b1..8b487b92 100644 --- a/project/data.js +++ b/project/data.js @@ -11,6 +11,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "images": [ "bg.jpg" ], + "tilesets": [], "animates": [ "hand", "sword", From f710f7c04eb1ab0939464344fc445cfc244b9bb3 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Wed, 26 Sep 2018 20:15:02 +0800 Subject: [PATCH 03/10] Add support for Tilesets --- docs/personalization.md | 3 +-- libs/loader.js | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/personalization.md b/docs/personalization.md index bf4a377e..ab9ed33e 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -237,8 +237,7 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和 从V2.4.2开始,HTML5魔塔样板开始支持额外素材。 -具体而言,通过上面的“素材导入”的方式,确实可以有效地添加素材到游戏。但是,如果想增加大量自定义素材,需要通过便捷PS工具将这些素材全部导入到 -`terrains.png`中,并且全部是单列,极度不友好。这也导致了野外风的制作相对变得很困难,增加了大量素材处理的工作量。 +具体而言,通过上面的“素材导入”的方式,确实可以有效地添加素材到游戏。但是,如果想增加大量自定义素材,需要通过便捷PS工具将这些素材全部导入到`terrains.png`中,并且全部是单列,极度不友好。这也导致了野外风的制作相对变得很困难,增加了大量素材处理的工作量。 额外素材就是为了解决这个问题而被提出。 diff --git a/libs/loader.js b/libs/loader.js index 26219691..3e84d733 100644 --- a/libs/loader.js +++ b/libs/loader.js @@ -51,6 +51,9 @@ loader.prototype.load = function (callback) { if (img.width%32!=0 || img.height%32!=0) { console.warn("警告!"+imgName+"的宽或高不是32的倍数!"); } + if (img.width * img.height > 32*32*1000) { + console.warn("警告!"+imgName+"上的图块素材个数大于1000!"); + } } core.loader.loadAnimates(); From 1f4a78848fb0800bda83571a46be632e96bcde17 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Wed, 26 Sep 2018 20:24:00 +0800 Subject: [PATCH 04/10] EraseBlockgit add . --- libs/events.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/events.js b/libs/events.js index 0dfa58c4..177d6d3e 100644 --- a/libs/events.js +++ b/libs/events.js @@ -391,10 +391,10 @@ events.prototype.doAction = function() { if ((typeof data.loc[0] == 'number' || typeof data.loc[0] == 'string') && (typeof data.loc[1] == 'number' || typeof data.loc[1] == 'string')) data.loc = [[core.calValue(data.loc[0]), core.calValue(data.loc[1])]]; - data.loc.forEach(function (t) { - core.maps.eraseBlock(t[0],t[1],data.floorId); - }) if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { + data.loc.forEach(function (t) { + core.maps.eraseBlock(t[0],t[1],data.floorId); + }) core.animateBlock(data.loc,'hide',data.time, function () { data.loc.forEach(function (t) { core.removeBlock(t[0],t[1],data.floorId) From f1c4ab8dd430456e6901ccd84aebcaf4a77571f2 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Wed, 26 Sep 2018 20:25:19 +0800 Subject: [PATCH 05/10] hideBlock --- docs/api.md | 11 ++++++++--- libs/core.js | 7 ++++++- libs/events.js | 2 +- libs/maps.js | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/api.md b/docs/api.md index c0e61ca0..699407e0 100644 --- a/docs/api.md +++ b/docs/api.md @@ -225,10 +225,15 @@ core.showBlock(x, y, floorId) 将某个点从禁用变成启用状态。 +core.hideBlock(x, y, floorId) +将某个点从启用变成禁用状态,但不会对其进行删除。 +此函数不会实际将该块从地图中进行删除,而是将该点设置为禁用,以供以后可能的启用事件。 + + core.removeBlock(x, y, floorId) -将某个点删除或从启用变成禁用状态。 -如果该点不存在自定义事件(比如普通的怪物),则将直接从地图中删除。 -否则将该点设置为禁用,以供以后可能的启用事件。 +将从启用变成禁用状态,并尽可能将其从地图上删除。 +和hideBlock相比,如果该点不存在自定义事件(比如门或普通的怪物),则将直接从地图中删除。 +如果存在自定义事件,则简单的禁用它,以供以后可能的启用事件。 core.setBlock(number, x, y, floorId) diff --git a/libs/core.js b/libs/core.js index e049fe92..0c8ec1c2 100644 --- a/libs/core.js +++ b/libs/core.js @@ -723,7 +723,12 @@ core.prototype.showBlock = function(x, y, floodId) { core.maps.showBlock(x,y,floodId); } -////// 将某个块从启用变成禁用状态 ////// +////// 将某个块从启用变成禁用状态,但是并不删除它 ////// +core.prototype.hideBlock = function(x, y, floorId) { + core.maps.hideBlock(x,y,floorId); +} + +////// 将某个块从启用变成禁用状态,并删除该块 ////// core.prototype.removeBlock = function (x, y, floorId) { core.maps.removeBlock(x,y,floorId); } diff --git a/libs/events.js b/libs/events.js index 177d6d3e..e7246359 100644 --- a/libs/events.js +++ b/libs/events.js @@ -393,7 +393,7 @@ events.prototype.doAction = function() { data.loc = [[core.calValue(data.loc[0]), core.calValue(data.loc[1])]]; if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { data.loc.forEach(function (t) { - core.maps.eraseBlock(t[0],t[1],data.floorId); + core.hideBlock(t[0],t[1],data.floorId); }) core.animateBlock(data.loc,'hide',data.time, function () { data.loc.forEach(function (t) { diff --git a/libs/maps.js b/libs/maps.js index dc61a904..8c6157aa 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -1011,7 +1011,7 @@ maps.prototype.showBlock = function(x, y, floodId) { } ////// 只隐藏但不删除某块 ////// -maps.prototype.eraseBlock = function (x, y, floorId) { +maps.prototype.hideBlock = function (x, y, floorId) { floorId = floorId || core.status.floorId; var block = core.getBlock(x,y,floorId,true); From 458e464f738b033078707ca235e3ad2c20a78e8f Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Wed, 26 Sep 2018 23:39:36 +0800 Subject: [PATCH 06/10] editor-tilesets --- _server/data.comment.js | 7 +++++- _server/editor.js | 48 +++++++++++++++++++++++++++++++++++------ _server/editor_mode.js | 8 +++++++ _server/vm.js | 5 +---- editor-mobile.html | 3 +++ editor.html | 3 +++ 6 files changed, 62 insertions(+), 12 deletions(-) diff --git a/_server/data.comment.js b/_server/data.comment.js index 634859e7..3f5089d2 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -16,7 +16,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "images": { "_leaf": true, "_type": "textarea", - "_data": "在此存放所有可能使用的图片 \n 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 \n 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 \n 依次向后添加" + "_data": "在此存放所有可能使用的图片(tilesets除外) \n 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 \n 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 \n 依次向后添加" + }, + "tilesets": { + "_leaf": true, + "_type": "textarea", + "_data": "在此存放额外素材的图片名, \n 可以自定导入任意张素材图片,无需PS,无需注册,即可直接在游戏中使用 \n 形式如[\"1.png\", \"2.png\"] ,将需要的素材图片放在images目录下 \n 素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)" }, "animates": { "_leaf": true, diff --git a/_server/editor.js b/_server/editor.js index 22a77852..9b1bc7ab 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -81,7 +81,8 @@ editor.prototype.init = function (callback) { editor.prototype.idsInit = function (maps, icons) { editor.ids = [0]; editor.indexs = []; - var MAX_NUM = 1000; + var MAX_NUM = Math.max.apply(null,Object.keys(maps_90f36752_8815_4be8_b32b_d7fad1d0542e)); + editor.MAX_NUM=MAX_NUM; var getInfoById = function (id) { var block = maps.initBlock(0, 0, id); if (hasOwnProp(block, 'event')) { @@ -89,7 +90,7 @@ editor.prototype.idsInit = function (maps, icons) { } } var point = 0; - for (var i = 0; i < MAX_NUM; i++) { + for (var i = 0; i <= MAX_NUM; i++) { var indexBlock = getInfoById(i); editor.indexs[i] = []; if (indexBlock) { @@ -106,6 +107,21 @@ editor.prototype.idsInit = function (maps, icons) { } } editor.indexs[0] = [0]; + + var startOffset = core.icons.tilesetStartOffset; + for (var i in core.tilesets) { + var imgName = core.tilesets[i]; + var img = core.material.images.tilesets[imgName]; + var width = Math.floor(img.width/32), height = Math.floor(img.height/32); + for (var id=startOffset; id= editor.widthsX[spriter][1] && pos.x < editor.widthsX[spriter][2]) { var ysize = spriter.indexOf('48') === -1 ? 32 : 48; loc.ysize = ysize; - pos.y = ~~(loc.y / loc.ysize); - pos.x = editor.widthsX[spriter][1]; pos.images = editor.widthsX[spriter][0]; + pos.y = ~~(loc.y / loc.ysize); + if(core.tilesets.indexOf(pos.images)==-1)pos.x = editor.widthsX[spriter][1]; var autotiles = core.material.images['autotile']; if (pos.images == 'autotile') { var imNames = Object.keys(autotiles); @@ -773,13 +803,17 @@ editor.prototype.listen = function () { } else { if (hasOwnProp(autotiles, pos.images)) editor.info = {'images': pos.images, 'y': 0}; else if (pos.images == 'terrains') editor.info = {'images': pos.images, 'y': pos.y - 1}; + else if (core.tilesets.indexOf(pos.images)!=-1) editor.info = {'images': pos.images, 'y': pos.y, 'x': pos.x-editor.widthsX[spriter][1]}; else editor.info = {'images': pos.images, 'y': pos.y}; for (var ii = 0; ii < editor.ids.length; ii++) { - if (( editor.info.images == editor.ids[ii].images - && editor.info.y == editor.ids[ii].y ) + if ((core.tilesets.indexOf(pos.images)!=-1 && editor.info.images == editor.ids[ii].images + && editor.info.y == editor.ids[ii].y && editor.info.x == editor.ids[ii].x) || (hasOwnProp(autotiles, pos.images) && editor.info.images == editor.ids[ii].id - && editor.info.y == editor.ids[ii].y)) { + && editor.info.y == editor.ids[ii].y) + || (core.tilesets.indexOf(pos.images)==-1 && editor.info.images == editor.ids[ii].images + && editor.info.y == editor.ids[ii].y ) + ) { editor.info = editor.ids[ii]; break; diff --git a/_server/editor_mode.js b/_server/editor_mode.js index f6649baf..ad0ba74f 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -320,10 +320,18 @@ editor_mode = function (editor) { if (!core.isset(editor_mode.info.id)) { // document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML = ''; document.getElementById('enemyItemTable').style.display = 'none'; + document.getElementById('tilesetsDiv').style.display = 'none'; document.getElementById('newIdIdnum').style.display = 'block'; return; } + if (editor_mode.info.isTile) { + document.getElementById('enemyItemTable').style.display = 'none'; + document.getElementById('tilesetsDiv').style.display = 'block'; + document.getElementById('newIdIdnum').style.display = 'none'; + return; + } document.getElementById('newIdIdnum').style.display = 'none'; + document.getElementById('tilesetsDiv').style.display = 'none'; document.getElementById('enemyItemTable').style.display = 'block'; var objs = []; diff --git a/_server/vm.js b/_server/vm.js index 3ff88ec0..afd49b90 100644 --- a/_server/vm.js +++ b/_server/vm.js @@ -95,10 +95,7 @@ var editArea = new Vue({ var num = mapArray[y][x]; if (num == 0) editor.map[y][x] = 0; - else if (num >= 1000) { - that.error = 3; - editor.map[y][x] = undefined; - } else if (typeof(editor.indexs[num][0]) == 'undefined') { + else if (typeof(editor.indexs[num][0]) == 'undefined') { that.error = 2; editor.map[y][x] = undefined; } else editor.map[y][x] = editor.ids[[editor.indexs[num][0]]]; diff --git a/editor-mobile.html b/editor-mobile.html index 540b256d..5aaa217f 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -92,6 +92,9 @@

图块属性  

+
+

tilesets不允许编辑图块属性

+
diff --git a/editor.html b/editor.html index f70dd9f0..e7b3b937 100644 --- a/editor.html +++ b/editor.html @@ -91,6 +91,9 @@

图块属性  

+
+

tilesets不允许编辑图块属性

+
From 8e6e301bae375bb56281a48679b6c7f84e8bca96 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Thu, 27 Sep 2018 00:05:49 +0800 Subject: [PATCH 07/10] editor-tilesets:check .[height/width] mod 32 --- _server/editor.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_server/editor.js b/_server/editor.js index 9b1bc7ab..937d5dd0 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -113,6 +113,9 @@ editor.prototype.idsInit = function (maps, icons) { var imgName = core.tilesets[i]; var img = core.material.images.tilesets[imgName]; var width = Math.floor(img.width/32), height = Math.floor(img.height/32); + if(img.width%32 || img.height%32){ + alert(imgName+'的长或宽不是32的整数倍, 请修改后刷新页面') + } for (var id=startOffset; id Date: Thu, 27 Sep 2018 09:41:45 +0800 Subject: [PATCH 08/10] clearStatus --- libs/control.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/libs/control.js b/libs/control.js index 6029ea0e..d27ce4d5 100644 --- a/libs/control.js +++ b/libs/control.js @@ -237,7 +237,6 @@ control.prototype.clearStatus = function() { } core.status = {}; core.clearStatusBar(); - core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); } ////// 重置游戏状态和初始数据 ////// @@ -249,16 +248,8 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value totalTime=core.status.hero.statistics.totalTime; } - // 停止各个Timeout和Interval - for (var i in core.timeout) { - clearTimeout(core.timeout[i]); - core.timeout[i] = null; - } - for (var i in core.interval) { - clearInterval(core.interval[i]); - core.interval[i] = null; - } - core.clearStatusBar(); + // 清除游戏数据 + core.clearStatus(); // 初始化status core.status = core.clone(core.initStatus); From 9941d126894222662d5b6008f8bc4ee1302fd96d Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 27 Sep 2018 10:53:10 +0800 Subject: [PATCH 09/10] Equipment Buff --- _server/data.comment.js | 18 ++++++++++++------ docs/element.md | 18 ++++++++++++++++++ libs/enemys.js | 23 +++++++++++++++++------ libs/items.js | 28 +++++++++++++++++++++------- libs/ui.js | 15 +++++++++++++-- project/data.js | 1 + project/functions.js | 19 ++++++++++++++++++- 7 files changed, 100 insertions(+), 22 deletions(-) diff --git a/_server/data.comment.js b/_server/data.comment.js index 3f5089d2..94a6fcbb 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -16,27 +16,27 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "images": { "_leaf": true, "_type": "textarea", - "_data": "在此存放所有可能使用的图片(tilesets除外) \n 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 \n 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 \n 依次向后添加" + "_data": "在此存放所有可能使用的图片(tilesets除外) \n图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 \n 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 \n 依次向后添加" }, "tilesets": { "_leaf": true, "_type": "textarea", - "_data": "在此存放额外素材的图片名, \n 可以自定导入任意张素材图片,无需PS,无需注册,即可直接在游戏中使用 \n 形式如[\"1.png\", \"2.png\"] ,将需要的素材图片放在images目录下 \n 素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)" + "_data": "在此存放额外素材的图片名, \n可以自定导入任意张素材图片,无需PS,无需注册,即可直接在游戏中使用 \n 形式如[\"1.png\", \"2.png\"] ,将需要的素材图片放在images目录下 \n 素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)" }, "animates": { "_leaf": true, "_type": "textarea", - "_data": "在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 \n 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 \n \"jianji\", \"thunder\" \n 根据需求自行添加" + "_data": "在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 \n动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 \n \"jianji\", \"thunder\" \n 根据需求自行添加" }, "bgms": { "_leaf": true, "_type": "textarea", - "_data": "在此存放所有的bgm,和文件名一致。第一项为默认播放项 \n 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好" + "_data": "在此存放所有的bgm,和文件名一致。第一项为默认播放项 \n音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好" }, "sounds": { "_leaf": true, "_type": "textarea", - "_data": "在此存放所有的SE,和文件名一致 \n 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好" + "_data": "在此存放所有的SE,和文件名一致 \n音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好" }, "startBackground": { "_leaf": true, @@ -445,7 +445,13 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "checkbox", "_bool": "bool", - "_data": "若此项为true则将状态栏中的楼层转换器按钮换为装备栏按钮" + "_data": "状态栏的装备按钮。若此项为true则将状态栏中的楼层转换器按钮换为装备栏按钮" + }, + "equipPercentage": { + "_leaf": true, + "_type": "checkbox", + "_bool": "bool", + "_data": "装备增加百分比属性。如果此项为true,则装备属性全部按照百分比进行计算,比如\"atk\": 20意味着攻击增加20%。\n如果多个装备百分比增加同一个属性的,按加算处理。(即一个10%一个20%总共是30%而不是32%)" }, /* "enableDeleteItem": { diff --git a/docs/element.md b/docs/element.md index beb5ea81..2a4d8444 100644 --- a/docs/element.md +++ b/docs/element.md @@ -67,6 +67,24 @@ animate为该装备的攻击动画,仅对type为0时有效。具体可参见[ {"type": 3, "atk": -20, "def": 50, "mdef": 50} // 装备类型是魔杖,效果是攻击-20,防御和魔防各+50 ``` +### 装备按比例增加属性 + +从V2.4.2开始,装备可以选择按照比例来增加属性。 + +在全塔属性中有个`equipPercentage`开关,如果将其打开,则会所有值都按照比例计算。(也就是类似Buff一样) + +例如,上面的例子就变成了: + +``` js +{"type": 0, "atk": 10} // 装备类型是武器,效果是攻击提升10%,使用默认的攻击动画 +{"type": 0, "atk": 40, "animate": "sword"} // 装备类型为武器,效果是攻击提升10%,攻击动画是sword +{"type": 1, "def": 40} // 装备类型是防具,效果是防御提升40% +{"type": 1, "def": 100, "mdef": 100} // 装备类型是防具,效果是防御和魔防各提升100% +{"type": 3, "atk": -20, "def": 50, "mdef": 50} // 装备类型是魔杖,效果是攻击下降20%,防御和魔防各提升50% +``` + +值得注意的是:多装备增加同一属性使用加法计算;也就是比如武器增加30%攻击,防具增加10%攻击,最终合起来增加的是40%而不是43%的属性。 + ### 检测是否存在装备 可以使用`core.hasEquip(itemId)`来检测是否装上某个装备。 diff --git a/libs/enemys.js b/libs/enemys.js index d7e0d5d0..c2f7d3ee 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -129,7 +129,7 @@ enemys.prototype.getExtraDamage = function (enemy) { enemys.prototype.nextCriticals = function (enemy, number) { if (typeof enemy == 'string') enemy = core.material.enemys[enemy]; - var useTurn = !core.flags.useLoop; // 是否使用回合法计算临界值;如果要用循环法,则直接改为false。 + var useTurn = !core.flags.useLoop; number = number||1; @@ -161,6 +161,10 @@ enemys.prototype.nextCriticals = function (enemy, number) { if (useTurn) { // 回合数计算法 for (var t = turn-1;t>=1;t--) { var nextAtk = Math.ceil(mon_hp/t) + mon_def; + // 装备提升比例的计算临界 + if (core.flags.equipPercentage) { + nextAtk = Math.ceil(nextAtk / core.getFlag('equip_atk_buff', 1)); + } if (nextAtk<=hero_atk) break; if (nextAtk!=pre) { var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, nextAtk, core.status.hero.def, core.status.hero.mdef); @@ -235,12 +239,19 @@ enemys.prototype.getCurrentEnemys = function (floorId) { var enemy = core.material.enemys[enemyId]; var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def; - if (this.hasSpecial(enemy.special, 10)) { - mon_atk=core.status.hero.atk; - mon_def=core.status.hero.def; + var hero_atk = core.status.hero.atk, hero_def = core.status.hero.def, hero_mdef = core.status.hero.mdef; + + if (core.flags.equipPercentage) { + hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk); + hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def); + hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef); } - if (this.hasSpecial(enemy.special, 3) && mon_def < core.status.hero.atk - 1) - mon_def = core.status.hero.atk - 1; + if (this.hasSpecial(enemy.special, 10)) { + mon_atk=hero_atk; + mon_def=hero_def; + } + if (this.hasSpecial(enemy.special, 3) && mon_def < hero_atk - 1) + mon_def = hero_atk - 1; var specialText = core.enemys.getSpecialText(enemyId); if (specialText.length>=3) specialText = "多属性..."; diff --git a/libs/items.js b/libs/items.js index 3d0fdef6..e177be96 100644 --- a/libs/items.js +++ b/libs/items.js @@ -175,10 +175,17 @@ items.prototype.loadEquip = function (equipId, callback) { // 比较能力值 var result = core.compareEquipment(equipId,unloadEquipId); - - core.status.hero.atk += result.atk; - core.status.hero.def += result.def; - core.status.hero.mdef += result.mdef; + + if (core.flags.equipPercentage) { + core.setFlag('equip_atk_buff', core.getFlag('equip_atk_buff',1)+result.atk/100); + core.setFlag('equip_def_buff', core.getFlag('equip_def_buff',1)+result.def/100); + core.setFlag('equip_mdef_buff', core.getFlag('equip_mdef_buff',1)+result.mdef/100); + } + else { + core.status.hero.atk += result.atk; + core.status.hero.def += result.def; + core.status.hero.mdef += result.mdef; + } // 更新装备状态 core.status.hero.equipment[loadEquipType] = equipId; @@ -214,9 +221,16 @@ items.prototype.unloadEquip = function (equipType, callback) { var unloadEquip = core.material.items[unloadEquipId]; // 处理能力值改变 - core.status.hero.atk -= unloadEquip.equip.atk || 0; - core.status.hero.def -= unloadEquip.equip.def || 0; - core.status.hero.mdef -= unloadEquip.equip.mdef || 0; + if (core.flags.equipPercentage) { + core.setFlag('equip_atk_buff', core.getFlag('equip_atk_buff',1)-(unloadEquip.equip.atk||0)/100); + core.setFlag('equip_def_buff', core.getFlag('equip_def_buff',1)-(unloadEquip.equip.def||0)/100); + core.setFlag('equip_mdef_buff', core.getFlag('equip_mdef_buff',1)-(unloadEquip.equip.mdef||0)/100); + } + else { + core.status.hero.atk -= unloadEquip.equip.atk || 0; + core.status.hero.def -= unloadEquip.equip.def || 0; + core.status.hero.mdef -= unloadEquip.equip.mdef || 0; + } // 更新装备状态 core.status.hero.equipment[equipType] = null; diff --git a/libs/ui.js b/libs/ui.js index eb6be6d8..afa4fb39 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -865,6 +865,12 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { var monster = core.material.enemys[monsterId]; var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def, mon_money=monster.money, mon_exp = monster.experience, mon_special=monster.special; + if (core.flags.equipPercentage) { + hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk); + hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def); + hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef); + } + var initDamage = 0; // 战前伤害 // 吸血 @@ -1849,10 +1855,15 @@ ui.prototype.drawEquipbox = function(index) { if (!core.isset(compare[name]) || compare[name]==0) return; var color = '#00FF00'; if (compare[name]<0) color = '#FF0000'; - var content = title + ' ' + core.getStatus(name) + '->'; + var nowValue = core.getStatus(name), newValue = nowValue + compare[name]; + if (core.flags.equipPercentage) { + var nowBuff = core.getFlag('equip_'+name+"_buff",1), newBuff = nowBuff+compare[name]/100; + nowValue = Math.floor(nowBuff*core.getStatus(name)); + newValue = Math.floor(newBuff*core.getStatus(name)); + } + var content = title + ' ' + nowValue + '->'; core.fillText('ui', content, drawOffset, 89, '#CCCCCC', 'bold 14px Verdana'); drawOffset += core.canvas.ui.measureText(content).width; - var newValue = core.getStatus(name) + compare[name] + ""; core.fillText('ui', newValue, drawOffset, 89, color); drawOffset += core.canvas.ui.measureText(newValue).width + 15; }) diff --git a/project/data.js b/project/data.js index 8b487b92..fb984999 100644 --- a/project/data.js +++ b/project/data.js @@ -203,6 +203,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "bigKeyIsBox": false, "equipment": false, "equipboxButton": false, + "equipPercentage": false, "enableAddPoint": false, "enableNegativeDamage": false, "hatredDecrease": true, diff --git a/project/functions.js b/project/functions.js index a108604c..da3e33f9 100644 --- a/project/functions.js +++ b/project/functions.js @@ -366,7 +366,17 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 怪物生命,怪物攻击、防御、特殊属性 var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def, mon_special = enemy.special; // 勇士的负属性都按0计算 - hero_hp=Math.max(0, hero_hp); hero_atk=Math.max(0, hero_atk); hero_def=Math.max(0, hero_def); hero_mdef=Math.max(0, hero_mdef); + hero_hp=Math.max(0, hero_hp); + hero_atk=Math.max(0, hero_atk); + hero_def=Math.max(0, hero_def); + hero_mdef=Math.max(0, hero_mdef); + + // 装备按比例增加属性 + if (core.flags.equipPercentage) { + hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk); + hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def); + hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef); + } // 如果是无敌属性,且勇士未持有十字架 if (this.hasSpecial(mon_special, 20) && !core.hasItem("cross")) @@ -495,6 +505,13 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.statusBar[item].innerHTML = core.formatBigNumber(core.getStatus(item)); }); + // 装备按比例增加属性 + if (core.flags.equipPercentage) { + core.statusBar.atk.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_atk_buff',1)*core.getStatus('atk'))); + core.statusBar.def.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_def_buff',1)*core.getStatus('def'))); + core.statusBar.mdef.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_mdef_buff',1)*core.getStatus('mdef'))); + } + // 可以在这里添加自己额外的状态栏信息,比如想攻击显示 +0.5 可以这么写: // if (core.hasFlag('halfAtk')) core.statusBar.atk.innerHTML += "+0.5"; From 1aef219f538801c47164b6a5c46f789943ab723f Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 27 Sep 2018 10:58:32 +0800 Subject: [PATCH 10/10] Equipment Buff --- docs/element.md | 4 +++- project/functions.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/element.md b/docs/element.md index 2a4d8444..a9e1dc78 100644 --- a/docs/element.md +++ b/docs/element.md @@ -77,12 +77,14 @@ animate为该装备的攻击动画,仅对type为0时有效。具体可参见[ ``` js {"type": 0, "atk": 10} // 装备类型是武器,效果是攻击提升10%,使用默认的攻击动画 -{"type": 0, "atk": 40, "animate": "sword"} // 装备类型为武器,效果是攻击提升10%,攻击动画是sword +{"type": 0, "atk": 40, "animate": "sword"} // 装备类型为武器,效果是攻击提升40%,攻击动画是sword {"type": 1, "def": 40} // 装备类型是防具,效果是防御提升40% {"type": 1, "def": 100, "mdef": 100} // 装备类型是防具,效果是防御和魔防各提升100% {"type": 3, "atk": -20, "def": 50, "mdef": 50} // 装备类型是魔杖,效果是攻击下降20%,防御和魔防各提升50% ``` +所有取值全部向下取整。 + 值得注意的是:多装备增加同一属性使用加法计算;也就是比如武器增加30%攻击,防具增加10%攻击,最终合起来增加的是40%而不是43%的属性。 ### 检测是否存在装备 diff --git a/project/functions.js b/project/functions.js index da3e33f9..de58713f 100644 --- a/project/functions.js +++ b/project/functions.js @@ -508,8 +508,8 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 装备按比例增加属性 if (core.flags.equipPercentage) { core.statusBar.atk.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_atk_buff',1)*core.getStatus('atk'))); - core.statusBar.def.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_def_buff',1)*core.getStatus('def'))); - core.statusBar.mdef.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_mdef_buff',1)*core.getStatus('mdef'))); + core.statusBar.def.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_def_buff',1)*core.getStatus('def'))); + core.statusBar.mdef.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_mdef_buff',1)*core.getStatus('mdef'))); } // 可以在这里添加自己额外的状态栏信息,比如想攻击显示 +0.5 可以这么写: