Merge remote-tracking branch 'refs/remotes/ckcz123/master'

This commit is contained in:
YouWei Zhao 2017-12-31 15:50:49 +08:00
commit f037ebe3f0
16 changed files with 498 additions and 362 deletions

View File

@ -21,6 +21,7 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
│ └─ *.png # 对应的某个具体的图片素材 │ └─ *.png # 对应的某个具体的图片素材
├── /libs/ # JS源代码目录 ├── /libs/ # JS源代码目录
│ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件 │ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件
│ ├─ /thirdparty/ # 游戏所用到的第三方库文件
│ ├─ core.js # 系统核心文件 │ ├─ core.js # 系统核心文件
│ ├─ data.js # 记录了勇士的初始化信息、各个全局变量和全局Flag值 │ ├─ data.js # 记录了勇士的初始化信息、各个全局变量和全局Flag值
│ ├─ enemys.js # 记录了怪物的信息,包括怪物的数据和特殊属性、伤害计算公式、临界值计算等。 │ ├─ enemys.js # 记录了怪物的信息,包括怪物的数据和特殊属性、伤害计算公式、临界值计算等。
@ -47,6 +48,7 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
### 2017.12.31 V1.3 ### 2017.12.31 V1.3
* [x] 支持全键盘操作。 * [x] 支持全键盘操作。
* [x] 支持将某个图片作为某层的背景素材。
* [x] 便捷PS工具支持更改图片色相。 * [x] 便捷PS工具支持更改图片色相。
* [x] 支持经验升级(进阶/境界塔)。 * [x] 支持经验升级(进阶/境界塔)。
* [x] 打败怪物可以进行加点(加点塔)。 * [x] 打败怪物可以进行加点(加点塔)。

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

@ -0,0 +1,297 @@
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;
}
.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);
}
#bgSelect{
width: 50%;
height: 100px;
margin-top: 10px;
}
#bgSelect span{
/* display: block; */
font-size: 14px;
line-height: 30px;
}
#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;
margin-top: 5px;
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

