diff --git a/README.md b/README.md index 6844c8f5..055ec27a 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! * [x] 事件:更新怪物数据 * [x] 移动事件和跳跃事件增加“不消失”选项 * [x] 获胜结局可以指定“不计入榜单” +* [x] 贴图可自适应遮挡效果 +* [x] 默认不能走到将死的领域上 * [x] RM动画导出器可以指定压缩比率 * [x] 修改默认bgm * [x] 修复读档开启战斗动画等Bug diff --git a/_server/data.comment.js b/_server/data.comment.js index 74cd5fea..760450e8 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -62,6 +62,11 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_type": "textarea", "_data": "竖屏时下方道具栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。" }, + "borderColor": { + "_leaf": true, + "_type": "textarea", + "_data": "边框颜色,包括游戏边界的边框和对话框边框等。" + } } }, "firstData": { @@ -567,6 +572,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_bool": "bool", "_data": "经过楼梯、传送门时是否能“穿透”。\n穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件" }, + "canGoDeadZone": { + "_leaf": true, + "_type": "checkbox", + "_bool": "bool", + "_data": "是否允许走到将死的领域上。如果此项为true,则可以走到将死的领域上" + }, "enableMoveDirectly": { "_leaf": true, "_type": "checkbox", diff --git a/docs/personalization.md b/docs/personalization.md index 44ffd482..caa80a16 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -64,16 +64,23 @@ HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们 之后,我们可以在每层剧本的`"images"`里来定义该层的默认背景图片素材。 ``` js -"images": [[x,y,"bg.jpg",false]], // 背景图;你可以选择一张或多张图片来作为背景/前景素材。 +"images": [[3,5,"bg.jpg",0]], // 背景图;你可以选择一张或多张图片来作为背景/前景素材。 "images": [], // 无任何背景图 -"images": [[1,1,"house.png",false], [6,7,"bed.png",true]] // 在(1,1)放一个house.png在背景层,且(6,7)放bed.png在前景层 +"images": [[1,1,"house.png",0], [6,7,"bed.png",1]] // 在(1,1)放一个house.png在背景层,且(6,7)放bed.png在前景层 +"images": [[3,5,"tree.png",2]] // 如果写2,则会自动调节遮挡效果 ``` images为一个数组,代表当前层所有作为背景素材的图片信息。 -每一项为一个四元组,分别为该背景素材的x,y,图片名和是否为前景。其中x和y分别为横纵坐标,在0-12之间;图片名则必须在上面的images中定义过。 +每一项为一个四元组,分别为该背景素材的x,y,图片名和遮挡方式。其中x和y分别为横纵坐标,在0-12之间;图片名则必须在上面的images中定义过。 -如果第四项为true,则会在前景层(event2)上绘制,能覆盖勇士,常常用来作为柱子的上半部分等情况。 +第四项为遮挡方式,定义如下: + +- 0:该图片将全部画在背景层,被勇士所遮挡。举例:某些特殊地形等。 +- 1:该图片将全部画在前景层,可以遮挡勇士。举例:云彩等效果。 +- 2:该图片将上部分画在前景层,下部分画在背景层。从而可以达到一个“自动调节遮挡的效果”。举例:树、房子等等。 + +!> 如果写2的话,请确保图片高度是32的倍数! **如果你需要让某些点不可通行(比如你建了个房子,墙壁和家具等位置不让通行),则需在`events`中指定`{"noPass": false}`,参见[自定义事件](event#自定义事件)的写法。** diff --git a/libs/control.js b/libs/control.js index af6b00df..8352da57 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2658,8 +2658,10 @@ control.prototype.resize = function(clientWidth, clientHeight) { var shopDisplay; - statusBarBorder = '3px #fff solid'; - toolBarBorder = '3px #fff solid'; + var borderColor = main.borderColor||"white"; + + statusBarBorder = '3px '+borderColor+' solid'; + toolBarBorder = '3px '+borderColor+' solid'; var zoom = (ADAPT_WIDTH - width) / 4.22; var aScale = 1 - zoom / 100; @@ -2694,7 +2696,7 @@ control.prototype.resize = function(clientWidth, clientHeight) { // canvasLeft = 0; toolBarWidth = statusBarWidth = canvasWidth; statusBarHeight = tempTopBarH; - statusBarBorder = '3px #fff solid'; + statusBarBorder = '3px '+borderColor+' solid'; statusHeight = scale*BASE_LINEHEIGHT * .8; statusLabelsLH = .8 * BASE_LINEHEIGHT *scale; @@ -2703,11 +2705,11 @@ control.prototype.resize = function(clientWidth, clientHeight) { toolBarHeight = tempBotBarH; toolBarTop = statusBarHeight + canvasWidth; - toolBarBorder = '3px #fff solid'; + toolBarBorder = '3px '+borderColor+' solid'; toolsHeight = scale * BASE_LINEHEIGHT; toolsPMaxwidth = scale * DEFAULT_BAR_WIDTH * .4; toolsBackground = main.toolsBackground; - borderRight = '3px #fff solid'; + borderRight = '3px '+borderColor+' solid'; margin = scale * SPACE * 2; toolsMargin = scale * SPACE * 4; @@ -2722,14 +2724,14 @@ control.prototype.resize = function(clientWidth, clientHeight) { // canvasLeft = DEFAULT_BAR_WIDTH * scale; toolBarWidth = statusBarWidth = DEFAULT_BAR_WIDTH * scale; statusBarHeight = gameGroupHeight - SPACE; - statusBarBorder = '3px #fff solid'; + statusBarBorder = '3px '+borderColor+' solid'; statusBackground = main.statusLeftBackground; statusHeight = scale*statusLineHeight * .8; statusLabelsLH = .8 * statusLineHeight *scale; toolBarTop = scale*statusLineHeight * count + SPACE * 2; toolBarHeight = canvasWidth - toolBarTop; - toolBarBorder = '3px #fff solid'; + toolBarBorder = '3px '+borderColor+' solid'; toolsHeight = scale * BASE_LINEHEIGHT; toolsBackground = 'transparent'; fontSize = statusLineFontSize * scale; @@ -2792,7 +2794,7 @@ control.prototype.resize = function(clientWidth, clientHeight) { height: canvasWidth + unit, top: canvasTop + unit, right: 0, - border: '3px #fff solid', + border: '3px '+borderColor+' solid', } }, { diff --git a/libs/maps.js b/libs/maps.js index 04b3a3ae..dd943c40 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -238,7 +238,8 @@ maps.prototype.canMoveHero = function(x,y,direction,floorId) { 'down': {'x': 0, 'y': 1}, 'right': {'x': 1, 'y': 0} }; - var nextBlock = core.getBlock(x+scan[direction].x,y+scan[direction].y,floorId); + var nx = x+scan[direction].x, ny = y+scan[direction].y; + var nextBlock = core.getBlock(nx,ny); if (nextBlock!=null){ nextId = nextBlock.block.event.id; // 遇到单向箭头处理 @@ -250,6 +251,11 @@ maps.prototype.canMoveHero = function(x,y,direction,floorId) { } } } + + // 检查将死的领域 + if (core.status.hero.hp <= core.status.checkBlock.damage[13*nx+ny] && !core.flags.canGoDeadZone) + return false; + return true; } @@ -349,8 +355,14 @@ maps.prototype.drawMap = function (mapName, callback) { core.canvas.bg.drawImage(image, dx * ratio, dy * ratio, Math.min(size - dx * ratio, ratio * image.width), Math.min(size - dy * ratio, ratio * image.height)); } } - else + else if (t[3]==1) core.canvas.event2.drawImage(image, dx*ratio, dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height)); + else if (t[3]==2) { + core.canvas.event2.drawImage(image, 0, 0, image.width, image.height-32, + dx * ratio, dy * ratio, ratio * image.width, ratio * (image.height-32)); + core.canvas.bg.drawImage(image, 0, image.height-32, image.width, 32, + dx * ratio, (dy + image.height - 32) * ratio, ratio*image.width, 32*ratio); + } } }) diff --git a/libs/ui.js b/libs/ui.js index 5a28b569..d2bc5293 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -421,13 +421,16 @@ ui.prototype.drawTextBox = function(content) { // var left = 97, top = 64, right = 416 - 2 * left, bottom = 416 - 2 * top; //core.setAlpha('ui', 0.85); + + var borderColor = main.borderColor||"#FFFFFF"; + core.setAlpha('ui', textAttribute.background[3]); core.setFillStyle('ui', core.arrayToRGB(textAttribute.background)); - core.setStrokeStyle('ui', '#FFFFFF'); + core.setStrokeStyle('ui', borderColor); core.fillRect('ui', left, top, right, height); - core.strokeRect('ui', left - 1, top - 1, right + 1, height + 1, '#FFFFFF', 2); + core.strokeRect('ui', left - 1, top - 1, right + 1, height + 1, borderColor, 2); var xoffset = 9; @@ -475,7 +478,7 @@ ui.prototype.drawTextBox = function(content) { if (id == 'hero') { var heroHeight=core.material.icons.hero.height; - core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, heroHeight+2, null, 2); + core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, heroHeight+2, borderColor, 2); core.fillText('ui', name, content_left, top + 30, null, 'bold 22px Verdana'); core.clearMap('ui', left + 15, top + 40, 32, heroHeight); core.fillRect('ui', left + 15, top + 40, 32, heroHeight, background); @@ -486,7 +489,7 @@ ui.prototype.drawTextBox = function(content) { core.fillText('ui', name, content_left, top + 30, null, 'bold 22px Verdana'); if (core.isset(icon)) { - core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, iconHeight + 2, null, 2); + core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, iconHeight + 2, borderColor, 2); core.status.boxAnimateObjs = []; core.status.boxAnimateObjs.push({ 'bgx': left + 15, 'bgy': top + 40, 'bgWidth': 32, 'bgHeight': iconHeight, @@ -646,8 +649,10 @@ ui.prototype.drawChoices = function(content, choices) { } var top = bottom-height; + var borderColor = main.borderColor||"#FFFFFF"; + core.fillRect('ui', left, top, width, height, background); - core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, '#FFFFFF', 2); + core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2); // 如果有内容 if (core.isset(contents)) { @@ -739,10 +744,12 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { var top = 140 - (lines-1)*30; var right = 416 - 2 * left, bottom = 416 - 140 - top; + var borderColor = main.borderColor||"#FFFFFF"; + if (core.isPlaying()) core.fillRect('ui', left, top, right, bottom, background); if (core.isPlaying()) - core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); + core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, borderColor, 2); core.canvas.ui.textAlign = "center"; for (var i in contents) { core.fillText('ui', contents[i], 208, top + 50 + i*30, "#FFFFFF"); @@ -1725,10 +1732,14 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL images.forEach(function (t) { var ratio = size/416; var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2]; - if (core.isset(dx) && core.isset(dy) && !t[3] && core.isset(core.material.images.images[p])) { + if (core.isset(dx) && core.isset(dy) && core.isset(core.material.images.images[p])) { dx*=32; dy*=32; var image = core.material.images.images[p]; - core.canvas.ui.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height)); + if (!t[3]) + core.canvas.ui.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height)); + else if (t[3]==2) + core.canvas.ui.drawImage(image, 0, image.height-32, image.width, 32, + x+dx * ratio, y+(dy + image.height - 32) * ratio, ratio*image.width, 32*ratio); } }) @@ -1762,10 +1773,14 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL images.forEach(function (t) { var ratio = size/416; var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2]; - if (core.isset(dx) && core.isset(dy) && t[3] && core.isset(core.material.images.images[p])) { + if (core.isset(dx) && core.isset(dy) && core.isset(core.material.images.images[p])) { dx*=32; dy*=32; var image = core.material.images.images[p]; - core.canvas.ui.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height)); + if (t[3]==1) + core.canvas.ui.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height)); + else if (t[3]==2) + core.canvas.ui.drawImage(image, 0, 0, image.width, image.height-32, + x+dx * ratio, y+dy * ratio, ratio * image.width, ratio * (image.height-32)); } }) diff --git a/main.js b/main.js index 964ab271..154f2f20 100644 --- a/main.js +++ b/main.js @@ -10,7 +10,7 @@ function main() { // 如果要进行剧本的修改请务必将其改成false。 this.bgmRemote = false; // 是否采用远程BGM - this.bgmRemoteRoot = "https://gitee.com/ckcz123/h5music/raw/master/"; // 远程BGM的根目录 + this.bgmRemoteRoot = "https://h5mota.com/music/"; // 远程BGM的根目录 this.isCompetition = false; // 是否是比赛模式 diff --git a/project/data.js b/project/data.js index b8aadbe8..f01f9468 100644 --- a/project/data.js +++ b/project/data.js @@ -21,7 +21,8 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "levelChoose" : [["简单","Easy"],["普通","Normal"],["困难","Hard"],["噩梦","Hell"]], "statusLeftBackground": "url(project/images/ground.png) repeat", "statusTopBackground": "url(project/images/ground.png) repeat", - "toolsBackground": "url(project/images/ground.png) repeat" + "toolsBackground": "url(project/images/ground.png) repeat", + "borderColor": "white" }, "firstData" : { "title": "魔塔样板", @@ -164,6 +165,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "potionWhileRouting": false, "enableViewMaps": true, "portalWithoutTrigger": true, + "canGoDeadZone": false, "enableMoveDirectly": true, } } \ No newline at end of file diff --git a/更新说明.txt b/更新说明.txt index fc40123f..c491796f 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -5,6 +5,8 @@ 瞬间移动可以指定存在事件的点(如怪物、门、楼梯等) 事件:画面震动 事件:更新怪物数据 +贴图可自适应遮挡效果 +默认不能走到将死的领域上 移动事件和跳跃事件增加“不消失”选项 获胜结局可以指定“不计入榜单” RM动画导出器可以指定压缩比率