Merge pull request #227 from zhaouv/editor-tilesets

Editor: tilesets airwall shortcut
This commit is contained in:
Zhang Chen 2018-09-27 23:29:37 +08:00 committed by GitHub
commit 82519ae27b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 35 deletions

View File

@ -1,6 +1,6 @@
function editor() {
this.version = "2.0";
this.brushMod = "line";//["line","rectangle"]
this.brushMod = "line";//["line","rectangle","tileset"]
this.layerMod = "map";//["fgmap","map","bgmap"]
this.isMobile = false;
}
@ -97,6 +97,12 @@ editor.prototype.idsInit = function (maps, icons) {
var id = indexBlock.event.id;
var indexId = indexBlock.id;
var allCls = Object.keys(icons);
if(i==17){
editor.ids.push({'idnum': 17, 'id': id, 'images': 'terrains'});
point++;
editor.indexs[i].push(point);
continue;
}
for (var j = 0; j < allCls.length; j++) {
if (id in icons[allCls[j]]) {
editor.ids.push({'idnum': indexId, 'id': id, 'images': allCls[j], 'y': icons[allCls[j]][id]});
@ -332,9 +338,9 @@ editor.prototype.drawInitData = function (icons) {
continue;
}
if (img == 'terrains') {
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + images[img].width) / 32, images[img].height + 32]
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + images[img].width) / 32, images[img].height + 32*2]
sumWidth += images[img].width;
maxHeight = Math.max(maxHeight, images[img].height + 32);
maxHeight = Math.max(maxHeight, images[img].height + 32*2);
continue;
}
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + images[img].width) / 32, images[img].height];
@ -360,7 +366,19 @@ editor.prototype.drawInitData = function (icons) {
for (var ii = 0; ii < imgNames.length; ii++) {
var img = imgNames[ii];
if (img == 'terrains') {
dc.drawImage(images[img], nowx, 32);
(function(image,dc,nowx){
if (image.complete) {
dc.drawImage(image, nowx, 32);
core.material.images.airwall = image;
delete(editor.airwallImg);
} else image.onload = function () {
dc.drawImage(image, nowx, 32);
core.material.images.airwall = image;
delete(editor.airwallImg);
editor.updateMap();
}
})(editor.airwallImg,dc,nowx);
dc.drawImage(images[img], nowx, 32*2);
nowx += images[img].width;
continue;
}
@ -443,6 +461,31 @@ editor.prototype.buildMark = function(){
}
}
editor.prototype.setSelectBoxFromInfo=function(thisevent){
var pos={x: 0, y: 0, images: "terrains"};
var ysize = 32;
if(thisevent==0){
} else if (thisevent.idnum==17){
pos.y=1;
} else {
pos.x=editor.widthsX[thisevent.images][1];
pos.y=thisevent.y;
if(thisevent.x)pos.x+=thisevent.x;
if(thisevent.images=='terrains')pos.y+=2;
ysize = thisevent.images.indexOf('48') === -1 ? 32 : 48;
}
var dataSelection = document.getElementById('dataSelection');
dataSelection.style.left = pos.x * 32 + 'px';
dataSelection.style.top = pos.y * ysize + 'px';
dataSelection.style.height = ysize - 6 + 'px';
setTimeout(function(){selectBox.isSelected = true;});
editor.info = JSON.parse(JSON.stringify(thisevent));
tip.infos = JSON.parse(JSON.stringify(thisevent));
editor.pos=pos;
editor_mode.onmode('nextChange');
editor_mode.onmode('enemyitem');
}
editor.prototype.listen = function () {
document.body.onmousedown = function (e) {
@ -471,7 +514,7 @@ editor.prototype.listen = function () {
});
var unselect=true;
for(var ii=0,thisId;thisId=['edit','tip','brushMod','brushMod2','layerMod','layerMod2','layerMod3','viewportButtons'][ii];ii++){
for(var ii=0,thisId;thisId=['edit','tip','brushMod','brushMod2','brushMod3','layerMod','layerMod2','layerMod3','viewportButtons'][ii];ii++){
if (clickpath.indexOf(thisId) !== -1){
unselect=false;
break;
@ -628,7 +671,7 @@ editor.prototype.listen = function () {
e.stopPropagation();
if (stepPostfix && stepPostfix.length) {
preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
if(editor.brushMod==='rectangle'){
if(editor.brushMod!=='line'){
var x0=stepPostfix[0].x;
var y0=stepPostfix[0].y;
var x1=stepPostfix[stepPostfix.length-1].x;
@ -636,8 +679,8 @@ editor.prototype.listen = function () {
if(x0>x1){x0^=x1;x1^=x0;x0^=x1;}//swap
if(y0>y1){y0^=y1;y1^=y0;y0^=y1;}//swap
stepPostfix=[];
for(var ii=x0;ii<=x1;ii++){
for(var jj=y0;jj<=y1;jj++){
for(var jj=y0;jj<=y1;jj++){
for(var ii=x0;ii<=x1;ii++){
stepPostfix.push({x:ii,y:jj})
}
}
@ -649,8 +692,22 @@ editor.prototype.listen = function () {
if (editor.layerMod!='map' && editor.info.images && editor.info.images.indexOf('48')!==-1){
printe('前景/背景不支持48的图块');
} else {
for (var ii = 0; ii < stepPostfix.length; ii++)
if(editor.brushMod==='tileset' && core.tilesets.indexOf(editor.info.images)!==-1){
var imgWidth=~~(core.material.images.tilesets[editor.info.images].width/32);
var x0=stepPostfix[0].x;
var y0=stepPostfix[0].y;
var idnum=editor.info.idnum;
for (var ii = 0; ii < stepPostfix.length; ii++){
if(stepPostfix[ii].y!=y0){
y0++;
idnum+=imgWidth;
}
editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.ids[editor.indexs[idnum+stepPostfix[ii].x-x0]];
}
} else {
for (var ii = 0; ii < stepPostfix.length; ii++)
editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.info;
}
}
// console.log(editor.map);
editor.updateMap();
@ -713,9 +770,12 @@ editor.prototype.listen = function () {
info: {}
};
var reDo = null;
var shortcut = core.getLocalStorage('shortcut',{49: 0, 50: 0, 51: 0, 52: 0, 53: 0, 54: 0, 55: 0, 56: 0, 57: 0});
document.body.onkeydown = function (e) {
// 禁止快捷键的默认行为
if (e.ctrlKey && ( e.keyCode == 90 || e.keyCode == 89 ))
if (e.ctrlKey && [89, 90, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
e.preventDefault();
if (e.altKey && [49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
e.preventDefault();
//Ctrl+z 撤销上一步undo
if (e.keyCode == 90 && e.ctrlKey && preMapData && currDrawData.pos.length && selectBox.isSelected) {
@ -760,6 +820,18 @@ editor.prototype.listen = function () {
editor.changeFloor(toId);
}
}
//ctrl + 1~9 切换到快捷图块
if (e.ctrlKey && [49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1){
editor.setSelectBoxFromInfo(JSON.parse(JSON.stringify(shortcut[e.keyCode]||0)));
}
//alt + 1~9 改变快捷图块
if (e.altKey && [49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1){
var infoToSave = JSON.stringify(editor.info||0);
if(infoToSave==JSON.stringify({}))return;
shortcut[e.keyCode]=JSON.parse(infoToSave);
printf('已保存该快捷图块, ctrl + '+(e.keyCode-48)+' 使用.')
core.setLocalStorage('shortcut',shortcut);
}
}
var dataSelection = document.getElementById('dataSelection');
@ -806,9 +878,11 @@ editor.prototype.listen = function () {
if (pos.x == 0 && pos.y == 0) {
// editor.info={idnum:0, id:'empty','images':'清除块', 'y':0};
editor.info = 0;
} else if(pos.x == 0 && pos.y == 1){
editor.info = editor.ids[editor.indexs[17]];
} 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 (pos.images == 'terrains') editor.info = {'images': pos.images, 'y': pos.y - 2};
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};
@ -877,28 +951,7 @@ editor.prototype.listen = function () {
editor.hideMidMenu();
e.stopPropagation();
var thisevent = editor.map[editor.pos.y][editor.pos.x];
var pos={x: 0, y: 0, images: "terrains"};
var ysize = 32;
if(thisevent==0){
//选中清除块
editor.info = 0;
editor.pos=pos;
} else {
var ids=editor.indexs[thisevent.idnum];
ids=ids[0]?ids[0]:ids;
editor.info=editor.ids[ids];
pos.x=editor.widthsX[thisevent.images][1];
pos.y=editor.info.y;
if(thisevent.images=='terrains')pos.y++;
ysize = thisevent.images.indexOf('48') === -1 ? 32 : 48;
}
setTimeout(function(){selectBox.isSelected = true;});
dataSelection.style.left = pos.x * 32 + 'px';
dataSelection.style.top = pos.y * ysize + 'px';
dataSelection.style.height = ysize - 6 + 'px';
tip.infos = JSON.parse(JSON.stringify(editor.info));
editor_mode.onmode('nextChange');
editor_mode.onmode('enemyitem');
editor.setSelectBoxFromInfo(thisevent);
}
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
@ -1016,6 +1069,11 @@ editor.prototype.listen = function () {
editor.brushMod=brushMod2.value;
}
var brushMod3=document.getElementById('brushMod3');
if(brushMod3)brushMod3.onchange=function(){
editor.brushMod=brushMod3.value;
}
var layerMod=document.getElementById('layerMod');
layerMod.onchange=function(){
editor.layerMod=layerMod.value;

View File

@ -315,7 +315,7 @@ editor_mode = function (editor) {
//editor.info=editor.ids[editor.indexs[201]];
if (!core.isset(editor.info)) return;
if (Object.keys(editor.info).length !== 0) editor_mode.info = editor.info;//避免editor.info被清空导致无法获得是物品还是怪物
if (Object.keys(editor.info).length !== 0 && editor.info.idnum!=17) editor_mode.info = editor.info;//避免editor.info被清空导致无法获得是物品还是怪物
if (!core.isset(editor_mode.info.id)) {
// document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML = '';

View File

@ -241,6 +241,7 @@ var tip = new Vue({
isAutotile: false,
isSelectedBlock: false,
isClearBlock: false,
isAirwall: false,
geneMapSuccess: false,
timer: null,
msgs: [ //分别编号1,2,3,4,5,6,7,8,9,10奇数警告偶数成功
@ -264,12 +265,17 @@ var tip = new Vue({
infos: {
handler: function (val, oldval) {
this.isClearBlock = false;
this.isAirwall = false;
if (typeof(val) != 'undefined') {
if (val == 0) {
this.isClearBlock = true;
return;
}
if ('id' in val) {
if (val.idnum == 17) {
this.isAirwall = true;
return;
}
this.hasId = true;
} else {
this.hasId = false;

View File

@ -234,6 +234,7 @@
<div id="tip" v-cloak>
<div v-if="isSelectedBlock">
<p v-if="isClearBlock" class="infoText">当前选择为清除块,可擦除地图上块</p>
<p v-if="isAirwall" class="infoText">当前选择为空气墙, 在编辑器中可视, 在游戏中隐藏的墙, 用来配合前景/背景的贴图</p>
<div v-else>
<p v-if="hasId">图块编号:<span class="infoText">{{ infos['idnum'] }}</span></p>
<p v-if="hasId">图块ID<span class="infoText">{{ infos['id'] }}</span></p>
@ -276,6 +277,7 @@
<select id="brushMod" style="clear:right">
<option value="line">画线</option>
<option value="rectangle">画矩形</option>
<option value="tileset">tileset贴图</option>
</select>
<select id="layerMod" style="float:left;margin-right:3px">
<option value="bgmap">背景层</option>
@ -449,6 +451,8 @@ if (location.protocol.indexOf("http")!=0) {
var useCompress = main.useCompress;
main.useCompress = false;
editor.airwallImg = new Image();
editor.airwallImg.src = './project/images/airwall.png';
main.init('editor', function () {
editor.init(function () {
editor.useCompress = useCompress;

View File

@ -221,6 +221,7 @@
<div id="tip" v-cloak>
<div v-if="isSelectedBlock">
<p v-if="isClearBlock" class="infoText">当前选择为清除块,可擦除地图上块</p>
<p v-else-if="isAirwall" class="infoText">当前选择为空气墙, 在编辑器中可视, 在游戏中隐藏的墙, 用来配合前景/背景的贴图</p>
<div v-else>
<p v-if="hasId">图块编号:<span class="infoText">{{ infos['idnum'] }}</span></p>
<p v-if="hasId">图块ID<span class="infoText">{{ infos['id'] }}</span></p>
@ -245,9 +246,11 @@
<option value="functions">脚本编辑</option>
<option value="appendpic">追加素材</option>
</select>
<span style="font-size: 12px; margin-left: 5px">
<br/>
<span style="font-size: 12px;">
<input type="radio" id="brushMod" name="brushMod" value="line" checked="checked" />画线
<input type="radio" id="brushMod2" name="brushMod" value="rectangle" />画矩形
<input type="radio" id="brushMod3" name="brushMod" value="tileset" />tileset贴图
</span>
<br/>
<span style="font-size: 12px">
@ -432,6 +435,8 @@ if (location.protocol.indexOf("http")!=0) {
<script>
var useCompress = main.useCompress;
main.useCompress = false;
editor.airwallImg = new Image();
editor.airwallImg.src = './project/images/airwall.png';
main.init('editor', function () {
editor.init(function () {
editor.useCompress = useCompress;

BIN
project/images/airwall.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB