This commit is contained in:
echo 2017-12-30 22:04:37 +08:00
parent d94d5f7137
commit c45c638599
3 changed files with 505 additions and 356 deletions

340
_server/css/editor.css Normal file
View File

@ -0,0 +1,340 @@
html,body,div,img{margin:0;padding:0;}
body{
font-family: Roboto,"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;;
background-color: #F5F5F5;
}
/* ::-webkit-scrollbar {
width: 5px;
} */
.main {
max-width: 100%;
min-height: 500px;
margin: 0 auto;
}
#left, #mid, #right{
border-radius: 2px;
box-sizing: border-box;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
}
#left{
position: absolute;
left: 5px;
top: 10px;
width: 435px;
height: 630px;
}
.nav {
width: 100%;
height: 40px;
margin-top: 5px;
box-sizing: border-box;
}
.nav a{
display: block;
float: left;
line-height: 30px;
font-size: 14px;
text-align: center;
color: #424242;
margin: 0 10px;
padding: 0 3px ;
list-style: none;
box-sizing: border-box;
cursor: pointer;
/* border-bottom: 3px solid #009688; */
}
.is-selected {
border-bottom: 3px solid #009688;
}
#left .tabs{
position: absolute;
top: 50px;
left: 0;
width: 435px;
height: 535px;
}
#left .card{
width: 100%;
height: 535px;
position: absolute;
left: 0;
top: 10px;
border-top: 1px solid #ccc;
}
#arrEditor{
z-index: 8;
}
.card .lineTitle {
position: absolute;
top: -12px;
left: 20px;
padding: 0 5px;
font-size: 14px;
color: #03A9F4;
background-color: #F5F5F5;
z-index: 10;
}
#editArea{
width: 100%;
height: 70%;
/* padding: 10px 5px; */
box-sizing: border-box;
margin-top: 15px;
}
#pout{
position: absolute;
left: 22px;
top: 37px;
display: block;
width: 410px;
height: 300px;
box-sizing: border-box;
line-height: 20px;
font-size: 12.3px;
font-family: 'Lucida Console', Monaco, monospace;
white-space: pre;
border: 1px solid #ddd;
border-radius: 2px;
}
#editTip{
position: absolute;
width: 100%;
height: 80px;
bottom:10px;
left: 10px;
}
#editArea p{
margin: 10px;
display: block;
width: 70%;
line-height: 20px;
text-align: left;
font-size: 14px;
}
#editTip .btn{
float: right;
margin-right: 20px;
margin-top: 5px;
}
.files {
width: 100%;
height: 120px;
/* padding: 10px; */
margin-top: 15px;
}
.files .input{
display: block;
max-width: 150px;
height: 20px;
padding: 6px 12px;
font-size: 14px;
margin-top: 10px;
color: #555;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 3px;
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
}
/* ==================================== */
#mid{
position: absolute;
left: 448px;
top: 10px;
width: 440px;
height: 630px;
}
.map {
position: absolute;
left: 20px;
top: 21px;
width: 416px;
height: 416px;
}
#mid .tools{
position: absolute;
width: 425px;
height: 180px;
left: 0;
bottom: 0;
border-top: 1px solid #ccc;
padding: 10px 5px;
margin-left: 8px;;
box-sizing: border-box;
}
#tip{
float: right;
width: 50%;
height: 95%;
padding: 5px 10px 10px 10px;
margin-right: 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
font-size: 15px;
line-height: 14px;
}
#printOut{
margin-top: 10px;
height: 20px;
}
.btn {
width: 80px;
border-radius: 2px;
line-height: 30px;
margin: 0;
min-width: 50px;
padding: 0 5px;
display: inline-block;
font-size: 14px;
font-weight: 400;
/* text-transform: uppercase; */
letter-spacing: 0;
overflow: hidden;
cursor: pointer;
text-decoration: none;
text-align: center;
vertical-align: middle;
border: 0;
background: rgba(158,158,158,.2);
box-shadow: 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 3px 0 rgba(0,0,0,.12);
color: #fff;
background-color: #26A69A;
}
.btn:hover {
background-color: #009688;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
}
/* =========================== */
#right{
position: absolute;
left: 900px;
top: 10px;
width: 440px;
height: 630px;
/* border: 1px solid rgb(238, 13, 13); */
}
#iconLib{
position: absolute;
width: 435px;
height: 620px;
left: 5px;
top: 5px;
overflow: auto;
}
.gameCanvas {
position: absolute;
}
#dataSelection{
position: absolute;
/* top:0;
left:320px; */
z-index:75;
width:26px;
height:26px;
margin: 3px 0 0 3px;
padding:0;
/* display: none; */
box-sizing: border-box;
background-color:rgba(255, 255, 255, 0.0);
border: 1px solid #000;
box-shadow: 0 0 0 2px #fff,
0 0 0 3px #000;
}
.warnText{
color: #D50000;
font-weight: 700;
font-size: 14px;
}
.infoText{
color: #2196F3;
}
.successText{
color: #00897B
}
table, td {
border: 1px solid #fff;
color: #fff;
cursor:crosshair;
}
table.col{
position: relative;
text-align: center;
border-collapse: collapse;
}
table.col td{
background-color: #4DB6AC;
}
#arrColMark td{
width: 16px;
}
#arrColMark {
top: 2px;
left: 36px;
width: 385px;
height: 16px;
font-size: 13px;
}
#mapColMark {
top: 2px;
left: 19px;
width: 418px;
height: 16px;
font-size: 13px;
}
#mapColMark td{
width: 29px;
}
#mapColMark td:hover .colBlock{
position: absolute;
top: 19px;
height: 416px;
width: 32px;
z-index: 100;
background-color: rgba(38,166,154,.5);
}
table.row{
position: relative;
text-align: right;
vertical-align:middle;
border-collapse: collapse;
}
table.row td{
background-color: #4C221B;
}
#arrRowMark{
top: 5px;
left: 2px;
width: 16px;
height: 262px;
font-size: 12px;
}
#mapRowMark{
top: 1px;
left: 2px;
width: 16px;
height: 416px;
font-size: 12px;
}
#mapRowMark td{
height: 29px;
}
#mapRowMark td:hover .rowBlock{
position: absolute;
left: 18px;
height: 32px;
width: 416px;
z-index: 100;
background-color: rgba(76,34,27,.5);
}
/* for vue dom */
[v-cloak] {
display: none !important;
}

