diff --git a/2.0diff.md b/2.0diff.md index 1652456b..0f9ad4eb 100644 --- a/2.0diff.md +++ b/2.0diff.md @@ -9,8 +9,11 @@ + 设置了三个模式`play|editor|replay`在`editor`模式关闭了部分动画,并且角色无法行动 重构editor ++ 重命名为`editor.html` + * 需要相应的修改本地服务的按钮打开的网址,为了兼容,临时加了个内容为``的`drawMapGUI.html` + 不再独立的导入数据和画图,尽可能的通过`main.init('editor')`复用代码 -+ 能够在本地服务器环境中直接修改`project`中的数据,目前只完成了文件操作的代码`editor_file.js`,前端尚未完成 ++ 能够在本地服务器环境中直接修改`project`中的数据,目前只完成了文件操作的代码`_server/editor_file.js`,前端尚未完成 ++ 把`editor`的代码拆到了`_server/editor.js`中 ## 具体: @@ -48,37 +51,39 @@ 提供了以下函数进行楼层`map`数组相关的操作 ```javascript editor.file.getFloorFileList -editor_file.loadFloorFile -editor_file.saveFloorFile -editor_file.saveFloorFileAs +editor.file.loadFloorFile +editor.file.saveFloorFile +editor.file.saveFloorFileAs ``` 5个编辑模式有关的查询 ```javascript -editor_file.editItem(editor,'redJewel',[],function(a){console.log(a)}); -editor_file.editEnemy(editor,'redBat',[],function(a){console.log(a)}); -editor_file.editLoc(editor,2,0,[],function(a){console.log(a)}); -editor_file.editFloor(editor,[],function(a){console.log(a)}); +editor.file.editItem(editor,'redJewel',[],function(a){console.log(a)}); +editor.file.editEnemy(editor,'redBat',[],function(a){console.log(a)}); +editor.file.editLoc(editor,2,0,[],function(a){console.log(a)}); +editor.file.editFloor(editor,[],function(a){console.log(a)}); editor.file.editTower(editor,[],function(a){console.log(a)}); ``` 5个编辑模式有关的编辑 ```javascript editor.info={images: "terrains", y: 9}; editor.file.changeIdAndIdnum(editor,'yellowWall2',16,editor.info,function(a){console.log(a)}); -editor_file.editItem(editor,'book',[["change","['items']['name']","怪物手册的新名字"]],function(a){console.log(a)}); -editor_file.editEnemy(editor,'redBat',[['change',"['atk']",20]],function(a){console.log(a)}); -editor_file.editLoc(editor,2,6,[["change","['afterBattle']",null]],function(a){console.log(a)}); -editor_file.editFloor(editor,[["change","['title']",'样板 33 层']],function(a){console.log(a)}); +editor.file.editItem(editor,'book',[["change","['items']['name']","怪物手册的新名字"]],function(a){console.log(a)}); +editor.file.editEnemy(editor,'redBat',[['change',"['atk']",20]],function(a){console.log(a)}); +editor.file.editLoc(editor,2,6,[["change","['afterBattle']",null]],function(a){console.log(a)}); +editor.file.editFloor(editor,[["change","['title']",'样板 33 层']],function(a){console.log(a)}); editor.file.editTower(editor,[["change","['values']['lavaDamage']",200]],function(a){console.log(a)}); ``` ### drawMapGUI.html +把`editor`的代码拆到了`_server/editor.js`中 + 以`display:none`的形式引入了`index.html`的`dom`,修改了原来的`.gameCanvas #ui #data`等的名字以避免冲突 通过`main.init('editor')`加载数据,移除了原有的`editor.loadjs`等 背景层如果未设置`editor.bgY`则通过运行时中的代码画背景 -`updateMap`中只画未定义快的报错,其他的由运行时中的代码完成 +`editor.updateMap`中只画未定义快的报错,其他的由运行时中的代码完成 `editor.ids[0] = 0; editor.indexs[0]=[0];` diff --git a/_server/editor.js b/_server/editor.js new file mode 100644 index 00000000..1190bb85 --- /dev/null +++ b/_server/editor.js @@ -0,0 +1,508 @@ +function editor() { + this.version = "1.2"; + this.material = {}; +} + +editor.prototype.init = function(callback){ + var afterCoreReset = function(){ + + main.editor.disableGlobalAnimate=false;//允许GlobalAnimate + /* core.setHeroMoveTriggerInterval(); */ + + editor.reset(function(){ + editor.drawMapBg(); + var mapArray = core.maps.getMapArray(core.status.maps, core.status.floorId); + editor.map = mapArray.map(function(v){return v.map(function(v){return editor.ids[[editor.indexs[v][0]]]})}); + editor.updateMap(); + editor.currentFloorId=core.status.floorId; + editor.currentFloorData = core.floors[core.status.floorId]; + + if (Boolean(callback))callback(); + }); + } + var afterMainInit = function(){ + editor.main=main; + editor.core=core; + editor.fs=fs; + editor.file=editor_file; + editor.material.images=core.material.images; + editor.listen(); // 开始监听事件 + var hard = 'Hard'; + core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, core.initStatus.maps); + //core.status.maps = core.clone(core.maps.initMaps(floorIds)); + core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { + afterCoreReset(); + }); + core.events.setInitData(hard); + } + setTimeout(afterMainInit, 300); +} + +editor.prototype.reset = function(callback){ + editor.idsInit(core.maps, core.icons.icons); // 初始化图片素材信息 + editor.drawInitData(core.icons.icons); // 初始化绘图 + if(Boolean(callback))callback(); +} + +editor.prototype.idsInit = function(maps, icons){ + editor.ids = [0]; + editor.indexs = []; + var MAX_NUM = 400; + var getInfoById = function(id){ + var block = maps.getBlock(0, 0, id); + if(hasOwnProp(block, 'event')){ + return block; + } + } + var point = 0; + for(var i=0; i edata.width) edata.style.width = (edata.width = fullWidth)/ratio + 'px'; + edata.style.height = (edata.height = fullHeight)/ratio + 'px'; + var dc = edata.getContext('2d'); + var nowx = 0; + var nowy = 0; + for(var ii=0; ii=0 && y >=0 && x<13 && y<13 && isAutotile(editor.map[y][x]) && editor.map[y][x].idnum == currId) + return 1; + else if(x<0 || y<0 || x>12 || y>12) return 1; //边界外视为通用autotile,这样好看些 + else + return 0; + } + var checkAround = function(x, y){ // 得到周围四个32*32块(周围每块都包含当前块的1/4,不清楚的话画下图你就明白)的数组索引 + var currId = editor.map[y][x].idnum; + var pointBlock = []; + for(var i=0; i<4; i++){ + var bsum = 0; + var offsetx = i%2, offsety = ~~(i/2); + for(var j=0; j<4; j++){ + var mx = j%2, my = ~~(j/2); + var b = getAutotileAroundId(currId, x+offsetx+mx-1, y+offsety+my-1); + bsum += b*(Math.pow(2, 3-j)); + } + pointBlock.push(bsum); + } + return pointBlock; + } + var addIndexToAutotileInfo = function(x, y){ + var indexArr = []; + var pointBlocks = checkAround(x, y); + for(var i=0; i<4; i++){ + var arr = indexArrs[pointBlocks[i]] + indexArr.push(arr[3-i]); + } + editor.map[y][x].blockIndex = indexArr; + } + var drawAutotile = function(ctx, x, y, info){ // 绘制一个autotile + ctx.clearRect(x*32, y*32, 32, 32); + //修正四个边角的固定搭配 + if(info.blockIndex[0] == 13){ + if(info.blockIndex[1] == 16) info.blockIndex[1] = 14; + if(info.blockIndex[2] == 31) info.blockIndex[2] = 19; + } + if(info.blockIndex[1] == 18){ + if(info.blockIndex[0] == 15) info.blockIndex[0] = 17; + if(info.blockIndex[3] == 36) info.blockIndex[3] = 24; + } + if(info.blockIndex[2] == 43){ + if(info.blockIndex[0] == 25) info.blockIndex[0] = 37; + if(info.blockIndex[3] == 46) info.blockIndex[3] = 44; + } + if(info.blockIndex[3] == 48){ + if(info.blockIndex[1] == 30) info.blockIndex[1] = 42; + if(info.blockIndex[2] == 45) info.blockIndex[2] = 47; + } + for(var i=0; i<4; i++){ + var index = info.blockIndex[i]; + var dx = x*32 + 16*(i%2), dy = y*32 + 16*(~~(i/2)); + drawBlockByIndex(ctx, dx, dy, editor.material.images[info.images][info.id], index); + } + } + */ + // 绘制地图 start + var eventCtx = document.getElementById('event').getContext("2d"); + for(var y=0; y<13; y++) + for(var x=0; x<13; x++){ + var tileInfo = editor.map[y][x]; + if(false && isAutotile(tileInfo)){ + addIndexToAutotileInfo(x, y); + drawAutotile(eventCtx, x, y, tileInfo); + }else drawTile(eventCtx, x, y, tileInfo); + } + // 绘制地图 end +} + +editor.prototype.changeFloor = function(floorId,callback) { + core.changeFloor(floorId, null, core.firstData.hero.loc, null, function(){ + editor.drawMapBg(); + var mapArray = core.maps.getMapArray(core.status.maps, core.status.floorId); + editor.map = mapArray.map(function(v){return v.map(function(v){return editor.ids[[editor.indexs[v][0]]]})}); + editor.updateMap(); + editor.currentFloorId=core.status.floorId; + editor.currentFloorData = core.floors[core.status.floorId]; + if (core.isset(callback))callback(); + }); +} + +editor.prototype.listen = function() { + + var uc = eui.getContext('2d'); + + function fillPos(pos) { + uc.fillStyle = '#' + ~~(Math.random() * 8) + ~~(Math.random() * 8) + ~~(Math.random() * 8); + uc.fillRect(pos.x * 32 + 12, pos.y * 32 + 12, 8, 8); + }//在格子内画一个随机色块 + + function eToLoc(e) { + editor.loc = { + 'x': document.documentElement.scrollLeft+e.clientX - mid.offsetLeft-mapEdit.offsetLeft, + 'y': document.documentElement.scrollTop+e.clientY - mid.offsetTop-mapEdit.offsetTop, + 'size': 32 + }; + return editor.loc; }//返回可用的组件内坐标 + + function locToPos(loc) { + editor.pos = { 'x': ~~(loc.x / loc.size), 'y': ~~(loc.y / loc.size) } + return editor.pos; + } + + var holdingPath = 0; + var stepPostfix = null;//用于存放寻路检测的第一个点之后的后续移动 + + var mouseOutCheck = 2; + function clear1() { + if (mouseOutCheck > 1) { + mouseOutCheck--; + setTimeout(clear1, 1000); + return; + } + holdingPath = 0; + stepPostfix = []; + uc.clearRect(0, 0, 416, 416); + }//用于鼠标移出canvas时的自动清除状态 + + eui.onmousedown = function (e) { + if(!selectBox.isSelected) { + tip.whichShow = 1; + return; + } + + holdingPath = 1; + mouseOutCheck = 2; + setTimeout(clear1); + e.stopPropagation(); + uc.clearRect(0, 0, 416, 416); + var loc = eToLoc(e); + var pos = locToPos(loc) + stepPostfix = []; + stepPostfix.push(pos); + fillPos(pos); + } + + eui.onmousemove = function (e) { + if(!selectBox.isSelected) { + // tip.whichShow = 1; + return; + } + + if (holdingPath == 0) { return; } + mouseOutCheck = 2; + e.stopPropagation(); + var loc = eToLoc(e); + var pos = locToPos(loc); + var pos0 = stepPostfix[stepPostfix.length - 1] + var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x] + var max = 0, index = 4; + for (var i = 0; i < 4; i++) { + if (directionDistance[i] > max) { + index = i; + max = directionDistance[i]; + } + } + var pos = [{ 'x': 0, 'y': 1 }, { 'x': -1, 'y': 0 }, { 'x': 0, 'y': -1 }, { 'x': 1, 'y': 0 }, false][index] + if (pos) { + pos.x += pos0.x; + pos.y += pos0.y; + stepPostfix.push(pos); + fillPos(pos); + } + } + + eui.onmouseup = function (e) { + if(!selectBox.isSelected) { + tip.whichShow = 1; + return; + } + holdingPath = 0; + e.stopPropagation(); + var loc = eToLoc(e); + if (stepPostfix.length) { + preMapData = JSON.parse(JSON.stringify(editor.map)); + currDrawData.pos = JSON.parse(JSON.stringify(stepPostfix)); + currDrawData.info = JSON.parse(JSON.stringify(editor.info)); + reDo = null; + // console.log(stepPostfix); + for (var ii = 0; ii < stepPostfix.length; ii++) + editor.map[stepPostfix[ii].y][stepPostfix[ii].x] = editor.info; + // console.log(editor.map); + editor.updateMap(); + holdingPath = 0; + stepPostfix = []; + uc.clearRect(0, 0, 416, 416); + } + } + + var preMapData = {}; + var currDrawData = { + pos: [], + info: {} + }; + var reDo = null; + document.body.onkeydown = function(e) { + // 禁止快捷键的默认行为 + if( e.ctrlKey && ( e.keyCode == 90 || e.keyCode == 89 ) ) + e.preventDefault(); + //Ctrl+z 撤销上一步undo + if(e.keyCode == 90 && e.ctrlKey && preMapData && currDrawData.pos.length){ + editor.map = JSON.parse(JSON.stringify(preMapData)); + editor.updateMap(); + reDo = JSON.parse(JSON.stringify(currDrawData)); + currDrawData = {pos: [],info: {}}; + preMapData = null; + } + //Ctrl+y 重做一步redo + if(e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length){ + preMapData = JSON.parse(JSON.stringify(editor.map)); + for(var j=0; j=editor.widthsX[spriter][1] && pos.x editor.widthsX[spriter][3]) + pos.y = ~~(editor.widthsX[spriter][3]/32)-4; + else{ + for(var i=0; i= 4*i && pos.y < 4*(i+1)){ + pos.images = imNames[i]; + pos.y = 4*i; + } + } + } + }else if((pos.y+1)*32 > editor.widthsX[spriter][3]) + pos.y = ~~(editor.widthsX[spriter][3]/32)-1; + + selectBox.isSelected = true; + // console.log(pos,editor.material.images[pos.images].height) + dataSelection.style.left = pos.x*32 +'px'; + dataSelection.style.top = pos.y*32 +'px'; + + if(pos.x==0&&pos.y==0){ + // editor.info={idnum:0, id:'empty','images':'清除块', 'y':0}; + editor.info=0; + }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 editor.info={'images':pos.images, 'y':pos.y}; + + for (var ii=0;ii - - - - - - -
-
-
-
-
-
- -

