diff --git a/README.md b/README.md index 96af4734..13b94127 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,15 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 +### 2018.10.27 V2.4.4 + +* [x] tilesets可以设置图块属性(如可通行状态) +* [x] 追加素材时可以更改图片色调 +* [x] 防作弊手段的进一步加强:打开控制台则禁止上传成绩 +* [x] 图块属性增加“是否可被破震”的选项 +* [x] 模仿怪物内置模仿临界计算器 +* [x] 部分其他细节优化 + ### 2018.10.14 V2.4.3 * [x] 并行事件处理 diff --git a/_server/comment.js b/_server/comment.js index 85f7b315..6421f29e 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -228,14 +228,9 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = }, "canBreak": { "_leaf": true, - "_type": "select", - "_select": { - "values": [ - true, - false - ] - }, - "_data": "该图块是否可被破炸;true代表可以,false代表不可以" + "_type": "checkbox", + "_bool": "bool", + "_data": "该图块是否可被破墙或地震" } } }, diff --git a/_server/editor.js b/_server/editor.js index 1372d04f..e7cd0523 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -81,7 +81,12 @@ editor.prototype.init = function (callback) { editor.prototype.idsInit = function (maps, icons) { editor.ids = [0]; editor.indexs = []; - var MAX_NUM = Math.max.apply(null,Object.keys(maps_90f36752_8815_4be8_b32b_d7fad1d0542e)); + var MAX_NUM = 0; + var keys=Object.keys(maps_90f36752_8815_4be8_b32b_d7fad1d0542e); + for(var ii=0;iiMAX_NUM && v 0) { - actionList.forEach(function (value) { + var tempmap=[]; + for(var ii=0;ii=editor.core.icons.tilesetStartOffset && !isset(editor.core.maps.blocksInfo[idnum]) && tempmap.indexOf(idnum)===-1){ + actionList.splice(ii,0,["add","['" + idnum + "']",{"cls": "tileset", "id": "X"+idnum, "noPass": true}]); + tempmap.push(idnum); + ii++; + } value[1] = "['" + idnum + "']" + value[1]; - }); + } saveSetting('maps', actionList, function (err) { callback([ (function () { - var locObj = Object.assign({}, editor.core.maps.blocksInfo[idnum]); + var sourceobj=editor.core.maps.blocksInfo[idnum]; + if(!isset(sourceobj) && idnum>=editor.core.icons.tilesetStartOffset)sourceobj={"cls": "tileset", "id": "X"+idnum, "noPass": true} + var locObj = Object.assign({}, sourceobj); Object.keys(editor_file.comment._data.maps._data).forEach(function (v) { - if (!isset(editor.core.maps.blocksInfo[idnum][v])) + if (!isset(sourceobj[v])) locObj[v] = null; }); locObj.idnum = idnum; @@ -496,9 +506,11 @@ editor_file = function (editor, callback) { } else { callback([ (function () { - var locObj = Object.assign({}, editor.core.maps.blocksInfo[idnum]); + var sourceobj=editor.core.maps.blocksInfo[idnum]; + if(!isset(sourceobj) && idnum>=editor.core.icons.tilesetStartOffset)sourceobj={"cls": "tileset", "id": "X"+idnum, "noPass": true} + var locObj = Object.assign({}, sourceobj); Object.keys(editor_file.comment._data.maps._data).forEach(function (v) { - if (!isset(editor.core.maps.blocksInfo[idnum][v])) + if (!isset(sourceobj[v])) locObj[v] = null; }); locObj.idnum = idnum; diff --git a/_server/editor_mode.js b/_server/editor_mode.js index 1b0e71f2..0c231b0a 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -320,18 +320,11 @@ 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 = []; @@ -506,9 +499,18 @@ editor_mode = function (editor) { var appendPicCanvas = document.getElementById('appendPicCanvas'); var bg = appendPicCanvas.children[0]; var source = appendPicCanvas.children[1]; + var source_ctx=source.getContext('2d'); var picClick = appendPicCanvas.children[2]; var sprite = appendPicCanvas.children[3]; + var sprite_ctx=sprite.getContext('2d'); var appendPicSelection = document.getElementById('appendPicSelection'); + + [source_ctx,sprite_ctx].forEach(function(ctx){ + ctx.mozImageSmoothingEnabled = false; + ctx.webkitImageSmoothingEnabled = false; + ctx.msImageSmoothingEnabled = false; + ctx.imageSmoothingEnabled = false; + }) var selectAppend = document.getElementById('selectAppend'); var selectAppend_str = []; @@ -526,8 +528,8 @@ editor_mode = function (editor) { if (editor_mode.appendPic.img) { sprite.style.width = (sprite.width = editor_mode.appendPic.img.width) / ratio + 'px'; sprite.style.height = (sprite.height = editor_mode.appendPic.img.height) / ratio + 'px'; - sprite.getContext('2d').clearRect(0, 0, sprite.width, sprite.height); - sprite.getContext('2d').drawImage(editor_mode.appendPic.img, 0, 0); + sprite_ctx.clearRect(0, 0, sprite.width, sprite.height); + sprite_ctx.drawImage(editor_mode.appendPic.img, 0, 0); } return; } @@ -550,7 +552,7 @@ editor_mode = function (editor) { } sprite.style.width = (sprite.width = img.width) / ratio + 'px'; sprite.style.height = (sprite.height = img.height + ysize) / ratio + 'px'; - sprite.getContext('2d').drawImage(img, 0, 0); + sprite_ctx.drawImage(img, 0, 0); } selectAppend.onchange(); @@ -581,8 +583,8 @@ editor_mode = function (editor) { if (selectAppend.value == 'autotile') { sprite.style.width = (sprite.width = image.width) / ratio + 'px'; sprite.style.height = (sprite.height = image.height) / ratio + 'px'; - sprite.getContext('2d').clearRect(0, 0, sprite.width, sprite.height); - sprite.getContext('2d').drawImage(image, 0, 0); + sprite_ctx.clearRect(0, 0, sprite.width, sprite.height); + sprite_ctx.drawImage(image, 0, 0); } else { var ysize = selectAppend.value.indexOf('48') === -1 ? 32 : 48; @@ -608,7 +610,8 @@ editor_mode = function (editor) { } //把导入的图片画出 - source.getContext('2d').drawImage(image, 0, 0); + source_ctx.drawImage(image, 0, 0); + editor_mode.appendPic.sourceImageData=source_ctx.getImageData(0,0,image.width,image.height); //重置临时变量 selectAppend.onchange(); @@ -618,6 +621,151 @@ editor_mode = function (editor) { return; } + var changeColorInput=document.getElementById('changeColorInput') + changeColorInput.oninput=function(){ + var delta=(~~changeColorInput.value)*30; + var imgData=editor_mode.appendPic.sourceImageData; + var nimgData=new ImageData(imgData.width,imgData.height); + // ImageData .data 形如一维数组,依次排着每个点的 R(0~255) G(0~255) B(0~255) A(0~255) + var getPixel=function(imgData, x, y) { + var offset = (x + y * imgData.width) * 4; + var r = imgData.data[offset+0]; + var g = imgData.data[offset+1]; + var b = imgData.data[offset+2]; + var a = imgData.data[offset+3]; + return [r,g,b,a]; + } + var setPixel=function(imgData, x, y, rgba) { + var offset = (x + y * imgData.width) * 4; + imgData.data[offset+0]=rgba[0]; + imgData.data[offset+1]=rgba[1]; + imgData.data[offset+2]=rgba[2]; + imgData.data[offset+3]=rgba[3]; + } + var convert=function(rgba,delta){ + var round=Math.round; + // rgbToHsl hue2rgb hslToRgb from https://github.com/carloscabo/colz.git + //-------------------------------------------- + // The MIT License (MIT) + // + // Copyright (c) 2014 Carlos Cabo + // + // Permission is hereby granted, free of charge, to any person obtaining a copy + // of this software and associated documentation files (the "Software"), to deal + // in the Software without restriction, including without limitation the rights + // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + // copies of the Software, and to permit persons to whom the Software is + // furnished to do so, subject to the following conditions: + // + // The above copyright notice and this permission notice shall be included in all + // copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + // SOFTWARE. + //-------------------------------------------- + // https://github.com/carloscabo/colz/blob/master/public/js/colz.class.js + var rgbToHsl = function (rgba) { + var arg, r, g, b, h, s, l, d, max, min; + + arg = rgba; + + if (typeof arg[0] === 'number') { + r = arg[0]; + g = arg[1]; + b = arg[2]; + } else { + r = arg[0][0]; + g = arg[0][1]; + b = arg[0][2]; + } + + r /= 255; + g /= 255; + b /= 255; + + max = Math.max(r, g, b); + min = Math.min(r, g, b); + l = (max + min) / 2; + + if (max === min) { + h = s = 0; // achromatic + } else { + d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + + h /= 6; + } + + //CARLOS + h = round(h * 360); + s = round(s * 100); + l = round(l * 100); + + return [h, s, l]; + } + // + var hue2rgb = function (p, q, t) { + if (t < 0) { t += 1; } + if (t > 1) { t -= 1; } + if (t < 1 / 6) { return p + (q - p) * 6 * t; } + if (t < 1 / 2) { return q; } + if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; } + return p; + } + var hslToRgb = function (hsl) { + var arg, r, g, b, h, s, l, q, p; + + arg = hsl; + + if (typeof arg[0] === 'number') { + h = arg[0] / 360; + s = arg[1] / 100; + l = arg[2] / 100; + } else { + h = arg[0][0] / 360; + s = arg[0][1] / 100; + l = arg[0][2] / 100; + } + + if (s === 0) { + r = g = b = l; // achromatic + } else { + + q = l < 0.5 ? l * (1 + s) : l + s - l * s; + p = 2 * l - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + return [round(r * 255), round(g * 255), round(b * 255)]; + } + // + var hsl=rgbToHsl(rgba) + hsl[0]=(hsl[0]+delta)%360 + var nrgb=hslToRgb(hsl) + nrgb.push(rgba[3]) + return nrgb + } + for(var x=0; x 目前版本**v2.4.3**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.4**,上次更新时间:* {docsify-updated} * 目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。 diff --git a/docs/api.md b/docs/api.md index 6bc861dc..fa703397 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # 附录: API列表 -?> 目前版本**v2.4.3**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.4**,上次更新时间:* {docsify-updated} * **这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。** diff --git a/docs/element.md b/docs/element.md index 613e7e97..63e7ed59 100644 --- a/docs/element.md +++ b/docs/element.md @@ -1,6 +1,6 @@ # 元件说明 -?> 目前版本**v2.4.3**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.4**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 diff --git a/docs/event.md b/docs/event.md index 82075336..6c475c36 100644 --- a/docs/event.md +++ b/docs/event.md @@ -1,6 +1,6 @@ # 事件 -?> 目前版本**v2.4.3**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.4**,上次更新时间:* {docsify-updated} * 本章内将对样板所支持的事件进行介绍。 diff --git a/docs/index.md b/docs/index.md index c243a47d..3d12213c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # HTML5 魔塔样板说明文档 -?> 目前版本**v2.4.3**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.4**,上次更新时间:* {docsify-updated} * 众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 diff --git a/docs/personalization.md b/docs/personalization.md index 1065d8ab..30260cd3 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -1,6 +1,6 @@ # 个性化 -?> 目前版本**v2.4.3**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.4**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 diff --git a/docs/start.md b/docs/start.md index 7c82c6d7..ca8d110a 100644 --- a/docs/start.md +++ b/docs/start.md @@ -1,6 +1,6 @@ # 快速上手 -?> 目前版本**v2.4.3**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.4**,上次更新时间:* {docsify-updated} * 在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! diff --git a/editor-mobile.html b/editor-mobile.html index 469dfe63..38c0fb7f 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -56,6 +56,15 @@