View File

@ -245,3 +245,51 @@ var selectBox = new Vue({
}
}
})
var editFile4map = new Vue({
el: '#editFile4map',
data: {
selected: 'untitle',
options:[],
filelist: [],
},
watch: {
filelist: function(val){
if(val){
var oval = val.length ? JSON.parse(JSON.stringify(val)) : [];
for(var i=0; i<oval.length; i++)
this.$set("options", i, oval[i]);
}
},
}
})
var modSeletNav = new Vue({
el: '#modSeletNav',
data: {
currTabnum: 1,
tabs:[
{num: 1, title: "地图数组"},
{num: 2, title: "对象属性"},
{num: 3, title: "选点事件"},
{num: 4, title: "楼层事件"},
]
},
watch: {
currTabnum(val){
this.$emit('on-change', val)
this.$emit('input', val)
}
},
methods: {
selectTab(num){
this.currTabnum = num;
tabSelection.showTab = num;
}
}
})
var tabSelection = new Vue({
el: '#tabSelection',
data: {
showTab: 1,
},
})

View File

@ -2,316 +2,57 @@
<html>
<head>
<meta charset="utf-8">
<style>
html,body,div,img{margin:0;padding:0;}
body{
font-family: Roboto,"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;;
background-color: #F5F5F5;
}
/* ::-webkit-scrollbar {
width: 5px;
} */
.main {
max-width: 100%;
min-height: 500px;
margin: 0 auto;
}
#left, #mid, #right{
border-radius: 2px;
box-sizing: border-box;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
}
#left{
position: absolute;
left: 5px;
top: 10px;
width: 435px;
height: 630px;
}
#editArea{
position: absolute;
width: 100%;
height: 70%;
left: 0;
top: 0;
/* padding: 10px 5px; */
box-sizing: border-box;
}
#pout{
display: block;
width: 410px;
height: 100%;
box-sizing: border-box;
margin-left: 22px;
margin-top: 23px;
line-height: 20px;
font-size: 12.3px;
font-family: 'Lucida Console', Monaco, monospace;
white-space: pre;
border: 1px solid #ddd;
border-radius: 2px;
}
#editTip{
position: absolute;
width: 100%;
height: 80px;
bottom:10px;
left: 10px;
}
#editArea p{
margin: 10px;
display: block;
width: 70%;
line-height: 20px;
text-align: left;
font-size: 14px;
}
#editTip .btn{
float: right;
margin-right: 20px;
margin-top: 5px;
}
#mid{
position: absolute;
left: 448px;
top: 10px;
width: 440px;
height: 630px;
}
.map {
position: absolute;
left: 20px;
top: 21px;
width: 416px;
height: 416px;
}
#mid .tools{
position: absolute;
width: 425px;
height: 180px;
left: 0;
bottom: 0;
border-top: 1px solid #ccc;
padding: 10px 5px;
margin-left: 8px;;
box-sizing: border-box;
}
#tip{
float: right;
width: 50%;
height: 95%;
padding: 5px 10px 10px 10px;
margin-right: 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
font-size: 15px;
line-height: 14px;
}
.files {
width: 50%;
height: 120px;
/* padding: 10px; */
margin-top: 15px;
}
.files .input{
display: block;
max-width: 150px;
height: 20px;
padding: 6px 12px;
font-size: 14px;
margin-top: 10px;
color: #555;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 3px;
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
}
#printOut{
margin-top: 10px;
height: 20px;
}
.btn {
width: 80px;
border-radius: 2px;
line-height: 30px;
margin: 0;
min-width: 50px;
padding: 0 5px;
display: inline-block;
font-size: 14px;
font-weight: 400;
/* text-transform: uppercase; */
letter-spacing: 0;
overflow: hidden;
cursor: pointer;
text-decoration: none;
text-align: center;
vertical-align: middle;
border: 0;
background: rgba(158,158,158,.2);
box-shadow: 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 3px 0 rgba(0,0,0,.12);
color: #fff;
background-color: #26A69A;
}
.btn:hover {
background-color: #009688;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
}
#right{
position: absolute;
left: 900px;
top: 10px;
width: 440px;
height: 630px;
/* border: 1px solid rgb(238, 13, 13); */
}
#iconLib{
position: absolute;
width: 435px;
height: 620px;
left: 5px;
top: 5px;
overflow: auto;
}
.gameCanvas {
position: absolute;
}
#dataSelection{
position: absolute;
/* top:0;
left:320px; */
z-index:75;
width:26px;
height:26px;
margin: 3px 0 0 3px;
padding:0;
/* display: none; */
box-sizing: border-box;
background-color:rgba(255, 255, 255, 0.0);
border: 1px solid #000;
box-shadow: 0 0 0 2px #fff,
0 0 0 3px #000;
}
.warnText{
color: #D50000;
font-weight: 700;
font-size: 14px;
}
.infoText{
color: #2196F3;
}
.successText{
color: #00897B
}
table, td {
border: 1px solid #fff;
color: #fff;
cursor:crosshair;
}
table.col{
position: relative;
text-align: center;
border-collapse: collapse;
}
table.col td{
background-color: #4DB6AC;
}
#arrColMark td{
width: 16px;
}
#arrColMark {
top: 2px;
left: 36px;
width: 385px;
height: 16px;
font-size: 13px;
}
#mapColMark {
top: 2px;
left: 19px;
width: 418px;
height: 16px;
font-size: 13px;
}
#mapColMark td{
width: 29px;
}
#mapColMark td:hover .colBlock{
position: absolute;
top: 19px;
height: 416px;
width: 32px;
z-index: 100;
background-color: rgba(38,166,154,.5);
}
table.row{
position: relative;
text-align: right;
vertical-align:middle;
border-collapse: collapse;
}
table.row td{
background-color: #4C221B;
}
#arrRowMark{
top: 5px;
left: 2px;
width: 16px;
height: 262px;
font-size: 12px;
}
#mapRowMark{
top: 1px;
left: 2px;
width: 16px;
height: 416px;
font-size: 12px;
}
#mapRowMark td{
height: 29px;
}
#mapRowMark td:hover .rowBlock{
position: absolute;
left: 18px;
height: 32px;
width: 416px;
z-index: 100;
background-color: rgba(76,34,27,.5);
}
/* for vue dom */
[v-cloak] {
display: none !important;
}
</style>
<link href="_server/css/editor.css" rel="stylesheet">
</head>
<body>
<div class="main">
<div id="left">
<div id="arrEditor">
<table class="col" id='arrColMark'></table>
<table class="row" id='arrRowMark'></table>
<div id="editArea" v-cloak>
<textarea cols="10" rows="10" id="pout" v-model="mapArr"></textarea>
<p class="warnText" v-if="error">{{ errors[error-1] }}</p>
<div class="nav" id="modSeletNav" v-cloak>
<input v-model="currTabnum" type="hidden">
<a v-for="tab in tabs" :key="tab.num"
:class="{ 'is-selected': currTabnum == tab.num }"
@click="selectTab(tab.num)" >
<span v-text="tab.title"></span>
</a>
</div>
<div class="tabs" id="tabSelection" v-cloak>
<div id="arrEditor" class="card" v-show="showTab==1">
<div class="lineTitle">地图数组编辑区</div>
<div id="editArea" v-cloak>
<table class="col" id='arrColMark'></table>
<table class="row" id='arrRowMark'></table>
<textarea cols="10" rows="10" id="pout" v-model="mapArr"></textarea>
<p class="warnText" v-if="error">{{ errors[error-1] }}</p>
</div>
<div id="editTip" v-cloak>
<!-- <input class='btn' type="button" value="复制地图" v-on:click="copyMap"/> -->
</div>
<div class="files" id="editFile4map" v-cloak >
<div class="lineTitle">文件操作区</div>
<select v-model="selected">
<option disabled value="">请选择要编辑的文件</option>
<option v-for="option in options" v-bind:value="option">
{{ option }}
</option>
</select>
<span>当前文件: {{ selected }}</span>
<input class='btn' type="button" value="保存" onclick="readUTF8file(pin.value)" />
<input class='btn' type="button" value="另存为" onclick="writeUTF8file(pin.value,pout.innerText)" />
<input class='input' id='pin' placeholder="请输入文件名"/>
<div id="printOut"></div>
</div>
</div>
<div id="editTip" v-cloak>
<input class='btn' type="button" value="复制地图" v-on:click="copyMap"/>
<div id="objDataEditor" class="card" v-show="showTab==2">
<div class="lineTitle">对象属性编辑区</div>
</div>
<div id="eventEditor" class="card" v-show="showTab==3">
<div class="lineTitle">地图选点事件编辑区</div>
</div>
<div id="floorEditor" class="card" v-show="showTab==4">
<div class="lineTitle">楼层事件编辑区</div>
</div>
</div>
<div id="objDataEditor">
</div>
<div id="eventEditor">
</div>
</div>
<div id="mid">
<table class="col" id='mapColMark'></table>
@ -337,13 +78,6 @@
<input class='btn' id='clear' type="button" value="清除地图" v-on:click="clearMap"/>
<input class='btn' type="button" value="导出地图" id="exportM" v-on:click="exportMap"/>
<div class="files">
<input class='btn' type="button" value="read" onclick="readUTF8file(pin.value)" />
<input class='btn' type="button" value="write" onclick="writeUTF8file(pin.value,pout.innerText)" />
<input class='input' id='pin' placeholder="请输入文件名"/>
<div id="printOut"></div>
</div>
</div>
</div>
<div id="right">
@ -355,31 +89,34 @@
</div>
</div>
</div>
<script>
// 生成定位编号
(function(){
var colNum = ' ';
for(var i=0; i<13; i++){
var tpl = '<td>'+i+'<div class="colBlock" style="left:'+(i*32+1)+'px;"></div></td>';
colNum += tpl;
}
arrColMark.innerHTML = '<tr>'+colNum+'</tr>';
mapColMark.innerHTML = '<tr>'+colNum+'</tr>';
var rowNum = ' ';
for(var i=0; i<13; i++){
var tpl = '<tr><td>'+i+'<div class="rowBlock" style="top:'+(i*32+1)+'px;"></div></td></tr>';
rowNum += tpl;
}
arrRowMark.innerHTML = rowNum;
mapRowMark.innerHTML = rowNum;
})();
// 生成定位编号
(function(){
var colNum = ' ';
for(var i=0; i<13; i++){
var tpl = '<td>'+i+'<div class="colBlock" style="left:'+(i*32+1)+'px;"></div></td>';
colNum += tpl;
}
arrColMark.innerHTML = '<tr>'+colNum+'</tr>';
mapColMark.innerHTML = '<tr>'+colNum+'</tr>';
var rowNum = ' ';
for(var i=0; i<13; i++){
var tpl = '<tr><td>'+i+'<div class="rowBlock" style="top:'+(i*32+1)+'px;"></div></td></tr>';
rowNum += tpl;
}
arrRowMark.innerHTML = rowNum;
mapRowMark.innerHTML = rowNum;
})();
</script>
<!-- =========================================================== -->
<script src='_server/vendor/vue.min.js'></script>
<!-- <script src='_server/vendor/vue.min.js'></script> -->
<!-- <script src="https://unpkg.com/vue"></script> -->
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script src='_server/fs.js'></script>
<script src='_server/editor_file.js'></script>
<script src='_server/vm.js'></script>
<script>
printf = function(str,weak) {
@ -459,7 +196,6 @@ editor.prototype.loadImg = function(url){
}
})
}
editor.prototype.loadAllImgs = function(icons){
editor.material.images = {};
var imgs = Object.keys(icons);
@ -586,7 +322,6 @@ editor.prototype.drawMapBg = function(){
bgc.drawImage(editor.material.images['terrains'], 0, 32*(editor.bgY||0), 32, 32, ii*32, jj*32, 32, 32);
}
}
editor.prototype.updateMap = function(){
var drawTile = function(ctx, x, y, tileInfo){ // 绘制一个普通块
@ -612,23 +347,24 @@ editor.prototype.updateMap = function(){
}
// autotile的相关处理
var indexArrs = [ //16种组合的图块索引数组
[10, 9, 4, 3], //0 bin:0000
[10, 9, 4, 13], //1 bin:0001
[10, 9, 18, 3], //2 bin:0010
[10, 9, 16, 15], //3 bin:0011
[10, 43, 4, 3], //4 bin:0100
[10, 31, 4, 25], //5 bin:0101
[10, 7, 2, 3], //6 bin:0110
[10, 19, 14, 5], //7 bin:0111
[48, 9, 4, 3], //8 bin:1000
[8, 9, 4, 1], //9 bin:1001
[36, 9, 30, 3], //10 bin:1010
[24, 9, 6, 17], //11 bin:1011
[46, 45, 4, 3], //12 bin:1100
[44, 11, 4, 37], //13 bin:1101
[12, 47, 42, 3], //14 bin:1110
[34, 33, 28, 27] //15 bin:1111
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, 19, 14, 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 |
[24, 9, 6, 17], //11 bin:1011 +----+----+----+----+----+----+
[46, 45, 4, 3 ], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 |
[44, 11, 4, 37], //13 bin:1101 +----+----+----+----+----+----+
[12, 47, 42, 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));
@ -641,6 +377,7 @@ editor.prototype.updateMap = function(){
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;
}
@ -706,7 +443,6 @@ editor.prototype.updateMap = function(){
}
// 绘制地图 end
}
editor.prototype.listen = function() {
var uc = ui.getContext('2d');
@ -894,7 +630,9 @@ editor.prototype.listen = function() {
}
}//绑定事件
editor.prototype.locInfo = function(){
}
/*
editor.updateMap
@ -906,14 +644,37 @@ editor.info
*/
var editor = new editor();
editor.init();
editor.fs=fs;
editor.file=editor_file;
</script>
<script type="text/javascript">
//Vue
//var listenByVue = function() {
<script>
// 文件相关操作
var promisify = function (fn, receiver) {
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return new Promise(function (resolve, reject) {
fn.apply(receiver, [].concat(args, [function (res, err) {
return err ? reject(err) : resolve(res);
}]));
});
};
};
var fns = Object.keys(editor.file);
var promiseFns = {};
fns.forEach(function(fn){
promiseFns[fn] = promisify(editor.file[fn], editor.file)
});
editor.promiseFiles = Object.assign(promiseFns);
//}
//listenByVue()
editor.promiseFiles.getFloorFileList(editor)
.then(function(filelist){
editFile4map.filelist = filelist;
})
.catch(function(err){
console.log(err);
})
</script>
</body>
</html>