{{ errors[error-1] }}

-
-
- -
-
-
- -
-
- -
- -
-
-
-
-
- - - -
-
-
-
-

当前选择为清除块,可擦除地图上块

-
-

图块编号:{{ infos['idnum'] }}

-

图块ID:{{ infos['id'] }}

-

该图块无对应的数字或ID存在,请先前往icons.js和maps.js中进行定义!

-

图块所在素材:{{ infos['images'] + (isAutotile ? '( '+infos['id']+' )' : '') }}

-

图块索引:{{ infos['y'] }}

-
-
-
-

{{ mapMsg }}

-
-
- - - -
- 当前地板: - -
- - -
-
-
-
- -
- - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/editor.html b/editor.html new file mode 100644 index 00000000..3b0f15cf --- /dev/null +++ b/editor.html @@ -0,0 +1,227 @@ + + + + + + + +
+
+
+
+
+
+ +

{{ errors[error-1] }}

+
+
+ +
+
+
+ +
+
+ +
+ +
+
+
+
+
+ + + +
+
+
+
+

当前选择为清除块,可擦除地图上块

+
+

图块编号:{{ infos['idnum'] }}

+

图块ID:{{ infos['id'] }}

+

该图块无对应的数字或ID存在,请先前往icons.js和maps.js中进行定义!

+

图块所在素材:{{ infos['images'] + (isAutotile ? '( '+infos['id']+' )' : '') }}

+

图块索引:{{ infos['y'] }}

+
+
+
+

{{ mapMsg }}

+
+
+ + + +
+ 当前地板: + +
+ + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/libs/core.js b/libs/core.js index caf786d0..93926547 100644 --- a/libs/core.js +++ b/libs/core.js @@ -79,7 +79,6 @@ function core() { 'mouseOutCheck': 1, 'moveStepBeforeStop': [], - // 勇士状态;中心对称飞行器 // event事件 'saveIndex': null,