+

+ 色相: + +

@@ -92,9 +101,6 @@

图块属性  

-
-

tilesets不允许编辑图块属性

-
diff --git a/editor.html b/editor.html index 4c098703..5b8600b0 100644 --- a/editor.html +++ b/editor.html @@ -55,6 +55,15 @@

+

+ 色相: + +

@@ -91,9 +100,6 @@

图块属性  

-
-

tilesets不允许编辑图块属性

-
diff --git a/main.js b/main.js index 5273c055..02a0a8f2 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "2.4.3"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "2.4.4"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 diff --git a/project/data.js b/project/data.js index 764b93f6..2a73e455 100644 --- a/project/data.js +++ b/project/data.js @@ -61,7 +61,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "firstData": { "title": "魔塔样板", "name": "template", - "version": "Ver 2.4.3", + "version": "Ver 2.4.4", "floorId": "sample0", "hero": { "name": "阳光", diff --git a/更新说明.txt b/更新说明.txt index f15483f9..1e1ad136 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,4 +1,15 @@ -HTML5魔塔样板V2.4.3 +HTML5魔塔样板V2.4.4 + +tilesets可以设置图块属性(如可通行状态) +追加素材时可以更改图片色调 +防作弊手段的进一步加强:打开控制台则禁止上传成绩 +图块属性增加“是否可被破震”的选项 +模仿怪物内置模仿临界计算器 +部分其他细节优化 + +----------------------------------------------------------------------- + +HTML5魔塔样板V2.4.3 并行事件处理 事件:设置楼层属性