@ -187,7 +187,7 @@ var tip = new Vue({
isClearBlock: false, isClearBlock: false,
geneMapSuccess: false, geneMapSuccess: false,
timer: null, timer: null,
msgs: [ //分别编号1,2,3,4,5,6,7,8;奇数警告,偶数成功 msgs: [ //分别编号1,2,3,4,5,6,7,8,9,10;奇数警告,偶数成功
"当前未选择任何图块,请先在右边选择要画的图块!", "当前未选择任何图块,请先在右边选择要画的图块!",
"生成地图成功!可点击复制按钮复制地图数组到剪切板", "生成地图成功!可点击复制按钮复制地图数组到剪切板",
"生成失败! 地图中有未定义的图块,建议先用其他有效图块覆盖或点击清除地图!", "生成失败! 地图中有未定义的图块,建议先用其他有效图块覆盖或点击清除地图!",
@ -195,7 +195,9 @@ var tip = new Vue({
"复制失败!", "复制失败!",
"复制成功!可直接粘贴到楼层文件的地图数组中。", "复制成功!可直接粘贴到楼层文件的地图数组中。",
"复制失败!当前还没有数据", "复制失败!当前还没有数据",
"修改成功!可点击复制按钮复制地图数组到剪切板" "修改成功!可点击复制按钮复制地图数组到剪切板",
"选择背景图片失败!文件名格式错误或图片不存在!",
"更新背景图片成功!",
], ],
mapMsg: '', mapMsg: '',
whichShow: 0, whichShow: 0,
@ -255,12 +257,31 @@ var bgSelect = new Vue({
el: '#bgSelect', el: '#bgSelect',
data: { data: {
bgs: {}, bgs: {},
selectedBg: 'ground' selectedBg: 'ground',
imgname: ''
}, },
watch:{ watch:{
selectedBg: function(){ selectedBg: function(){
editor.bgY = this.bgs.indexOf(this.selectedBg); editor.bgY = this.bgs.indexOf(this.selectedBg);
editor.drawMapBg(); editor.drawMapBg();
} }
},
methods: {
updatebg: function(){
tip.whichShow = 0;
var regx = /\S+\.(png|bmp|jpg|jpeg|gif)$/i;
if(regx.test(this.imgname)){
var url = 'images/'+this.imgname;
editor.loadImg(url).then(function(img){
editor.drawMapBg(img);
tip.whichShow = 10;
}).catch(function(err){
console.log(err);
tip.whichShow = 9;
});
}else{
tip.whichShow = 9;
}
}
} }
}) })

View File

@ -29,6 +29,7 @@
"x,y": { "x,y": {
"trigger": "action", // 触发的trigger, action代表自定义事件 "trigger": "action", // 触发的trigger, action代表自定义事件
"enable": true, // 该事件初始状态下是否处于启用状态 "enable": true, // 该事件初始状态下是否处于启用状态
"noPass": true, // 该点是否不可通行。true代表不可通行false代表可通行。
"data": [ // 实际执行的事件列表 "data": [ // 实际执行的事件列表
// 事件1 // 事件1
// 事件2 // 事件2
@ -53,6 +54,7 @@
"x,y": { "x,y": {
// 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略 // 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略
"enable": true, // 该事件初始状态下是否处于启用状态 "enable": true, // 该事件初始状态下是否处于启用状态
"noPass": true, // 该点是否不可通行。true代表不可通行false代表可通行。
"data": [ // 实际执行的事件列表 "data": [ // 实际执行的事件列表
// 事件1 // 事件1
// 事件2 // 事件2
@ -71,6 +73,28 @@
"x,y": { "x,y": {
// 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略 // 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略
// 该事件初始状态下是启用状态,则可以省略"enable": true如果是禁用状态则必须加上"enable": false // 该事件初始状态下是启用状态,则可以省略"enable": true如果是禁用状态则必须加上"enable": false
"noPass": true, // 该点是否不可通行。true代表不可通行false代表可通行。
"data": [ // 实际执行的事件列表
// 事件1
// 事件2
// ...
]
}
}
```
`"noPass"`为该点是否可通行的标记。`true`代表该点不可通行,`false`代表该点可通行。
对于目前所有的素材,都存在默认的是否可通行状态。如果你在该点指定`noPass`,则原本的可通行状态会被覆盖。
因此,除非你想覆盖默认的可通行选项(比如将一个空地设为不可通行),否则该项可以忽略。
``` js
"events": { // 该楼的所有可能事件列表
"x,y": {
// 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略
// 该事件初始状态下是启用状态,则可以省略"enable": true如果是禁用状态则必须加上"enable": false
// 除非你想覆盖系统默认的可通行状态,否则"noPass"项可以忽略
"data": [ // 实际执行的事件列表 "data": [ // 实际执行的事件列表
// 事件1 // 事件1
// 事件2 // 事件2
@ -86,7 +110,7 @@
``` js ``` js
"events": { // 该楼的所有可能事件列表 "events": { // 该楼的所有可能事件列表
// 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号 // 如果大括号里只有"data"项(没有"action", "enable"或"noPass"),则可以省略到只剩下中括号
"x,y": [ // 实际执行的事件列表 "x,y": [ // 实际执行的事件列表
// 事件1 // 事件1
// 事件2 // 事件2
@ -97,7 +121,7 @@
这种简写方式可以极大方便地造塔者进行造塔。 这种简写方式可以极大方便地造塔者进行造塔。
!> **请注意:如果该点初始的`enable`为`false`,或者该点本身有系统默认事件且需要覆盖(`trigger`),则必须采用上面那种大括号写的方式来定义。** !> **请注意:如果该点初始的`enable`为`false`,或者该点本身有系统默认事件且需要覆盖(`trigger`或者你想覆盖该点的默认通行状态,则必须采用上面那种大括号写的方式来定义。**
   

View File

@ -21,6 +21,41 @@
如果你需要某个素材已经存在则可以直接将其覆盖images目录下的同名文件就能看到效果。 如果你需要某个素材已经存在则可以直接将其覆盖images目录下的同名文件就能看到效果。
### 使用自己的图片作为某层楼的背景素材
由于HTML5功能素材有限导致了对很多比较复杂的素材比如房子内等无法有着较好的绘图方式。
为了解决这个问题,我们允许用户自己放置一张图片作为某一层的背景素材。
要启用这个功能,我们首先需要在`main.js`中将可能的图片进行加载。
``` js
this.pngs = [ // 在此存放所有可能的背景图片背景图片最好是416*416像素其他分辨率会被强制缩放成416*416
// 建议对于较大的图片,在网上使用在线的“图片压缩工具”来进行压缩,以节省流量
"bg.png", // "yewai.png",
];
```
!> 背景素材只支持png格式且会被强制缩放到416*416。
!> 请使用网上的一些[在线图片压缩工具](http://www.asqql.com/gifzip/)对png图片进行压缩以节省流量。一张500KB的png图片可以被压缩到20-30KB显示效果不会有太大差异。
之后,我们可以在每层剧本的`"png": "xxx"`里来定义该层的默认背景图片素材。
``` js
"png": "bg.png", // 背景图你可以选择一张png图片来作为背景素材。
```
你的图片背景素材将会覆盖原来本身的背景层。
**如果你需要让某些点不可通行(比如你建了个房子,墙壁和家具等位置不让通行),则需在`events`中指定`{"noPass": false}`,参见[自定义事件](event#自定义事件)的写法。
``` js
"events": {
"x,y": {"noPass": true} // (x,y)点不可通行
}
```
### 使用便捷PS工具生成素材 ### 使用便捷PS工具生成素材
如果我们有更多的素材要求我们可以使用“便捷PS工具”进行处理。 如果我们有更多的素材要求我们可以使用“便捷PS工具”进行处理。
@ -52,7 +87,6 @@
如果需要添加一个素材到游戏,则必须为其分配一个唯一标识符,并同时修改`icons.js`和`maps.js`两个文件。 如果需要添加一个素材到游戏,则必须为其分配一个唯一标识符,并同时修改`icons.js`和`maps.js`两个文件。
#### 新添加自定义地形(路面、墙壁等) #### 新添加自定义地形(路面、墙壁等)
如果你在terrains.png中新增了一行 如果你在terrains.png中新增了一行

View File

@ -2,304 +2,7 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<style> <link href="_server/css/editor.css" rel="stylesheet">
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);
}
#bgSelect{
width: 50%;
height: 100px;
margin-top: 10px;
}
#bgSelect span{
display: block;
font-size: 14px;
line-height: 30px;
}
#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>
</head> </head>
<body> <body>
<div class="main"> <div class="main">
@ -349,14 +52,19 @@
</div> </div>
<input class='btn' id='clear' type="button" value="清除地图" v-on:click="clearMap"/> <input class='btn' id='clear' type="button" value="清除地图" v-on:click="clearMap"/>
<input class='btn' type="button" value="导出地图" id="exportM" v-on:click="exportMap"/> <input class='btn' type="button" value="导出地图" id="exportM" v-on:click="exportMap"/>
<div id="bgSelect" v-cloak> <div id="bgSelect" v-cloak>
<span>当前地板: </span>
<select v-model="selectedBg"> <select v-model="selectedBg">
<option disabled value="">请选择地板</option> <option disabled value="">请选择地板</option>
<option v-for="bg in bgs" v-bind:value="bg"> <option v-for="bg in bgs" v-bind:value="bg">
{{ bg }} {{ bg }}
</option> </option>
</select> </select>
<span>当前地板: {{ selectedBg }}</span> <div class="selectpng">
<input class='input' id='pin' v-model="imgname" placeholder="请输入自定义背景文件名"/>
<input class='btn' type="button" value="确定" v-on:click="updatebg"/>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -396,14 +104,9 @@
<script src='_server/fs.js'></script> <script src='_server/fs.js'></script>
<script src='_server/vm.js'></script> <script src='_server/vm.js'></script>
<script> <script>
printf = function(str,weak) {
var prefix='<span class="result">',postfix='</span>';
if (weak){prefix='<span class="weakresult">';}
if (typeof(str)==="undefined")str='';
printOut.innerHTML=prefix+String(str)+postfix;
}
//所有全局量 //所有全局量
__all__=['Vue','fs','printf','editor','main','core','fullX','fullY']; __all__=['Vue','fs','printf','editor','main','core'];
__id__=['printOut','arrRowMark','mapRowMark','data','bg','dataSelection']; __id__=['printOut','arrRowMark','mapRowMark','data','bg','dataSelection'];
__Vue__=['exportM','editArea','editTip','clear','tip','selectBox']; __Vue__=['exportM','editArea','editTip','clear','tip','selectBox'];
@ -602,7 +305,7 @@ editor.prototype.mapInit = function(){
} }
} }
} }
editor.prototype.drawMapBg = function(){ editor.prototype.drawMapBg = function(img){
var bgc = bg.getContext('2d'); var bgc = bg.getContext('2d');
for (var ii = 0; ii < 13; ii++) for (var ii = 0; ii < 13; ii++)
@ -610,6 +313,9 @@ editor.prototype.drawMapBg = function(){
bgc.clearRect(ii*32, jj*32, 32, 32); bgc.clearRect(ii*32, jj*32, 32, 32);
bgc.drawImage(editor.material.images['terrains'], 0, 32*(editor.bgY||0), 32, 32, ii*32, jj*32, 32, 32); bgc.drawImage(editor.material.images['terrains'], 0, 32*(editor.bgY||0), 32, 32, ii*32, jj*32, 32, 32);
} }
if(img){
bgc.drawImage(img, 0, 0, 416, 416);
}
} }
editor.prototype.updateMap = function(){ editor.prototype.updateMap = function(){

BIN
images/yewai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -7,6 +7,7 @@ function core() {
this.statusBar = {}; this.statusBar = {};
this.canvas = {}; this.canvas = {};
this.images = []; this.images = [];
this.pngs = [];
this.bgms = []; this.bgms = [];
this.sounds = []; this.sounds = [];
this.floorIds = []; this.floorIds = [];
@ -105,11 +106,12 @@ function core() {
/////////// 系统事件相关 /////////// /////////// 系统事件相关 ///////////
////// 初始化 ////// ////// 初始化 //////
core.prototype.init = function (dom, statusBar, canvas, images, bgms, sounds, floorIds, floors, coreData) { core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, sounds, floorIds, floors, coreData) {
core.dom = dom; core.dom = dom;
core.statusBar = statusBar; core.statusBar = statusBar;
core.canvas = canvas; core.canvas = canvas;
core.images = images; core.images = images;
core.pngs = pngs;
core.bgms = bgms; core.bgms = bgms;
core.sounds = sounds; core.sounds = sounds;
core.floorIds = floorIds; core.floorIds = floorIds;
@ -138,8 +140,6 @@ core.prototype.init = function (dom, statusBar, canvas, images, bgms, sounds, fl
core.material.icons = core.icons.getIcons(); core.material.icons = core.icons.getIcons();
core.material.events = core.events.getEvents(); core.material.events = core.events.getEvents();
if (location.protocol.indexOf("http")==0) { if (location.protocol.indexOf("http")==0) {
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext; window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
try { try {
@ -259,18 +259,29 @@ core.prototype.loader = function (callback) {
core.setStartLoadTipText(imgName + ' 加载完毕...'); core.setStartLoadTipText(imgName + ' 加载完毕...');
core.setStartProgressVal(loadedImageNum * (100 / allImageNum)); core.setStartProgressVal(loadedImageNum * (100 / allImageNum));
if (loadedImageNum == allImageNum) { if (loadedImageNum == allImageNum) {
// 加载Autotile // 加载pngs
core.material.images.autotile={}; core.material.images.pngs = {};
var autotileIds = Object.keys(core.material.icons.autotile); for (var x=0;x<core.pngs.length;x++) {
for (var x=0;x<autotileIds.length;x++) { core.loadImage(core.pngs[x], function (pngId, image) {
core.loadImage(autotileIds[x], function (autotileId, image) { core.material.images.pngs[pngId] = image;
core.material.images.autotile[autotileId]=image; if (Object.keys(core.material.images.pngs).length==core.pngs.length) {
if (Object.keys(core.material.images.autotile).length==autotileIds.length) {
// 音频 // 加载Autotile
core.loadMusic(callback); core.material.images.autotile={};
var autotileIds = Object.keys(core.material.icons.autotile);
for (var x=0;x<autotileIds.length;x++) {
core.loadImage(autotileIds[x], function (autotileId, image) {
core.material.images.autotile[autotileId]=image;
if (Object.keys(core.material.images.autotile).length==autotileIds.length) {
// 最后加载音频
core.loadMusic(callback);
}
})
}
} }
}) });
} }
} }
}); });
@ -281,8 +292,11 @@ core.prototype.loader = function (callback) {
core.prototype.loadImage = function (imgName, callback) { core.prototype.loadImage = function (imgName, callback) {
try { try {
core.setStartLoadTipText('加载图片 ' + imgName + ' 中...'); core.setStartLoadTipText('加载图片 ' + imgName + ' 中...');
var name=imgName;
if (name.indexOf(".png")<0) // 不包含"png"
name=name+".png";
var image = new Image(); var image = new Image();
image.src = 'images/' + imgName + '.png'; image.src = 'images/' + name;
if (image.complete) { if (image.complete) {
callback(imgName, image); callback(imgName, image);
return; return;
@ -1999,6 +2013,14 @@ core.prototype.drawMap = function (mapName, callback) {
core.canvas.bg.drawImage(blockImage, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32); core.canvas.bg.drawImage(blockImage, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32);
} }
} }
// 如果存在png
if (core.isset(core.floors[mapName].png)) {
var png = core.floors[mapName].png;
if (core.isset(core.material.images.pngs[png])) {
core.canvas.bg.drawImage(core.material.images.pngs[png], 0, 0, 416, 416);
}
}
var autotileMaps = []; var autotileMaps = [];
for (var b = 0; b < mapBlocks.length; b++) { for (var b = 0; b < mapBlocks.length; b++) {
// 事件启用 // 事件启用
@ -2010,10 +2032,12 @@ core.prototype.drawMap = function (mapName, callback) {
continue; continue;
} }
else { else {
blockIcon = core.material.icons[block.event.cls][block.event.id]; if (block.event.id!='none') {
blockImage = core.material.images[block.event.cls]; blockIcon = core.material.icons[block.event.cls][block.event.id];
core.canvas.event.drawImage(core.material.images[block.event.cls], 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); blockImage = core.material.images[block.event.cls];
core.addGlobalAnimate(block.event.animate, block.x * 32, block.y * 32, blockIcon, blockImage); core.canvas.event.drawImage(core.material.images[block.event.cls], 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
core.addGlobalAnimate(block.event.animate, block.x * 32, block.y * 32, blockIcon, blockImage);
}
} }
} }
} }

View File

@ -8,6 +8,7 @@ main.floors.MT0 = {
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
"canUseQuickShop": true, // 该层是否允许使用快捷商店 "canUseQuickShop": true, // 该层是否允许使用快捷商店
"defaultGround": "ground", // 默认地面的图块IDterrains中 "defaultGround": "ground", // 默认地面的图块IDterrains中
// "png": "bg.png", // 背景图你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。
// "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。 // "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 // "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
"map": [ // 地图数据需要是13x13建议使用地图生成器来生成 "map": [ // 地图数据需要是13x13建议使用地图生成器来生成

View File

@ -8,6 +8,7 @@ main.floors.sample0 = {
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
"canUseQuickShop": true, // 该层是否允许使用快捷商店 "canUseQuickShop": true, // 该层是否允许使用快捷商店
"defaultGround": "ground", // 默认地面的图块IDterrains中 "defaultGround": "ground", // 默认地面的图块IDterrains中
// "png": "bg.png", // 背景图你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。 // "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。
"bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
"map": [ // 地图数据需要是13x13建议使用地图生成器来生成 "map": [ // 地图数据需要是13x13建议使用地图生成器来生成

View File

@ -8,6 +8,7 @@ main.floors.sample1 = {
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
"canUseQuickShop": true, // 该层是否允许使用快捷商店 "canUseQuickShop": true, // 该层是否允许使用快捷商店
"defaultGround": "grass", // 默认地面的图块IDterrains中 "defaultGround": "grass", // 默认地面的图块IDterrains中
"png": "bg.png", // 背景图你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。 // "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 // "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
"map": [ // 地图数据需要是13x13建议使用地图生成器来生成 "map": [ // 地图数据需要是13x13建议使用地图生成器来生成

View File

@ -8,6 +8,7 @@ main.floors.sample2 = {
"canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
"canUseQuickShop": true, // 该层是否允许使用快捷商店 "canUseQuickShop": true, // 该层是否允许使用快捷商店
"defaultGround": "snowGround", // 默认地面的图块IDterrains中 "defaultGround": "snowGround", // 默认地面的图块IDterrains中
// "png": "bg.png", // 背景图你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。
"color": [255,0,0,0.3], // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。 "color": [255,0,0,0.3], // 该层的默认画面色调。本项可不写代表无色调如果写需要是一个RGBA数组。
"bgm": "qianjin.mid", // 到达该层后默认播放的BGM。本项可忽略。 "bgm": "qianjin.mid", // 到达该层后默认播放的BGM。本项可忽略。
"map": [ // 地图数据需要是13x13建议使用地图生成器来生成 "map": [ // 地图数据需要是13x13建议使用地图生成器来生成

View File

@ -14,7 +14,7 @@ maps.prototype.loadFloor = function (floorId, map) {
for (var i = 0; i < 13; i++) { for (var i = 0; i < 13; i++) {
for (var j = 0; j < 13; j++) { for (var j = 0; j < 13; j++) {
var block = this.getBlock(j, i, map[i][j]); var block = this.getBlock(j, i, map[i][j]);
if (block.event != undefined) { if (core.isset(block.event)) {
if (block.event.cls == 'enemys' && block.event.trigger==undefined) { if (block.event.cls == 'enemys' && block.event.trigger==undefined) {
block.event.trigger = 'battle'; block.event.trigger = 'battle';
} }
@ -35,7 +35,7 @@ maps.prototype.loadFloor = function (floorId, map) {
} }
} }
} }
this.addEvent(block,j,i,floor.events[j+","+i],floor.defaultGround || "ground") this.addEvent(block,j,i,floor.events[j+","+i])
this.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]); this.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]);
if (core.isset(block.event)) blocks.push(block); if (core.isset(block.event)) blocks.push(block);
} }
@ -258,10 +258,10 @@ maps.prototype.getBlock = function (x, y, id) {
} }
////// 向该楼层添加剧本的自定义事件 ////// ////// 向该楼层添加剧本的自定义事件 //////
maps.prototype.addEvent = function (block, x, y, event, ground) { maps.prototype.addEvent = function (block, x, y, event) {
if (!core.isset(event)) return; if (!core.isset(event)) return;
if (!core.isset(block.event)) { // 本身是空地? if (!core.isset(block.event)) { // 本身是空地?
block.event = {'cls': 'terrains', 'id': ground, 'noPass': false}; block.event = {'cls': 'terrains', 'id': 'none', 'noPass': false};
} }
// event是字符串或数组 // event是字符串或数组
if (typeof event == "string") { if (typeof event == "string") {
@ -273,6 +273,10 @@ maps.prototype.addEvent = function (block, x, y, event, ground) {
if (!core.isset(event.data)) if (!core.isset(event.data))
event.data = []; event.data = [];
// 覆盖noPass
if (core.isset(event.noPass))
block.event.noPass = event.noPass;
// 覆盖enable // 覆盖enable
if (!core.isset(block.enable) && core.isset(event.enable)) { if (!core.isset(block.enable) && core.isset(event.enable)) {
block.enable=event.enable; block.enable=event.enable;

View File

@ -1083,6 +1083,15 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + i * persize, y + j * persize, persize, persize); core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + i * persize, y + j * persize, persize, persize);
} }
} }
// 如果存在png
if (core.isset(core.floors[floorId].png)) {
var png = core.floors[floorId].png;
if (core.isset(core.material.images.pngs[png])) {
core.canvas[canvas].drawImage(core.material.images.pngs[png], x, y, size, size);
}
}
var autotileMaps = []; var autotileMaps = [];
for (var b in blocks) { for (var b in blocks) {
var block = blocks[b]; var block = blocks[b];
@ -1093,9 +1102,11 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL
continue; continue;
} }
else { else {
var blockIcon = core.material.icons[block.event.cls][block.event.id]; if (block.event.id!='none') {
var blockImage = core.material.images[block.event.cls]; var blockIcon = core.material.icons[block.event.cls][block.event.id];
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + block.x * persize, y + block.y * persize, persize, persize); var blockImage = core.material.images[block.event.cls];
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + block.x * persize, y + block.y * persize, persize, persize);
}
} }
} }
} }

54
main.js
View File

@ -1,4 +1,33 @@
function main() { function main() {
//------------------------ 用户修改内容 ------------------------//
this.version = "0.1"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.useCompress = false; // 是否使用压缩文件
// 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。
// 请注意只有useCompress是false时才会读取floors目录下的文件为true时会直接读取libs目录下的floors.min.js文件。
// 如果要进行剧本的修改请务必将其改成false。
this.floorIds = [ // 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序
"sample0", "sample1", "sample2"
];
this.pngs = [ // 在此存放所有可能的背景图片背景图片最好是416*416像素其他分辨率会被强制缩放成416*416
// 建议对于较大的图片,在网上使用在线的“图片压缩工具”来进行压缩,以节省流量
// 有关使用自定义背景图,请参见文档的“自定义素材”说明
"bg.png", "yewai.png", // 依次向后添加
];
this.bgms = [ // 在此存放所有的bgm和文件名一致。第一项为默认播放项
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
'058-Slow01.mid', 'bgm.mp3', 'qianjin.mid', 'star.mid',
];
this.sounds = [ // 在此存放所有的SE和文件名一致
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg',
];
//------------------------ 用户修改内容 END ------------------------//
this.dom = { this.dom = {
'body': document.body, 'body': document.body,
'gameGroup': document.getElementById('gameGroup'), 'gameGroup': document.getElementById('gameGroup'),
@ -46,14 +75,7 @@ function main() {
this.images = [ this.images = [
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains' 'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains'
]; ];
this.bgms = [ // 在此存放所有的bgm和文件名一致。第一项为默认播放项
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
'058-Slow01.mid', 'bgm.mp3', 'qianjin.mid', 'star.mid'
];
this.sounds = [ // 在此存放所有的SE和文件名一致
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg'
]
this.statusBar = { this.statusBar = {
'image': { 'image': {
'floor': document.getElementById('img-floor'), 'floor': document.getElementById('img-floor'),
@ -90,20 +112,6 @@ function main() {
'curse': document.getElementById('curse'), 'curse': document.getElementById('curse'),
'hard': document.getElementById("hard") 'hard': document.getElementById("hard")
} }
//------------------------ 用户修改内容 ------------------------//
this.version = "0.1"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.useCompress = false; // 是否使用压缩文件
// 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。
// 请注意只有useCompress是false时才会读取floors目录下的文件为true时会直接读取libs目录下的floors.min.js文件。
// 如果要进行剧本的修改请务必将其改成false。
this.floorIds = [ // 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序
"sample0", "sample1", "sample2"
]
//------------------------ 用户修改内容 END ------------------------//
this.floors = {} this.floors = {}
this.instance = {}; this.instance = {};
this.canvas = {}; this.canvas = {};
@ -122,7 +130,7 @@ main.prototype.init = function () {
coreData[name] = main[name]; coreData[name] = main[name];
} }
main.loaderFloors(function() { main.loaderFloors(function() {
main.core.init(main.dom, main.statusBar, main.canvas, main.images, main.bgms, main.sounds, main.floorIds, main.floors, coreData); main.core.init(main.dom, main.statusBar, main.canvas, main.images, main.pngs, main.bgms, main.sounds, main.floorIds, main.floors, coreData);
main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight);
}) })
}); });

View File

@ -1,6 +1,7 @@
HTML5魔塔样板V1.3 HTML5魔塔样板V1.3
支持全键盘操作。 支持全键盘操作。
支持将某个图片作为某层的背景素材。
便捷PS工具支持更改图片色相。 便捷PS工具支持更改图片色相。
支持经验升级(进阶/境界塔)。 支持经验升级(进阶/境界塔)。
打败怪物可以进行加点(加点塔)。 打败怪物可以进行加点(加点塔)。