diff --git a/README.md b/README.md
index 055ec27a..8f39f2c9 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,17 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
## 更新说明
+### 2018.8.28 V2.4
+
+* [x] 大地图的支持
+* [x] 同点多事件的颜色块绘制
+* [x] 录像播放时可以按PgUp/PgDn浏览地图
+* [x] 录像播放时对于瞬间移动绘制箭头
+* [x] 增加激光属性
+* [x] 可以在读档时E键直接指定编号
+* [x] 破炸飞可以在状态栏显示个数
+* [x] 部分细节优化,所有已知Bug修复
+
### 2018.7.21 V2.3.3
* [x] 将怪物特殊属性定义和伤害计算函数移动到脚本编辑中
diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4
index 3a19e2ac..917ed6e8 100644
--- a/_server/blockly/MotaAction.g4
+++ b/_server/blockly/MotaAction.g4
@@ -342,7 +342,7 @@ return code;
*/;
setValue_s
- : '变量设置' ':' '名称' idString_e '值' expression Newline
+ : '数值操作' ':' '名称' idString_e '值' expression Newline
/* setValue_s
@@ -1307,12 +1307,12 @@ IdString
;
FixedId_List
- : 'item:blueKey'|'status:hp'|'status:atk'|'status:def'|'item:yellowKey'
- ;
+ : '生命'|'攻击'|'防御'|'魔防'|'黄钥匙'|'蓝钥匙'|'红钥匙'|'金币'|'经验'
+ /*FixedId_List ['status:hp','status:atk','status:def','status:mdef','item:yellowKey','item:blueKey','item:redKey','status:money','status:experience']*/;
Id_List
- : 'flag' | 'status' | 'item'
- ;
+ : '变量' | '状态' | '物品'
+ /*Id_List ['flag','status','item']*/;
//转blockly后不保留需要加"
EvalString
diff --git a/_server/comment.js b/_server/comment.js
index 982424a4..42422d46 100644
--- a/_server/comment.js
+++ b/_server/comment.js
@@ -245,6 +245,18 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_type": "textarea",
"_data": "显示在状态栏中的层数"
},
+ "width": {
+ "_leaf": true,
+ "_type": "textarea",
+ "_range": "false",
+ "_data": "地图x方向大小,这里不能更改,仅能在新建地图时设置,null视为13"
+ },
+ "height": {
+ "_leaf": true,
+ "_type": "textarea",
+ "_range": "false",
+ "_data": "地图y方向大小,这里不能更改,仅能在新建地图时设置,null视为13"
+ },
"canFlyTo": {
"_leaf": true,
"_type": "checkbox",
diff --git a/_server/css/editor.css b/_server/css/editor.css
index f5681118..928a0964 100644
--- a/_server/css/editor.css
+++ b/_server/css/editor.css
@@ -89,6 +89,10 @@ body {
height: 630px;
}
+#mapEdit {
+ overflow: hidden;
+}
+
.map {
position: absolute;
left: 20px;
diff --git a/_server/css/editor_mobile.css b/_server/css/editor_mobile.css
index d5eed943..36ca92ae 100644
--- a/_server/css/editor_mobile.css
+++ b/_server/css/editor_mobile.css
@@ -82,6 +82,10 @@ body {
position: absolute;
}
+#mapEdit {
+ overflow: hidden;
+}
+
.map {
position: absolute;
left: 4vw;
diff --git a/_server/data.comment.js b/_server/data.comment.js
index 760450e8..acfae9fc 100644
--- a/_server/data.comment.js
+++ b/_server/data.comment.js
@@ -426,6 +426,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool",
"_data": "是否在状态栏显示三色钥匙数量"
},
+ "enablePZF": {
+ "_leaf": true,
+ "_type": "checkbox",
+ "_bool": "bool",
+ "_data": "是否在状态栏显示破炸飞数量"
+ },
"enableDebuff": {
"_leaf": true,
"_type": "checkbox",
diff --git a/_server/editor.js b/_server/editor.js
index b76134b0..612df88f 100644
--- a/_server/editor.js
+++ b/_server/editor.js
@@ -18,9 +18,10 @@ editor.prototype.init = function (callback) {
return editor.ids[[editor.indexs[parseInt(v)][0]]]
})
});
- editor.updateMap();
editor.currentFloorId = core.status.floorId;
editor.currentFloorData = core.floors[core.status.floorId];
+ editor.updateMap();
+ editor.buildMark();
editor.drawEventBlock();
if (Boolean(callback)) callback();
});
@@ -159,12 +160,13 @@ editor.prototype.drawInitData = function (icons) {
}
editor.prototype.mapInit = function () {
var ec = document.getElementById('event').getContext('2d');
- ec.clearRect(0, 0, 416, 416);
- document.getElementById('event2').getContext('2d').clearRect(0, 0, 416, 416);
+ ec.clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
+ document.getElementById('event2').getContext('2d').clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
editor.map = [];
- for (var y = 0; y < 13; y++) {
+ var sy=editor.currentFloorData.map.length,sx=editor.currentFloorData.map[0].length;
+ for (var y = 0; y < sy; y++) {
editor.map[y] = [];
- for (var x = 0; x < 13; x++) {
+ for (var x = 0; x < sx; x++) {
editor.map[y][x] = 0;
}
}
@@ -200,23 +202,23 @@ editor.prototype.drawEventBlock = function () {
fg.clearRect(0, 0, 416, 416);
for (var i=0;i<13;i++) {
for (var j=0;j<13;j++) {
- var color=null;
- var loc=i+","+j;
+ var color=[];
+ var loc=(i+core.bigmap.offsetX/32)+","+(j+core.bigmap.offsetY/32);
if (core.isset(editor.currentFloorData.events[loc]))
- color = '#FF0000';
- else if (core.isset(editor.currentFloorData.changeFloor[loc]))
- color = '#00FF00';
- else if (core.isset(editor.currentFloorData.afterBattle[loc]))
- color = '#FFFF00';
- else if (core.isset(editor.currentFloorData.afterGetItem[loc]))
- color = '#00FFFF';
- else if (core.isset(editor.currentFloorData.afterOpenDoor[loc]))
- color = '#FF00FF';
- else if (core.isset(editor.currentFloorData.cannotMove[loc]))
- color = '#0000FF';
- if (color!=null) {
- fg.fillStyle = color;
- fg.fillRect(32*i, 32*j+32-8, 8, 8);
+ color.push('#FF0000');
+ if (core.isset(editor.currentFloorData.changeFloor[loc]))
+ color.push('#00FF00');
+ if (core.isset(editor.currentFloorData.afterBattle[loc]))
+ color.push('#FFFF00');
+ if (core.isset(editor.currentFloorData.afterGetItem[loc]))
+ color.push('#00FFFF');
+ if (core.isset(editor.currentFloorData.afterOpenDoor[loc]))
+ color.push('#FF00FF');
+ if (core.isset(editor.currentFloorData.cannotMove[loc]))
+ color.push('#0000FF');
+ for(var kk=0,cc;cc=color[kk];kk++){
+ fg.fillStyle = cc;
+ fg.fillRect(32*i+8*kk, 32*j+32-8, 8, 8);
}
}
}
@@ -227,7 +229,7 @@ editor.prototype.updateMap = function () {
return v.map(function (v) {
return v.idnum || v || 0
})
- }), {'events': {}, 'changeFloor': {}});
+ }), {'events': {}, 'changeFloor': {}}, editor.currentFloorId);
core.status.thisMap.blocks = blocks;
main.editor.updateMap();
@@ -252,96 +254,10 @@ editor.prototype.updateMap = function () {
}
//ctx.drawImage(editor.material.images[tileInfo.images], 0, tileInfo.y*32, 32, 32, x*32, y*32, 32, 32);
}
- /*
- // autotile的相关处理
- var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块
- // +----+----+----+----+----+----+
- [10, 9, 4, 3 ], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
- [10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+
- [10, 9, 18, 3 ], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 |
- [10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+
- [10, 43, 4, 3 ], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 |
- [10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+
- [10, 7, 2, 3 ], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 |
- [10, 31, 16, 5 ], //7 bin:0111 +----+----+----+----+----+----+
- [48, 9, 4, 3 ], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 |
- [ 8, 9, 4, 1 ], //9 bin:1001 +----+----+----+----+----+----+
- [36, 9, 30, 3 ], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 |
- [36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+
- [46, 45, 4, 3 ], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 |
- [46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+
- [12, 45, 30, 3 ], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 |
- [34, 33, 28, 27] //15 bin:1111 +----+----+----+----+----+----+
- ];
- var drawBlockByIndex = function(ctx, dx, dy, autotileImg, index){ //index为autotile的图块索引1-48
- var sx = 16*((index-1)%6), sy = 16*(~~((index-1)/6));
- ctx.drawImage(autotileImg, sx, sy, 16, 16, dx, dy, 16, 16);
- }
- var isAutotile = function(info){
- if(typeof(info)=='object' && hasOwnProp(info, 'images') && info.images=='autotile') return true;
- return false;
- }
- var getAutotileAroundId = function(currId, x, y){ //与autotile当前idnum一致返回1,否则返回0
- if(x>=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++) {
+ for (var y = 0; y < editor.map.length; y++)
+ for (var x = 0; x < editor.map[0].length; x++) {
var tileInfo = editor.map[y][x];
if (false && isAutotile(tileInfo)) {
addIndexToAutotileInfo(x, y);
@@ -352,6 +268,64 @@ editor.prototype.updateMap = function () {
}
+editor.prototype.buildMark = function(){
+ // 生成定位编号
+ var arrColMark=document.getElementById('arrColMark');
+ var arrRowMark=document.getElementById('arrRowMark');
+ var mapColMark=document.getElementById('mapColMark');
+ var mapRowMark=document.getElementById('mapRowMark');
+ var buildMark = function (offsetX,offsetY) {
+ var colNum = ' ';
+ for (var i = 0; i < 13; i++) {
+ var tpl = '
' + (i+offsetX) + ' | ';
+ colNum += tpl;
+ }
+ arrColMark.innerHTML = '' + colNum + '
';
+ mapColMark.innerHTML = '' + colNum + '
';
+ var rowNum = ' ';
+ for (var i = 0; i < 13; i++) {
+ var tpl = '| ' + (i+offsetY) + ' |
';
+ rowNum += tpl;
+ }
+ arrRowMark.innerHTML = rowNum;
+ mapRowMark.innerHTML = rowNum;
+ }
+ var buildMark_mobile = function (offsetX,offsetY) {
+ var colNum = ' ';
+ for (var i = 0; i < 13; i++) {
+ var tpl = '' + (' '+i).slice(-2).replace(' ',' ') + ' | ';
+ colNum += tpl;
+ }
+ arrColMark.innerHTML = '' + colNum + '
';
+ //mapColMark.innerHTML = '' + colNum + '
';
+ var rowNum = ' ';
+ for (var i = 0; i < 13; i++) {
+ var tpl = '| ' + (' '+i).slice(-2).replace(' ',' ') + ' |
';
+ rowNum += tpl;
+ }
+ arrRowMark.innerHTML = rowNum;
+ //mapRowMark.innerHTML = rowNum;
+ //=====
+ var colNum = ' ';
+ for (var i = 0; i < 13; i++) {
+ var tpl = '' + (' '+(i+offsetX)).slice(-2).replace(' ',' ') + '
';
+ colNum += tpl;
+ }
+ mapColMark.innerHTML = '' + colNum + '
';
+ var rowNum = ' ';
+ for (var i = 0; i < 13; i++) {
+ var tpl = '' + (' '+(i+offsetY)).slice(-2).replace(' ',' ') + '
';
+ rowNum += tpl;
+ }
+ mapRowMark.innerHTML = rowNum;
+ }
+ if(editor.isMobile){
+ buildMark_mobile(core.bigmap.offsetX/32,core.bigmap.offsetY/32);
+ } else {
+ buildMark(core.bigmap.offsetX/32,core.bigmap.offsetY/32);
+ }
+}
+
editor.prototype.changeFloor = function (floorId, callback) {
editor.currentFloorData.map = editor.map.map(function (v) {
return v.map(function (v) {
@@ -366,9 +340,9 @@ editor.prototype.changeFloor = function (floorId, callback) {
return editor.ids[[editor.indexs[parseInt(v)][0]]]
})
});
- editor.updateMap();
editor.currentFloorId = core.status.floorId;
editor.currentFloorData = core.floors[core.status.floorId];
+ editor.updateMap();
editor_mode.floor();
editor.drawEventBlock();
if (core.isset(callback)) callback();
@@ -394,7 +368,7 @@ editor.prototype.listen = function () {
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);
+ uc.fillRect(pos.x * 32 + 12 - core.bigmap.offsetX, pos.y * 32 + 12 - core.bigmap.offsetY, 8, 8);
}//在格子内画一个随机色块
function eToLoc(e) {
@@ -410,8 +384,13 @@ editor.prototype.listen = function () {
return editor.loc;
}//返回可用的组件内坐标
- function locToPos(loc) {
- editor.pos = {'x': ~~(loc.x / loc.size), 'y': ~~(loc.y / loc.size)}
+ function locToPos(loc, addViewportOffset) {
+ var offsetX=0, offsetY=0;
+ if (addViewportOffset){
+ offsetX=core.bigmap.offsetX/32;
+ offsetY=core.bigmap.offsetY/32;
+ }
+ editor.pos = {'x': ~~(loc.x / loc.size)+offsetX, 'y': ~~(loc.y / loc.size)+offsetY}
return editor.pos;
}
@@ -436,13 +415,13 @@ editor.prototype.listen = function () {
eui.onmousedown = function (e) {
if (e.button==2){
var loc = eToLoc(e);
- var pos = locToPos(loc);
+ var pos = locToPos(loc,true);
editor.showMidMenu(e.clientX,e.clientY);
return;
}
if (!selectBox.isSelected) {
var loc = eToLoc(e);
- var pos = locToPos(loc);
+ var pos = locToPos(loc,true);
editor_mode.onmode('nextChange');
editor_mode.onmode('loc');
//editor_mode.loc();
@@ -458,7 +437,7 @@ editor.prototype.listen = function () {
e.stopPropagation();
uc.clearRect(0, 0, 416, 416);
var loc = eToLoc(e);
- var pos = locToPos(loc);
+ var pos = locToPos(loc,true);
stepPostfix = [];
stepPostfix.push(pos);
fillPos(pos);
@@ -476,7 +455,7 @@ editor.prototype.listen = function () {
mouseOutCheck = 2;
e.stopPropagation();
var loc = eToLoc(e);
- var pos = locToPos(loc);
+ var pos = locToPos(loc,true);
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;
@@ -532,6 +511,24 @@ editor.prototype.listen = function () {
}
}
+ /*
+ document.getElementById('mid').onkeydown = function (e) {
+ console.log(e);
+ if (e.keyCode==37) {
+ editor.moveViewport(-1, 0);
+ }
+ if (e.keyCode==38) {
+ editor.moveViewport(0, -1);
+ }
+ if (e.keyCode==39) {
+ editor.moveViewport(1, 0);
+ }
+ if (e.keyCode==40) {
+ editor.moveViewport(0, 1);
+ }
+ }
+ */
+
document.getElementById('mid').onmousewheel = function (e) {
e.preventDefault();
var wheel = function (direct) {
@@ -864,6 +861,24 @@ editor.prototype.listen = function () {
editor.brushMod=brushMod2.value;
}
+
+ editor.moveViewport=function(x,y){
+ core.bigmap.offsetX = core.clamp(core.bigmap.offsetX+32*x, 0, 32*core.bigmap.width-416);
+ core.bigmap.offsetY = core.clamp(core.bigmap.offsetY+32*y, 0, 32*core.bigmap.height-416);
+ core.control.updateViewport();
+ editor.buildMark();
+ editor.drawEventBlock();
+ }
+
+ var viewportButtons=document.getElementById('viewportButtons');
+ for(var ii=0,node;node=viewportButtons.children[ii];ii++){
+ (function(x,y){
+ node.onclick=function(){
+ editor.moveViewport(x,y);
+ }
+ })([-1,0,0,1][ii],[0,-1,1,0][ii]);
+ }
+
}//绑定事件
/*
diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js
index b35decf8..12805b87 100644
--- a/_server/editor_blockly.js
+++ b/_server/editor_blockly.js
@@ -53,8 +53,7 @@ editor_blockly = function () {
MotaActionBlocks['afterOpenDoor_m'].xmlText(),
MotaActionBlocks['firstArrive_m'].xmlText(),
],
- '语句块':[
- '',
+ '显示文字':[
MotaActionBlocks['text_0_s'].xmlText(),
MotaActionBlocks['text_1_s'].xmlText(),
MotaActionFunctions.actionParser.parseList({"type": "choices", "text": "是否跳过剧情", "choices": [
@@ -83,8 +82,11 @@ editor_blockly = function () {
])
])
]),
- '',
- MotaActionBlocks['setValue_s'].xmlText(),
+ ],
+ '数据相关':[
+ MotaActionBlocks['setValue_s'].xmlText([
+ MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
+ ]),
MotaActionBlocks['input_s'].xmlText(),
MotaActionBlocks['update_s'].xmlText(),
MotaActionBlocks['updateEnemys_s'].xmlText(),
@@ -100,7 +102,8 @@ editor_blockly = function () {
MotaActionBlocks['setHeroIcon_s'].xmlText(),
MotaActionBlocks['follow_s'].xmlText(),
MotaActionBlocks['unfollow_s'].xmlText(),
- '',
+ ],
+ '事件控制':[
MotaActionBlocks['if_s'].xmlText(),
MotaActionBlocks['while_s'].xmlText(),
MotaActionBlocks['break_s'].xmlText(),
@@ -113,7 +116,8 @@ editor_blockly = function () {
MotaActionBlocks['move_s'].xmlText(),
MotaActionBlocks['jump_s'].xmlText(),
MotaActionBlocks['disableShop_s'].xmlText(),
- '',
+ ],
+ '特效/声音':[
MotaActionBlocks['sleep_s'].xmlText(),
MotaActionBlocks['wait_s'].xmlText(),
MotaActionBlocks['viberate_s'].xmlText(),
@@ -126,11 +130,14 @@ editor_blockly = function () {
MotaActionBlocks['resumeBgm_s'].xmlText(),
MotaActionBlocks['playSound_s'].xmlText(),
MotaActionBlocks['setVolume_s'].xmlText(),
- '',
+ ],
+ '原生脚本':[
MotaActionBlocks['function_s'].xmlText(),
],
'值块':[
- MotaActionBlocks['setValue_s'].xmlText(),
+ MotaActionBlocks['setValue_s'].xmlText([
+ MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
+ ]),
MotaActionBlocks['expression_arithmetic_0'].xmlText(),
MotaActionBlocks['negate_e'].xmlText(),
MotaActionBlocks['bool_e'].xmlText(),
diff --git a/_server/editor_file.js b/_server/editor_file.js
index 82247ee0..4f534d2a 100644
--- a/_server/editor_file.js
+++ b/_server/editor_file.js
@@ -83,12 +83,21 @@ editor_file = function (editor, callback) {
} */
var filename = 'project/floors/' + editor.currentFloorId + '.js';
var datastr = ['main.floors.', editor.currentFloorId, '=\n{'];
- if (editor.currentFloorData.map == 'new')
+ if (editor.currentFloorData.map == 'new') {
+ /*
editor.currentFloorData.map = editor.map.map(function (v) {
return v.map(function () {
return 0
})
});
+ */
+ var width = parseInt(document.getElementById('newMapWidth').value);
+ var height = parseInt(document.getElementById('newMapHeight').value);
+ var row = [];
+ for (var i=0;i1000) {
+ printe("新建地图的宽高都不得小于13,且宽高之积不能超过1000");
+ return;
+ }
editor_mode.onmode('');
editor.file.saveNewFile(newFileName.value, function (err) {
diff --git a/_server/vm.js b/_server/vm.js
index 312507fa..f37956c5 100644
--- a/_server/vm.js
+++ b/_server/vm.js
@@ -24,7 +24,14 @@ document.body.onmousedown = function (e) {
}
});
- if (clickpath.indexOf('edit') === -1 && clickpath.indexOf('tip') === -1 && clickpath.indexOf('brushMod') === -1 && clickpath.indexOf('brushMod2') === -1) {
+ var unselect=true;
+ for(var ii=0,thisId;thisId=['edit','tip','brushMod','brushMod2','viewportButtons'][ii];ii++){
+ if (clickpath.indexOf(thisId) !== -1){
+ unselect=false;
+ break;
+ }
+ }
+ if (unselect) {
if (clickpath.indexOf('eui') === -1) {
if (selectBox.isSelected) {
editor_mode.onmode('');
@@ -60,11 +67,12 @@ var exportMap = new Vue({
methods: {
exportMap: function () {
editor.updateMap();
+ var sx=editor.map.length-1,sy=editor.map[0].length-1;
var filestr = '';
- for (var yy = 0; yy < 13; yy++) {
+ for (var yy = 0; yy <= sy; yy++) {
filestr += '['
- for (var xx = 0; xx < 13; xx++) {
+ for (var xx = 0; xx <= sx; xx++) {
var mapxy = editor.map[yy][xx];
if (typeof(mapxy) == typeof({})) {
if ('idnum' in mapxy) mapxy = mapxy.idnum;
@@ -79,10 +87,10 @@ var exportMap = new Vue({
}
mapxy = String(mapxy);
mapxy = Array(Math.max(4 - mapxy.length, 0)).join(' ') + mapxy;
- filestr += mapxy + (xx == 12 ? '' : ',')
+ filestr += mapxy + (xx == sx ? '' : ',')
}
- filestr += ']' + (yy == 12 ? '' : ',\n');
+ filestr += ']' + (yy == sy ? '' : ',\n');
}
pout.value = filestr;
editArea.mapArr = filestr;
@@ -97,7 +105,7 @@ var editArea = new Vue({
data: {
mapArr: '',
errors: [ // 编号1,2,3,4
- "格式错误!请使用正确格式(13*13数组,如不清楚,可先点击生成地图查看正确格式)",
+ "格式错误!请使用正确格式(请使用地图生成器进行生成,且需要和本地图宽高完全一致)",
"当前有未定义ID(在地图区域显示红块),请修改ID或者到icons.js和maps.js中进行定义!",
"ID越界(在地图区域显示红块),当前编辑器暂时支持编号小于400,请修改编号!",
// "发生错误!",
@@ -130,6 +138,8 @@ var editArea = new Vue({
},
error: function () {
// console.log(editArea.mapArr);
+ if (this.error>0)
+ printe(this.errors[this.error-1])
}
},
methods: {
@@ -138,8 +148,9 @@ var editArea = new Vue({
// var mapArray = that.mapArr.split(/\D+/).join(' ').trim().split(' ');
var mapArray = JSON.parse('[' + that.mapArr + ']');
- for (var y = 0; y < 13; y++)
- for (var x = 0; x < 13; x++) {
+ var sy=editor.map.length,sx=editor.map[0].length;
+ for (var y = 0; y < sy; y++)
+ for (var x = 0; x < sx; x++) {
var num = mapArray[y][x];
if (num == 0)
editor.map[y][x] = 0;
@@ -159,25 +170,26 @@ var editArea = new Vue({
var formatArrStr = '';
var that = this;
clearTimeout(that.formatTimer);
- if (this.mapArr.split(/\D+/).join(' ').trim().split(' ').length != 169) return false;
+ var si=editor.map.length,sk=editor.map[0].length;
+ if (this.mapArr.split(/\D+/).join(' ').trim().split(' ').length != si*sk) return false;
var arr = this.mapArr.replace(/\s+/g, '').split('],[');
- if (arr.length != 13) return;
- for (var i = 0; i < 13; i++) {
+ if (arr.length != si) return;
+ for (var i = 0; i < si; i++) {
var a = [];
formatArrStr += '[';
- if (i == 0 || i == 12) a = arr[i].split(/\D+/).join(' ').trim().split(' ');
+ if (i == 0 || i == si-1) a = arr[i].split(/\D+/).join(' ').trim().split(' ');
else a = arr[i].split(/\D+/);
- if (a.length != 13) {
+ if (a.length != sk) {
formatArrStr = '';
return;
}
- for (var k = 0; k < 13; k++) {
+ for (var k = 0; k < sk; k++) {
var num = parseInt(a[k]);
- formatArrStr += Array(Math.max(4 - String(num).length, 0)).join(' ') + num + (k == 12 ? '' : ',');
+ formatArrStr += Array(Math.max(4 - String(num).length, 0)).join(' ') + num + (k == sk-1 ? '' : ',');
}
- formatArrStr += ']' + (i == 12 ? '' : ',\n');
+ formatArrStr += ']' + (i == si-1 ? '' : ',\n');
}
return formatArrStr;
}
@@ -199,7 +211,8 @@ var copyMap = new Vue({
return;
}
try {
- pout.select();
+ pout.focus();
+ pout.setSelectionRange(0, pout.value.length);
document.execCommand("Copy");
tip.whichShow = 6;
} catch (e) {
diff --git a/docs/V2.0.md b/docs/V2.0.md
index 558eb1d1..2c87474d 100644
--- a/docs/V2.0.md
+++ b/docs/V2.0.md
@@ -1,6 +1,6 @@
# V2.0版本介绍
-?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
+?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} *
目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。
diff --git a/docs/api.md b/docs/api.md
index 50319569..1da8bef5 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -1,6 +1,6 @@
# 附录: API列表
-?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
+?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} *
**这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。**
@@ -184,22 +184,29 @@ core.enemyExists(x, y, id, floorId)
x和y为坐标;id为怪物ID,可为null表示任意怪物;floorId为楼层ID,可忽略表示当前楼层。
-core.getBlock(x, y, floorId, needEnable)
+core.getBlock(x, y, floorId, showDisable)
获得某个点的当前图块信息。
x和y为坐标;floorId为楼层ID,可忽略或null表示当前楼层。
-needEnable表示该点是否启用时才返回,其值不设置则默认为true。
+showDisable如果为true,则对于禁用的点和事件也会进行返回。
如果该点不存在图块,则返回null。
否则,返回值如下: {"index": xxx, "block": xxx}
其中index为该点在该楼层blocks数组中的索引,block为该图块实际内容。
-core.getBlockId(x, y, floorId, needEnable)
+core.getBlockId(x, y, floorId, showDisable)
获得某个点的图块ID。
x和y为坐标;floorId为楼层ID,可忽略或null表示当前楼层。
-needEnable表示是否需要该点处于启用状态才返回,其值不设置则默认为true。
+showDisable如果为true,则对于禁用的点和事件也会进行返回。
如果该点不存在图块,则返回null,否则返回该点的图块ID。
+core.getBlockCls(x, y, floorId, showDisable)
+获得某个点的图块cls。
+x和y为坐标;floorId为楼层ID,可忽略或null表示当前楼层。
+showDisable如果为true,则对于禁用的点和事件也会进行返回。
+如果该点不存在图块,则返回null,否则返回该点的图块cls。
+
+
core.showBlock(x, y, floorId)
将某个点从禁用变成启用状态。
@@ -292,6 +299,14 @@ actions.js主要用来进行用户交互行为的处理。
========== core.control.XXX 和游戏控制相关的函数 ==========
control.js主要用来进行游戏控制,比如行走控制、自动寻路、存读档等等游戏核心内容。
+core.control.setGameCanvasTranslate(canvasId, x, y)
+设置大地图的偏移量
+
+core.control.updateViewport()
+更新大地图的可见区域
+
+core.control.replay()
+回放下一个操作
========== core.enemys.XXX 和怪物相关的函数 ==========
enemys.js主要用来进行怪物相关的内容,比如怪物的特殊属性,伤害和临界计算等。
diff --git a/docs/element.md b/docs/element.md
index b5496f4a..882f54f5 100644
--- a/docs/element.md
+++ b/docs/element.md
@@ -1,6 +1,6 @@
# 元件说明
-?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
+?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} *
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
@@ -43,7 +43,7 @@
// 在该点的事件events中:
"x,y": [
- {"type": "openDoor", "loc": [x,y]} // 直接使用开门事件,坐标需写当前点坐标。
+ {"type": "openDoor"} // 直接使用开门事件,坐标可忽略表示当前点
]
```
@@ -64,38 +64,39 @@ yellowWall, blueWall, whiteWall, lava, star
怪物可以有特殊属性,每个怪物可以有多个自定义属性。
-怪物的特殊属性所对应的数字(special)在`libs/enemys.js`中的`getSpecialText`中定义,请勿对已有的属性进行修改。
+怪物的特殊属性所对应的数字(special)在脚本编辑中的`getSpecials`中定义,请勿对已有的属性进行修改。
``` js
-enemys.prototype.getSpecialText = function (enemyId) {
- if (enemyId == undefined) return "";
- var enemy = this.enemys[enemyId];
- var special = enemy.special;
- var text = [];
- if (this.hasSpecial(special, 1)) text.push("先攻");
- if (this.hasSpecial(special, 2)) text.push("魔攻");
- if (this.hasSpecial(special, 3)) text.push("坚固");
- if (this.hasSpecial(special, 4)) text.push("2连击");
- if (this.hasSpecial(special, 5)) text.push("3连击");
- if (this.hasSpecial(special, 6)) text.push((enemy.n||4)+"连击");
- if (this.hasSpecial(special, 7)) text.push("破甲");
- if (this.hasSpecial(special, 8)) text.push("反击");
- if (this.hasSpecial(special, 9)) text.push("净化");
- if (this.hasSpecial(special, 10)) text.push("模仿");
- if (this.hasSpecial(special, 11)) text.push("吸血");
- if (this.hasSpecial(special, 12)) text.push("中毒");
- if (this.hasSpecial(special, 13)) text.push("衰弱");
- if (this.hasSpecial(special, 14)) text.push("诅咒");
- if (this.hasSpecial(special, 15)) text.push("领域");
- if (this.hasSpecial(special, 16)) text.push("夹击");
- if (this.hasSpecial(special, 17)) text.push("仇恨");
- if (this.hasSpecial(special, 18)) text.push("阻击");
- if (this.hasSpecial(special, 19)) text.push("自爆");
- if (this.hasSpecial(special, 20)) text.push("无敌");
- if (this.hasSpecial(special, 21)) text.push("退化");
- if (this.hasSpecial(special, 22)) text.push("固伤");
- if (this.hasSpecial(special, 23)) text.push("重生");
- return text.join(" ");
+function() {
+ // 获得怪物的特殊属性,每一行定义一个特殊属性。
+ // 分为三项,第一项为该特殊属性的数字,第二项为特殊属性的名字,第三项为特殊属性的描述
+ // 可以直接写字符串,也可以写个function将怪物传进去
+ return [
+ [1, "先攻", "怪物首先攻击"],
+ [2, "魔攻", "怪物无视勇士的防御"],
+ [3, "坚固", "勇士每回合最多只能对怪物造成1点伤害"],
+ [4, "2连击", "怪物每回合攻击2次"],
+ [5, "3连击", "怪物每回合攻击3次"],
+ [6, function(enemy) {return (enemy.n||4)+"连击";}, function(enemy) {return "怪物每回合攻击"+(enemy.n||4)+"次";}],
+ [7, "破甲", "战斗前,怪物附加角色防御的"+Math.floor(100*core.values.breakArmor||0)+"%作为伤害"],
+ [8, "反击", "战斗时,怪物每回合附加角色攻击的"+Math.floor(100*core.values.counterAttack||0)+"%作为伤害,无视角色防御"],
+ [9, "净化", "战斗前,怪物附加勇士魔防的"+core.values.purify+"倍作为伤害"],
+ [10, "模仿", "怪物的攻防和勇士攻防相等"],
+ [11, "吸血", function (enemy) {return "战斗前,怪物首先吸取角色的"+Math.floor(100*enemy.value||0)+"%生命作为伤害"+(enemy.add?",并把伤害数值加到自身生命上":"");}],
+ [12, "中毒", "战斗后,勇士陷入中毒状态,每一步损失生命"+core.values.poisonDamage+"点"],
+ [13, "衰弱", "战斗后,勇士陷入衰弱状态,攻防暂时下降"+(core.values.weakValue>=1?core.values.weakValue+"点":parseInt(core.values.weakValue*100)+"%")],
+ [14, "诅咒", "战斗后,勇士陷入诅咒状态,战斗无法获得金币和经验"],
+ [15, "领域", function (enemy) {return "经过怪物周围"+(enemy.range||1)+"格时自动减生命"+(enemy.value||0)+"点";}],
+ [16, "夹击", "经过两只相同的怪物中间,勇士生命值变成一半"],
+ [17, "仇恨", "战斗前,怪物附加之前积累的仇恨值作为伤害"+(core.flags.hatredDecrease?";战斗后,释放一半的仇恨值":"")+"。(每杀死一个怪物获得"+(core.values.hatred||0)+"点仇恨值)"],
+ [18, "阻击", function (enemy) {return "经过怪物的十字领域时自动减生命"+(enemy.value||0)+"点,同时怪物后退一格";}],
+ [19, "自爆", "战斗后勇士的生命值变成1"],
+ [20, "无敌", "勇士无法打败怪物,除非拥有十字架"],
+ [21, "退化", function (enemy) {return "战斗后勇士永久下降"+(enemy.atkValue||0)+"点攻击和"+(enemy.defValue||0)+"点防御";}],
+ [22, "固伤", function (enemy) {return "战斗前,怪物对勇士造成"+(enemy.damage||0)+"点固定伤害,无视勇士魔防。";}],
+ [23, "重生", "怪物被击败后,角色转换楼层则怪物将再次出现"],
+ [24, "激光", function (enemy) {return "经过怪物同行或同列时自动减生命"+(enemy.value||0)+"点";}]
+ ];
}
```
@@ -138,11 +139,13 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数
领域怪还可以设置`range`选项代表该领域怪的范围,不写则默认为1。
-阻击怪同样需要设置value,代表领域伤害的数值。如果勇士生命值扣减到0,则直接死亡触发lose事件。
+阻击怪同样需要设置value,代表阻击伤害的数值。如果勇士生命值扣减到0,则直接死亡触发lose事件。
!> 阻击怪后退的地点不能有任何事件存在,即使是已经被禁用的自定义事件!
-请注意如果吸血、领域、阻击中任何两个同时存在,则value会冲突。**因此请勿将吸血、领域或阻击放置在同一个怪物身上。**
+激光怪同样需要设置value,代表激光伤害的数值。
+
+请注意如果吸血、领域、阻击中任何两个同时存在,则value会冲突。**因此请勿将吸血、领域、阻击或激光放置在同一个怪物身上。**
退化怪需要设置'atkValue'和'defValue'表示退化的数值;也可以不设置默认为0。
@@ -176,6 +179,14 @@ floorId指定的是目标楼层的唯一标识符(ID)。
**从2.1.1开始,楼层属性中提供了`upFloor`和`downFloor`两项。如果设置此项(比如`"upFloor": [2,3]`),则写stair:upFloor或者楼传器的落点将用此点来替换楼梯位置(即类似于RM中的上箭头)。**
+## 大地图
+
+从V2.4开始,H5魔塔开始支持大地图。
+
+大地图在创建时可以指定宽高,要求**宽和高都不得小于13,且宽高之积不超过1000**。
+
+大地图一旦创建成功则不得修改宽高数值。
+
## 动画和天气系统
现在我们的H5魔塔支持播放动画,也支持天气系统了。
@@ -271,8 +282,7 @@ HTML5魔塔一大亮点就是存在录像系统,可以很方便进行录像回
- **回退:** 按A可以回退到上一个录像节点(录像播放过程中每50步存一个录像节点)。
- **存档:** 按S可以在录像播放过程中进行存档。
- **查看手册:** 按C可以在录像播放过程中查看怪物手册。
-
-上述操作在手机端均有工具栏的对应按钮可点击操作。
+- **浏览地图:** 按PgUp/PgDn可以在录像播放过程中浏览地图。
如果录像出现问题,请加群539113091找小艾反馈Bug。
diff --git a/docs/event.md b/docs/event.md
index 04e68bc7..7b787615 100644
--- a/docs/event.md
+++ b/docs/event.md
@@ -1,6 +1,6 @@
# 事件
-?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
+?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} *
本章内将对样板所支持的事件进行介绍。
@@ -1687,11 +1687,15 @@ core.insertAction([
游戏开始时将调用`events.js`中的`startGame`函数。
-它将显示`data.js`中的startText内容(可以修改成自己的),提供战斗动画开启选择,设置初始福利,并正式开始游戏。
+它将显示全塔属性中的startText内容(可以修改成自己的),提供战斗动画开启选择,设置初始福利,并正式开始游戏。
-我们可以修改`setInitData`函数来对于不同难度分别设置初始属性。
+全塔属性的startText只能使用纯文本类型,其他的事件均无效。
-其参数hard为以下三个字符串之一:`"Easy"`, `"Normal"`, `"Hard"`,分别对应三个难度。针对不同的难度,我们可以设置一些难度分歧。
+我们可以修改脚本编辑`setInitData`函数来对于不同难度分别设置初始属性。
+
+其参数hard分为对应全塔属性中levelChooseButtons中的第二项,分别对应不同的难度,并会在游戏中传输,在状态栏显示。
+
+针对不同的难度,我们可以设置一些难度分歧。
``` js
////// 不同难度分别设置初始属性 //////
@@ -1718,9 +1722,11 @@ core.insertAction([
当获胜`{"type": "win"}`事件发生时,将调用`events.js`中的win事件。其显示一段恭喜文字,并重新开始游戏。
+可以指定norank表示该结局不计入榜单。
+
``` js
////// 游戏获胜事件 //////
-"win": function(reason) {
+"win": function(reason, norank) {
core.ui.closePanel();
var replaying = core.status.replay.replaying;
core.stopReplay();
@@ -1730,7 +1736,7 @@ core.insertAction([
core.drawText([
"\t[恭喜通关]你的分数是${status:hp}。"
], function () {
- core.events.gameOver(reason||'', replaying);
+ core.events.gameOver(reason||'', replaying, norank);
})
});
}
diff --git a/docs/index.md b/docs/index.md
index 0e744fb2..4bfabadd 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,6 +1,6 @@
# HTML5 魔塔样板说明文档
-?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
+?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} *
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
diff --git a/docs/personalization.md b/docs/personalization.md
index caa80a16..450e90e4 100644
--- a/docs/personalization.md
+++ b/docs/personalization.md
@@ -1,6 +1,6 @@
# 个性化
-?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
+?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} *
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
@@ -15,9 +15,10 @@ HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们
- hero:勇士层;主要用来绘制勇士
- event2:事件2层;本层主要用来绘制48x32的图片素材的上半部分(避免和勇士错位),也可以用来绘制该层的前景图片素材
- fg:显伤层;主要用来绘制怪物显伤和领域显伤
-- animate:动画层;主要用来绘制动画,图块的淡入/淡出效果,图块的移动。showImage事件绘制的图片也是在这一层。
+- animate:动画层;主要用来绘制动画。showImage事件绘制的图片也是在这一层。
- weather:天气层;主要用来绘制天气(雨/雪)
- curtain:色调层;用来控制当前楼层的画面色调
+- route:路线层;主要用来绘制勇士的行走路线图,也用来绘制图块的淡入/淡出效果,图块的移动等。
- ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等
- data:数据层;用来绘制一些顶层的或更新比较快的数据,如左上角的提示,战斗界面中数据的变化等等。
@@ -299,7 +300,7 @@ enemys.prototype.calDamage = function (monster, hero_hp, hero_atk, hero_def, her
// 检查领域、夹击、阻击事件
control.prototype.checkBlock = function () {
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
- var damage = core.status.checkBlock.damage[13*x+y];
+ var damage = core.status.checkBlock.damage[x+core.bigmap.width*y];
if (damage>0) {
if (core.hasFlag("shield5")) damage = 0; // 如果存在神圣盾,则将伤害变成0
core.status.hero.hp -= damage;
@@ -437,18 +438,18 @@ this.useEquipment = function (itemId) { // 使用装备
## 自定义怪物属性
-如果你对现有的怪物不满意,想自行添加怪物属性(例如让怪物拥有双属性乃至更多属性),也是可以的。具体参见`enemys.js`文件。
+如果你对现有的怪物不满意,想自行添加怪物属性也是可以的。具体参见脚本编辑-getSpecials。
-你需自己指定一个special数字,修改getSpecialText函数(属性名)和getSpecialHint函数(属性提示文字)。
+你需自己指定一个special数字,修改属性名和属性提示文字。后两者可以直接写字符串,或写个函数传入怪物。
如果要修改伤害计算公式,请修改下面的getDamageInfo函数。请注意,如果无法战斗,该函数必须返回`null`。
-对于毒衰弱怪物的战斗后结算在`functions.js`中的afterBattle函数中。
+!> 如果改动了伤害计算公式,可能导致临界计算崩掉,因此建议将全塔属性中的`useLoop`置为true。
+
+对于毒衰弱怪物的战斗后结算在脚本编辑中的afterBattle函数中。
对于领域、夹击、阻击怪物的检查在`control.js`中的checkBlock函数中。
-`getCritical`, `getCriticalDamage`和`getDefDamage`三个函数依次计算的是该怪物的临界值、临界减伤和1防减伤。也可以适当进行修改。
-
## 自定义快捷键
如果需要绑定某个快捷键为处理一段事件,也是可行的。
diff --git a/docs/start.md b/docs/start.md
index 6ab94659..46d5346d 100644
--- a/docs/start.md
+++ b/docs/start.md
@@ -1,6 +1,6 @@
# 快速上手
-?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
+?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} *
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
@@ -57,11 +57,13 @@

-我们打开Windows自带的“截图工具”,并将整个地图有效区域截图下来,并将其复制到剪切板。
+我们打开地图编辑器,创建一个地图,宽高需要和RM中的地图一致。
+
+之后,我们打开Windows自带的“截图工具”,并将整个地图有效区域截图下来,并将其复制到剪切板。

-截图时请注意:**只截取有效游戏空间内数据,并且有效空间内的范围必须是13x13。(如果地图小于13*13,请用星空或墙壁填充到13x13)。**
+截图时请注意:**只截取有效游戏空间内数据,并且有效空间内的范围必须是创建的地图的大小(至少为13x13)。**
确认地图的图片文件已经复制到剪切板后,我们打开“地图生成器”,并点“加载图片”。大约1-2秒后,可以得到地图的数据。
@@ -71,7 +73,9 @@
!> **地图生成器默认只支持已被定义的素材。如果有自定义素材需求(例如原版的1层小塔那种素材),请先[导入并注册素材](#素材注册)后再进行操作。**
-!> **请确保截图范围刚好为13x13,并且保证每个位置的像素都是32x32。**
+!> **请确保截图范围为你创建的地图大小,并且保证每个位置的像素都是32x32。**
+
+!> **如果宽度超过13,地图生成器将无法显示完全,但是仍然可以粘贴到地图编辑器中进行修改。**
!> **地图生成器靠左上角来确定偏移量,如果左上角是全黑或者星空之类的素材可能导致识别不准,此时请在左上角放置一个岩浆后再进行截图识别。**
diff --git a/editor-mobile.html b/editor-mobile.html
index eae04732..dc971066 100644
--- a/editor-mobile.html
+++ b/editor-mobile.html
@@ -20,13 +20,17 @@
-
{{ errors[error-1] }}
+
-
+
+ 宽
+
+ 高
+
- 保留楼层属性
+ 保留属性
-
-
+
+
+
+
+
+
@@ -370,36 +386,20 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
diff --git a/index.html b/index.html
index 0f69d24f..7b07028a 100644
--- a/index.html
+++ b/index.html
@@ -87,6 +87,11 @@
+
+
+
+
+
@@ -106,18 +111,22 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+